authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-10-12 14:55:02+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-10-12 20:51:51+02:00
log40fc7a1fdac23b1799ebce69c2a65236886bc360
tree724e184f57ab33daa05aa94959e5017dfd35d8a0
parent8b45921664c8f679c8154b45add84f84e3ec8128

Add support for the statx syscall


3 files changed, 124 insertions(+), 0 deletions(-)

lib/std/os/bits/linux.zig+78
...@@ -1293,3 +1293,81 @@ pub const utsname = extern struct {...@@ -1293,3 +1293,81 @@ pub const utsname = extern struct {
1293 domainname: [65]u8,1293 domainname: [65]u8,
1294};1294};
1295pub const HOST_NAME_MAX = 64;1295pub const HOST_NAME_MAX = 64;
1296
1297pub const STATX_TYPE = 0x0001;
1298pub const STATX_MODE = 0x0002;
1299pub const STATX_NLINK = 0x0004;
1300pub const STATX_UID = 0x0008;
1301pub const STATX_GID = 0x0010;
1302pub const STATX_ATIME = 0x0020;
1303pub const STATX_MTIME = 0x0040;
1304pub const STATX_CTIME = 0x0080;
1305pub const STATX_INO = 0x0100;
1306pub const STATX_SIZE = 0x0200;
1307pub const STATX_BLOCKS = 0x0400;
1308pub const STATX_BASIC_STATS = 0x07ff;
1309
1310pub const STATX_BTIME = 0x0800;
1311
1312pub const STATX_ATTR_COMPRESSED = 0x0004;
1313pub const STATX_ATTR_IMMUTABLE = 0x0010;
1314pub const STATX_ATTR_APPEND = 0x0020;
1315pub const STATX_ATTR_NODUMP = 0x0040;
1316pub const STATX_ATTR_ENCRYPTED = 0x0800;
1317pub const STATX_ATTR_AUTOMOUNT = 0x1000;
1318
1319pub const statx_timestamp = extern struct {
1320 tv_sec: i64,
1321 tv_nsec: u32,
1322 __pad1: u32,
1323};
1324
1325pub const Statx = extern struct {
1326 // Mask of bits indicating filled fields
1327 stx_mask: u32,
1328 // Block size for filesystem I/O
1329 stx_blksize: u32,
1330 // Extra file attribute indicators
1331 stx_attributes: u64,
1332 // Number of hard links
1333 stx_nlink: u32,
1334 // User ID of owner
1335 stx_uid: u32,
1336 // Group ID of owner
1337 stx_gid: u32,
1338 // File type and mode
1339 stx_mode: u16,
1340 __pad1: u16,
1341 // Inode number
1342 stx_ino: u64,
1343 // Total size in bytes
1344 stx_size: u64,
1345 // Number of 512B blocks allocated
1346 stx_blocks: u64,
1347 // Mask to show what's supported in stx_attributes
1348 stx_attributes_mask: u64,
1349
1350 // The following fields are file timestamps
1351 // Last access
1352 stx_atime: statx_timestamp,
1353 // Creation
1354 stx_btime: statx_timestamp,
1355 // Last status change
1356 stx_ctime: statx_timestamp,
1357 // Last modification
1358 stx_mtime: statx_timestamp,
1359
1360 // If this file represents a device, then the next two fields contain the ID of the device
1361 // Major ID
1362 stx_rdev_major: u32,
1363 // Minor ID
1364 stx_rdev_minor: u32,
1365
1366 // The next two fields contain the ID of the device containing the filesystem where the file resides
1367 // Major ID
1368 stx_dev_major: u32,
1369 // Minor ID
1370 stx_dev_minor: u32,
1371
1372 __pad2: [14]u64,
1373};
lib/std/os/linux.zig+14
...@@ -860,6 +860,20 @@ pub fn fstatat(dirfd: i32, path: [*]const u8, stat_buf: *Stat, flags: u32) usize...@@ -860,6 +860,20 @@ pub fn fstatat(dirfd: i32, path: [*]const u8, stat_buf: *Stat, flags: u32) usize
860 }860 }
861}861}
862862
863pub fn statx(dirfd: i32, path: [*]const u8, flags: u32, mask: u32, statx_buf: *Statx) usize {
864 if (@hasDecl(@This(), "SYS_statx")) {
865 return syscall5(
866 SYS_statx,
867 @bitCast(usize, isize(dirfd)),
868 @ptrToInt(path),
869 flags,
870 mask,
871 @ptrToInt(statx_buf),
872 );
873 }
874 return @bitCast(usize, isize(-ENOSYS));
875}
876
863// TODO https://github.com/ziglang/zig/issues/265877// TODO https://github.com/ziglang/zig/issues/265
864pub fn listxattr(path: [*]const u8, list: [*]u8, size: usize) usize {878pub fn listxattr(path: [*]const u8, list: [*]u8, size: usize) usize {
865 return syscall3(SYS_listxattr, @ptrToInt(path), @ptrToInt(list), size);879 return syscall3(SYS_listxattr, @ptrToInt(path), @ptrToInt(list), size);
lib/std/os/linux/test.zig+32
...@@ -44,3 +44,35 @@ test "timer" {...@@ -44,3 +44,35 @@ test "timer" {
44 // TODO implicit cast from *[N]T to [*]T44 // TODO implicit cast from *[N]T to [*]T
45 err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);45 err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);
46}46}
47
48const File = std.fs.File;
49
50test "statx" {
51 const tmp_file_name = "just_a_temporary_file.txt";
52 var file = try File.openWrite(tmp_file_name);
53 defer {
54 file.close();
55 std.fs.deleteFile(tmp_file_name) catch {};
56 }
57
58 var statx_buf: linux.Statx = undefined;
59 switch (linux.getErrno(linux.statx(file.handle, c"", linux.AT_EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
60 0 => {},
61 // The statx syscall was only introduced in linux 4.11
62 linux.ENOSYS => return error.SkipZigTest,
63 else => unreachable,
64 }
65
66 var stat_buf: linux.Stat = undefined;
67 switch (linux.getErrno(linux.fstatat(file.handle, c"", &stat_buf, linux.AT_EMPTY_PATH))) {
68 0 => {},
69 else => unreachable,
70 }
71
72 expect(stat_buf.mode == statx_buf.stx_mode);
73 expect(@bitCast(u32, stat_buf.uid) == statx_buf.stx_uid);
74 expect(@bitCast(u32, stat_buf.gid) == statx_buf.stx_gid);
75 expect(@bitCast(u64, i64(stat_buf.size)) == statx_buf.stx_size);
76 expect(@bitCast(u64, i64(stat_buf.blksize)) == statx_buf.stx_blksize);
77 expect(@bitCast(u64, i64(stat_buf.blocks)) == statx_buf.stx_blocks);
78}