Commit 40fc7a1fda
lib/std/os/bits/linux.zig
@@ -1293,3 +1293,81 @@ pub const utsname = extern struct {
domainname: [65]u8,
};
pub const HOST_NAME_MAX = 64;
+
+pub const STATX_TYPE = 0x0001;
+pub const STATX_MODE = 0x0002;
+pub const STATX_NLINK = 0x0004;
+pub const STATX_UID = 0x0008;
+pub const STATX_GID = 0x0010;
+pub const STATX_ATIME = 0x0020;
+pub const STATX_MTIME = 0x0040;
+pub const STATX_CTIME = 0x0080;
+pub const STATX_INO = 0x0100;
+pub const STATX_SIZE = 0x0200;
+pub const STATX_BLOCKS = 0x0400;
+pub const STATX_BASIC_STATS = 0x07ff;
+
+pub const STATX_BTIME = 0x0800;
+
+pub const STATX_ATTR_COMPRESSED = 0x0004;
+pub const STATX_ATTR_IMMUTABLE = 0x0010;
+pub const STATX_ATTR_APPEND = 0x0020;
+pub const STATX_ATTR_NODUMP = 0x0040;
+pub const STATX_ATTR_ENCRYPTED = 0x0800;
+pub const STATX_ATTR_AUTOMOUNT = 0x1000;
+
+pub const statx_timestamp = extern struct {
+ tv_sec: i64,
+ tv_nsec: u32,
+ __pad1: u32,
+};
+
+pub const Statx = extern struct {
+ // Mask of bits indicating filled fields
+ stx_mask: u32,
+ // Block size for filesystem I/O
+ stx_blksize: u32,
+ // Extra file attribute indicators
+ stx_attributes: u64,
+ // Number of hard links
+ stx_nlink: u32,
+ // User ID of owner
+ stx_uid: u32,
+ // Group ID of owner
+ stx_gid: u32,
+ // File type and mode
+ stx_mode: u16,
+ __pad1: u16,
+ // Inode number
+ stx_ino: u64,
+ // Total size in bytes
+ stx_size: u64,
+ // Number of 512B blocks allocated
+ stx_blocks: u64,
+ // Mask to show what's supported in stx_attributes
+ stx_attributes_mask: u64,
+
+ // The following fields are file timestamps
+ // Last access
+ stx_atime: statx_timestamp,
+ // Creation
+ stx_btime: statx_timestamp,
+ // Last status change
+ stx_ctime: statx_timestamp,
+ // Last modification
+ stx_mtime: statx_timestamp,
+
+ // If this file represents a device, then the next two fields contain the ID of the device
+ // Major ID
+ stx_rdev_major: u32,
+ // Minor ID
+ stx_rdev_minor: u32,
+
+ // The next two fields contain the ID of the device containing the filesystem where the file resides
+ // Major ID
+ stx_dev_major: u32,
+ // Minor ID
+ stx_dev_minor: u32,
+
+ __pad2: [14]u64,
+};
lib/std/os/linux/test.zig
@@ -44,3 +44,35 @@ test "timer" {
// TODO implicit cast from *[N]T to [*]T
err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);
}
+
+const File = std.fs.File;
+
+test "statx" {
+ const tmp_file_name = "just_a_temporary_file.txt";
+ var file = try File.openWrite(tmp_file_name);
+ defer {
+ file.close();
+ std.fs.deleteFile(tmp_file_name) catch {};
+ }
+
+ var statx_buf: linux.Statx = undefined;
+ switch (linux.getErrno(linux.statx(file.handle, c"", linux.AT_EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
+ 0 => {},
+ // The statx syscall was only introduced in linux 4.11
+ linux.ENOSYS => return error.SkipZigTest,
+ else => unreachable,
+ }
+
+ var stat_buf: linux.Stat = undefined;
+ switch (linux.getErrno(linux.fstatat(file.handle, c"", &stat_buf, linux.AT_EMPTY_PATH))) {
+ 0 => {},
+ else => unreachable,
+ }
+
+ expect(stat_buf.mode == statx_buf.stx_mode);
+ expect(@bitCast(u32, stat_buf.uid) == statx_buf.stx_uid);
+ expect(@bitCast(u32, stat_buf.gid) == statx_buf.stx_gid);
+ expect(@bitCast(u64, i64(stat_buf.size)) == statx_buf.stx_size);
+ expect(@bitCast(u64, i64(stat_buf.blksize)) == statx_buf.stx_blksize);
+ expect(@bitCast(u64, i64(stat_buf.blocks)) == statx_buf.stx_blocks);
+}
lib/std/os/linux.zig
@@ -860,6 +860,20 @@ pub fn fstatat(dirfd: i32, path: [*]const u8, stat_buf: *Stat, flags: u32) usize
}
}
+pub fn statx(dirfd: i32, path: [*]const u8, flags: u32, mask: u32, statx_buf: *Statx) usize {
+ if (@hasDecl(@This(), "SYS_statx")) {
+ return syscall5(
+ SYS_statx,
+ @bitCast(usize, isize(dirfd)),
+ @ptrToInt(path),
+ flags,
+ mask,
+ @ptrToInt(statx_buf),
+ );
+ }
+ return @bitCast(usize, isize(-ENOSYS));
+}
+
// TODO https://github.com/ziglang/zig/issues/265
pub fn listxattr(path: [*]const u8, list: [*]u8, size: usize) usize {
return syscall3(SYS_listxattr, @ptrToInt(path), @ptrToInt(list), size);