diff --git a/std/os/index.zig b/std/os/index.zig index 0b536d3193..2f6b70d90e 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -674,26 +674,36 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) mem.copy(u8, new_buf, new_path); new_buf[new_path.len] = 0; - const err = posix.getErrno(posix.rename(old_buf.ptr, new_buf.ptr)); - if (err > 0) { - return switch (err) { - posix.EACCES, posix.EPERM => error.AccessDenied, - posix.EBUSY => error.FileBusy, - posix.EDQUOT => error.DiskQuota, - posix.EFAULT, posix.EINVAL => unreachable, - posix.EISDIR => error.IsDir, - posix.ELOOP => error.SymLinkLoop, - posix.EMLINK => error.LinkQuotaExceeded, - posix.ENAMETOOLONG => error.NameTooLong, - posix.ENOENT => error.FileNotFound, - posix.ENOTDIR => error.NotDir, - posix.ENOMEM => error.SystemResources, - posix.ENOSPC => error.NoSpaceLeft, - posix.EEXIST, posix.ENOTEMPTY => error.PathAlreadyExists, - posix.EROFS => error.ReadOnlyFileSystem, - posix.EXDEV => error.RenameAcrossMountPoints, - else => error.Unexpected, - }; + if (is_windows) { + const flags = windows.MOVEFILE_REPLACE_EXISTING|windows.MOVEFILE_WRITE_THROUGH; + if (!windows.MoveFileExA(old_buf.ptr, new_buf.ptr, flags)) { + const err = windows.GetLastError(); + return switch (err) { + else => return error.Unexpected, + }; + } + } else { + const err = posix.getErrno(posix.rename(old_buf.ptr, new_buf.ptr)); + if (err > 0) { + return switch (err) { + posix.EACCES, posix.EPERM => error.AccessDenied, + posix.EBUSY => error.FileBusy, + posix.EDQUOT => error.DiskQuota, + posix.EFAULT, posix.EINVAL => unreachable, + posix.EISDIR => error.IsDir, + posix.ELOOP => error.SymLinkLoop, + posix.EMLINK => error.LinkQuotaExceeded, + posix.ENAMETOOLONG => error.NameTooLong, + posix.ENOENT => error.FileNotFound, + posix.ENOTDIR => error.NotDir, + posix.ENOMEM => error.SystemResources, + posix.ENOSPC => error.NoSpaceLeft, + posix.EEXIST, posix.ENOTEMPTY => error.PathAlreadyExists, + posix.EROFS => error.ReadOnlyFileSystem, + posix.EXDEV => error.RenameAcrossMountPoints, + else => error.Unexpected, + }; + } } } diff --git a/std/os/windows/index.zig b/std/os/windows/index.zig index eb066c7aa3..95dc836448 100644 --- a/std/os/windows/index.zig +++ b/std/os/windows/index.zig @@ -57,6 +57,9 @@ pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBy pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; +pub extern "kernel32" stdcallcc fn MoveFileExA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR, + dwFlags: DWORD) -> BOOL; + pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: LPVOID, in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: &DWORD, in_out_lpOverlapped: ?&OVERLAPPED) -> BOOL; @@ -258,3 +261,10 @@ pub const WAIT_FAILED = 0xFFFFFFFF; pub const HANDLE_FLAG_INHERIT = 0x00000001; pub const HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x00000002; + +pub const MOVEFILE_COPY_ALLOWED = 2; +pub const MOVEFILE_CREATE_HARDLINK = 16; +pub const MOVEFILE_DELAY_UNTIL_REBOOT = 4; +pub const MOVEFILE_FAIL_IF_NOT_TRACKABLE = 32; +pub const MOVEFILE_REPLACE_EXISTING = 1; +pub const MOVEFILE_WRITE_THROUGH = 8;