| 575 | #endif |
| 576 | |
| 577 | static int toml_replace_atomic(const char *temp_path, const char *path, int existed) { |
| 578 | #ifdef _WIN32 |
| 579 | wchar_t *wide_temp = cbm_utf8_to_wide(temp_path); |
| 580 | wchar_t *wide_path = cbm_utf8_to_wide(path); |
| 581 | if (!wide_temp || !wide_path) { |
| 582 | free(wide_temp); |
| 583 | free(wide_path); |
| 584 | return TOML_EDIT_ERR; |
| 585 | } |
| 586 | /* ReplaceFileW preserves the destination ACL and other mergeable metadata; |
| 587 | * merge failures stay fatal so metadata is never silently discarded. */ |
| 588 | BOOL replaced = |
| 589 | existed ? ReplaceFileW(wide_path, wide_temp, NULL, REPLACEFILE_WRITE_THROUGH, NULL, NULL) |
| 590 | : MoveFileExW(wide_temp, wide_path, MOVEFILE_WRITE_THROUGH); |
| 591 | free(wide_temp); |
| 592 | free(wide_path); |
| 593 | return replaced ? TOML_EDIT_OK : TOML_EDIT_ERR; |
| 594 | #else |
| 595 | if (!existed) { |
| 596 | if (link(temp_path, path) != 0) { |
| 597 | return TOML_EDIT_ERR; |
| 598 | } |
| 599 | if (cbm_unlink(temp_path) != 0) { |
| 600 | return TOML_EDIT_ERR; |
| 601 | } |
| 602 | return toml_sync_parent_directory(path); |
| 603 | } |
| 604 | if (rename(temp_path, path) != 0) { |
| 605 | return TOML_EDIT_ERR; |
| 606 | } |
| 607 | return toml_sync_parent_directory(path); |
| 608 | #endif |
| 609 | } |
| 610 | |
| 611 | static int toml_write_atomic(const char *path, const char *old_data, size_t old_len, |
| 612 | const char *new_data, size_t new_len, |
no test coverage detected