rename() with overwrite semantics on every platform: POSIX rename already * replaces atomically; Windows rename fails with EEXIST when the target * exists, so use write-through MoveFileExW(MOVEFILE_REPLACE_EXISTING) there * (wide paths — raw MoveFileExA would re-mangle non-ASCII cache paths). */
| 1034 | * exists, so use write-through MoveFileExW(MOVEFILE_REPLACE_EXISTING) there |
| 1035 | * (wide paths — raw MoveFileExA would re-mangle non-ASCII cache paths). */ |
| 1036 | int cbm_rename_replace(const char *src, const char *dst) { |
| 1037 | #ifdef _WIN32 |
| 1038 | wchar_t *wsrc = cbm_path_to_wide(src); |
| 1039 | wchar_t *wdst = cbm_path_to_wide(dst); |
| 1040 | int ret = CBM_NOT_FOUND; |
| 1041 | if (wsrc && wdst) { |
| 1042 | ret = MoveFileExW(wsrc, wdst, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) |
| 1043 | ? 0 |
| 1044 | : CBM_NOT_FOUND; |
| 1045 | } |
| 1046 | free(wsrc); |
| 1047 | free(wdst); |
| 1048 | return ret; |
| 1049 | #else |
| 1050 | return rename(src, dst); |
| 1051 | #endif |
| 1052 | } |
| 1053 | |
| 1054 | int cbm_rename_noreplace(const char *src, const char *dst) { |
| 1055 | if (!src || !dst || !src[0] || !dst[0]) { |