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