mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 16:24:51 +00:00
Merge pull request #3439 from LemonBoy/statx
Add support for the statx syscall
This commit is contained in:
commit
312880f102
@ -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,
|
||||
};
|
||||
|
||||
@ -6,6 +6,8 @@ const iovec = linux.iovec;
|
||||
const iovec_const = linux.iovec_const;
|
||||
const stack_t = linux.stack_t;
|
||||
const sigset_t = linux.sigset_t;
|
||||
const uid_t = linux.uid_t;
|
||||
const gid_t = linux.gid_t;
|
||||
|
||||
pub const SYS_restart_syscall = 0;
|
||||
pub const SYS_exit = 1;
|
||||
@ -512,7 +514,14 @@ pub const msghdr_const = extern struct {
|
||||
msg_flags: i32,
|
||||
};
|
||||
|
||||
pub const blksize_t = i32;
|
||||
pub const nlink_t = u32;
|
||||
pub const time_t = isize;
|
||||
pub const mode_t = u32;
|
||||
pub const off_t = i64;
|
||||
pub const ino_t = u64;
|
||||
pub const dev_t = u64;
|
||||
pub const blkcnt_t = i64;
|
||||
|
||||
/// Renamed to Stat to not conflict with the stat function.
|
||||
/// atime, mtime, and ctime have functions to return `timespec`,
|
||||
@ -521,22 +530,22 @@ pub const off_t = i64;
|
||||
/// in C, macros are used to hide the differences. Here we use
|
||||
/// methods to accomplish this.
|
||||
pub const Stat = extern struct {
|
||||
dev: u64,
|
||||
dev: dev_t,
|
||||
__dev_padding: u32,
|
||||
__ino_truncated: u32,
|
||||
mode: u32,
|
||||
nlink: u32,
|
||||
uid: u32,
|
||||
gid: u32,
|
||||
rdev: u64,
|
||||
mode: mode_t,
|
||||
nlink: nlink_t,
|
||||
uid: uid_t,
|
||||
gid: gid_t,
|
||||
rdev: dev_t,
|
||||
__rdev_padding: u32,
|
||||
size: off_t,
|
||||
blksize: i32,
|
||||
blocks: u64,
|
||||
blksize: blksize_t,
|
||||
blocks: blkcnt_t,
|
||||
atim: timespec,
|
||||
mtim: timespec,
|
||||
ctim: timespec,
|
||||
ino: u64,
|
||||
ino: ino_t,
|
||||
|
||||
pub fn atime(self: Stat) timespec {
|
||||
return self.atim;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user