diff --git a/std/fs/file.zig b/std/fs/file.zig index 5324ee915f..18fe658366 100644 --- a/std/fs/file.zig +++ b/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), diff --git a/std/os/windows.zig b/std/os/windows.zig index 60ebf01166..a608839b80 100644 --- a/std/os/windows.zig +++ b/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)); } diff --git a/std/os/windows/kernel32.zig b/std/os/windows/kernel32.zig index de5bd57a5a..e4edc349ab 100644 --- a/std/os/windows/kernel32.zig +++ b/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;