Commit 531f3344dc

Andrew Kelley <superjoe30@gmail.com>
2017-10-14 23:56:18
implement std.os.rename for windows
1 parent 61d715d
Changed files (2)
std
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;
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,
+            };
+        }
     }
 }