Function stat [src]
Returns Stat containing basic information about the File.
Use metadata to retrieve more detailed information (e.g. creation time, permissions).
TODO: integrate with async I/O
Prototype
pub fn stat(self: File) StatError!Stat
Parameters
self: File
Possible Errors
In WASI, this error may occur when the file descriptor does not hold the required rights to get its filestat information.
The Operating System returned an undocumented error code.
This error is in theory not possible, but it would be better to handle this error than to invoke undefined behavior.
When this error code is observed, it usually means the Zig Standard Library needs a small patch to add the error code to the error set for the respective function.
Source
pub fn stat(self: File) StatError!Stat {
if (builtin.os.tag == .windows) {
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
var info: windows.FILE_ALL_INFORMATION = undefined;
const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
switch (rc) {
.SUCCESS => {},
// Buffer overflow here indicates that there is more information available than was able to be stored in the buffer
// size provided. This is treated as success because the type of variable-length information that this would be relevant for
// (name, volume name, etc) we don't care about.
.BUFFER_OVERFLOW => {},
.INVALID_PARAMETER => unreachable,
.ACCESS_DENIED => return error.AccessDenied,
else => return windows.unexpectedStatus(rc),
}
return .{
.inode = info.InternalInformation.IndexNumber,
.size = @as(u64, @bitCast(info.StandardInformation.EndOfFile)),
.mode = 0,
.kind = if (info.BasicInformation.FileAttributes & windows.FILE_ATTRIBUTE_REPARSE_POINT != 0) reparse_point: {
var tag_info: windows.FILE_ATTRIBUTE_TAG_INFO = undefined;
const tag_rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &tag_info, @sizeOf(windows.FILE_ATTRIBUTE_TAG_INFO), .FileAttributeTagInformation);
switch (tag_rc) {
.SUCCESS => {},
// INFO_LENGTH_MISMATCH and ACCESS_DENIED are the only documented possible errors
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/d295752f-ce89-4b98-8553-266d37c84f0e
.INFO_LENGTH_MISMATCH => unreachable,
.ACCESS_DENIED => return error.AccessDenied,
else => return windows.unexpectedStatus(rc),
}
if (tag_info.ReparseTag & windows.reparse_tag_name_surrogate_bit != 0) {
break :reparse_point .sym_link;
}
// Unknown reparse point
break :reparse_point .unknown;
} else if (info.BasicInformation.FileAttributes & windows.FILE_ATTRIBUTE_DIRECTORY != 0)
.directory
else
.file,
.atime = windows.fromSysTime(info.BasicInformation.LastAccessTime),
.mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime),
.ctime = windows.fromSysTime(info.BasicInformation.ChangeTime),
};
}
if (builtin.os.tag == .wasi and !builtin.link_libc) {
const st = try std.os.fstat_wasi(self.handle);
return Stat.fromWasi(st);
}
if (builtin.os.tag == .linux) {
var stx = std.mem.zeroes(linux.Statx);
const rc = linux.statx(
self.handle,
"",
linux.AT.EMPTY_PATH,
linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
&stx,
);
return switch (linux.E.init(rc)) {
.SUCCESS => Stat.fromLinux(stx),
.ACCES => unreachable,
.BADF => unreachable,
.FAULT => unreachable,
.INVAL => unreachable,
.LOOP => unreachable,
.NAMETOOLONG => unreachable,
.NOENT => unreachable,
.NOMEM => error.SystemResources,
.NOTDIR => unreachable,
else => |err| posix.unexpectedErrno(err),
};
}
const st = try posix.fstat(self.handle);
return Stat.fromPosix(st);
}