feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.fileLength
fn fileLength(userdata: ?*anyopaque, file: File) File.LengthError!u64
File
Code
fn fileLength(userdata: ?*anyopaque, file: File) File.LengthError!u64 {
const t: *Threaded = @ptrCast(@alignCast(userdata));
if (native_os == .linux) {
const linux = std.os.linux;
const syscall: Syscall = try .start();
while (true) {
var statx = std.mem.zeroes(linux.Statx);
switch (linux.errno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, .{ .SIZE = true }, &statx))) {
.SUCCESS => {
syscall.finish();
if (!statx.mask.SIZE) return error.Unexpected;
return statx.size;
},
.INTR => {
try syscall.checkCancel();
continue;
},
else => |e| {
syscall.finish();
switch (e) {
.ACCES => |err| return errnoBug(err),
.BADF => |err| return errnoBug(err),
.FAULT => |err| return errnoBug(err),
.INVAL => |err| return errnoBug(err),
.LOOP => |err| return errnoBug(err),
.NAMETOOLONG => |err| return errnoBug(err),
.NOENT => |err| return errnoBug(err),
.NOMEM => return error.SystemResources,
.NOTDIR => |err| return errnoBug(err),
else => |err| return posix.unexpectedErrno(err),
}
},
}
}
} else if (is_windows) {
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
var info: windows.FILE.STANDARD_INFORMATION = undefined;
const syscall: Syscall = try .start();
while (true) switch (windows.ntdll.NtQueryInformationFile(
file.handle,
&io_status_block,
&info,
@sizeOf(windows.FILE.STANDARD_INFORMATION),
.Standard,
)) {
.SUCCESS => break syscall.finish(),
.INVALID_PARAMETER => |err| return syscall.ntstatusBug(err),
.ACCESS_DENIED => return syscall.fail(error.AccessDenied),
.CANCELLED => {
try syscall.checkCancel();
continue;
},
else => |s| return syscall.unexpectedNtstatus(s),
};
return @as(u64, @bitCast(info.EndOfFile));
}
const stat = try fileStat(t, file);
return stat.size;
}