feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.fileSetTimestamps
fn fileSetTimestamps(
userdata: ?*anyopaque,
file: File,
options: File.SetTimestampsOptions,
) File.SetTimestampsError!void
File
Code
fn fileSetTimestamps(
userdata: ?*anyopaque,
file: File,
options: File.SetTimestampsOptions,
) File.SetTimestampsError!void {
const t: *Threaded = @ptrCast(@alignCast(userdata));
_ = t;
if (is_windows) {
const now_sys = if (options.access_timestamp == .now or options.modify_timestamp == .now)
windows.ntdll.RtlGetSystemTimePrecise()
else
undefined;
var iosb: windows.IO_STATUS_BLOCK = undefined;
var info: windows.FILE.BASIC_INFORMATION = .{
.CreationTime = 0,
.LastAccessTime = switch (options.access_timestamp) {
.unchanged => 0,
.now => now_sys,
.new => |ts| windows.toSysTime(ts),
},
.LastWriteTime = switch (options.modify_timestamp) {
.unchanged => 0,
.now => now_sys,
.new => |ts| windows.toSysTime(ts),
},
.ChangeTime = 0,
.FileAttributes = .{},
};
var syscall: Syscall = try .start();
while (true) switch (windows.ntdll.NtSetInformationFile(
file.handle,
&iosb,
&info,
@sizeOf(windows.FILE.BASIC_INFORMATION),
.Basic,
)) {
.SUCCESS => return syscall.finish(),
.CANCELLED => try syscall.checkCancel(),
else => |status| return syscall.unexpectedNtstatus(status),
};
}
if (native_os == .wasi and !builtin.link_libc) {
var atime: std.os.wasi.timestamp_t = 0;
var mtime: std.os.wasi.timestamp_t = 0;
var flags: std.os.wasi.fstflags_t = .{};
switch (options.access_timestamp) {
.unchanged => {},
.now => flags.ATIM_NOW = true,
.new => |ts| {
atime = timestampToPosix(ts.nanoseconds).toTimestamp();
flags.ATIM = true;
},
}
switch (options.modify_timestamp) {
.unchanged => {},
.now => flags.MTIM_NOW = true,
.new => |ts| {
mtime = timestampToPosix(ts.nanoseconds).toTimestamp();
flags.MTIM = true;
},
}
const syscall: Syscall = try .start();
while (true) switch (std.os.wasi.fd_filestat_set_times(file.handle, atime, mtime, flags)) {
.SUCCESS => return syscall.finish(),
.INTR => {
try syscall.checkCancel();
continue;
},
.BADF => |err| return syscall.errnoBug(err),
.FAULT => |err| return syscall.errnoBug(err),
.INVAL => |err| return syscall.errnoBug(err),
.ACCES => return syscall.fail(error.AccessDenied),
.PERM => return syscall.fail(error.PermissionDenied),
.ROFS => return syscall.fail(error.ReadOnlyFileSystem),
else => |err| return syscall.unexpectedErrno(err),
};
}
var times_buffer: [2]posix.timespec = undefined;
const times = if (options.modify_timestamp == .now and options.access_timestamp == .now) null else p: {
times_buffer = .{
setTimestampToPosix(options.access_timestamp),
setTimestampToPosix(options.modify_timestamp),
};
break :p ×_buffer;
};
const syscall: Syscall = try .start();
while (true) switch (posix.errno(posix.system.futimens(file.handle, times))) {
.SUCCESS => return syscall.finish(),
.INTR => {
try syscall.checkCancel();
continue;
},
.BADF => |err| return syscall.errnoBug(err),
.FAULT => |err| return syscall.errnoBug(err),
.INVAL => |err| return syscall.errnoBug(err),
.ACCES => return syscall.fail(error.AccessDenied),
.PERM => return syscall.fail(error.PermissionDenied),
.ROFS => return syscall.fail(error.ReadOnlyFileSystem),
else => |err| return syscall.unexpectedErrno(err),
};
}