Commit aa170a7eff

Andrew Kelley <andrew@ziglang.org>
2019-07-15 06:02:44
implement std.fs.File.updateTimes for windows
1 parent 95fdff3
Changed files (3)
std/fs/file.zig
@@ -257,11 +257,16 @@ pub const File = struct {
         };
     }
 
-    pub const UpdateTimesError = os.FutimensError;
+    pub const UpdateTimesError = os.FutimensError || windows.SetFileTimeError;
 
     /// `atime`: access timestamp in nanoseconds
     /// `mtime`: last modification timestamp in nanoseconds
     pub fn updateTimes(self: File, atime: u64, mtime: u64) UpdateTimesError!void {
+        if (windows.is_the_target) {
+            const atime_ft = windows.nanoSecondsToFileTime(atime);
+            const mtime_ft = windows.nanoSecondsToFileTime(mtime);
+            return windows.SetFileTime(self.handle, null, &atime_ft, &mtime_ft);
+        }
         const times = [2]os.timespec{
             os.timespec{
                 .tv_sec = @bitCast(isize, atime / std.time.ns_per_s),
std/os/windows/kernel32.zig
@@ -170,6 +170,13 @@ pub extern "kernel32" stdcallcc fn SetFilePointerEx(
     in_dwMoveMethod: DWORD,
 ) BOOL;
 
+pub extern "kernel32" stdcallcc fn SetFileTime(
+    hFile: HANDLE,
+    lpCreationTime: ?*const FILETIME,
+    lpLastAccessTime: ?*const FILETIME,
+    lpLastWriteTime: ?*const FILETIME,
+) BOOL;
+
 pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL;
 
 pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void;
std/os/windows.zig
@@ -767,11 +767,35 @@ pub fn GetFileInformationByHandle(
     return info;
 }
 
+pub const SetFileTimeError = error{Unexpected};
+
+pub fn SetFileTime(
+    hFile: HANDLE,
+    lpCreationTime: ?*const FILETIME,
+    lpLastAccessTime: ?*const FILETIME,
+    lpLastWriteTime: ?*const FILETIME,
+) SetFileTimeError!void {
+    const rc = kernel32.SetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime);
+    if (rc == 0) {
+        switch (kernel32.GetLastError()) {
+            else => |err| return unexpectedError(err),
+        }
+    }
+}
+
 pub fn fileTimeToNanoSeconds(ft: FILETIME) u64 {
     const sec = (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
     return sec * std.time.ns_per_s;
 }
 
+pub fn nanoSecondsToFileTime(ns: u64) FILETIME {
+    const sec = ns / std.time.ns_per_s;
+    return FILETIME{
+        .dwHighDateTime = @truncate(u32, sec >> 32),
+        .dwLowDateTime = @truncate(u32, sec),
+    };
+}
+
 pub fn cStrToPrefixedFileW(s: [*]const u8) ![PATH_MAX_WIDE + 1]u16 {
     return sliceToPrefixedFileW(mem.toSliceConst(u8, s));
 }