Commit bfc569bc98
lib/std/c.zig
@@ -75,6 +75,7 @@ pub extern "c" fn isatty(fd: fd_t) c_int;
pub extern "c" fn close(fd: fd_t) c_int;
pub extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int;
pub extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int;
+pub extern "c" fn fstatat(dirfd: fd_t, path: [*:0]const u8, stat_buf: *Stat, flags: u32) c_int;
pub extern "c" fn lseek(fd: fd_t, offset: off_t, whence: c_int) off_t;
pub extern "c" fn open(path: [*:0]const u8, oflag: c_uint, ...) c_int;
pub extern "c" fn openat(fd: c_int, path: [*:0]const u8, oflag: c_uint, ...) c_int;
lib/std/os.zig
@@ -2371,6 +2371,29 @@ pub fn fstat(fd: fd_t) FStatError!Stat {
}
}
+const FStatAtError = FStatError || error{NameTooLong};
+
+pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError![]Stat {
+ const pathname_c = try toPosixPath(pathname);
+ return fstatatC(dirfd, &pathname_c, flags);
+}
+
+pub fn fstatatC(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!Stat {
+ var stat: Stat = undefined;
+ switch (errno(system.fstatat(dirfd, pathname, &stat, flags))) {
+ 0 => return stat,
+ EINVAL => unreachable,
+ EBADF => unreachable, // Always a race condition.
+ ENOMEM => return error.SystemResources,
+ EACCES => return error.AccessDenied,
+ EFAULT => unreachable,
+ ENAMETOOLONG => return error.NameTooLong,
+ ENOENT => return error.FileNotFound,
+ ENOTDIR => return error.FileNotFound,
+ else => |err| return unexpectedErrno(err),
+ }
+}
+
pub const KQueueError = error{
/// The per-process limit on the number of open file descriptors has been reached.
ProcessFdQuotaExceeded,