implement std.fs.File.updateTimes for windows

This commit is contained in:
Andrew Kelley 2019-07-15 00:02:44 -04:00
parent 95fdff3feb
commit aa170a7eff
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
3 changed files with 37 additions and 1 deletions

View File

@ -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),

View File

@ -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));
}

View File

@ -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;