| author | |
| committer | |
| log | 312880f10243b3074c3f176fbea6b9994e733f56 |
| tree | 440391f85a19f8414c0e49218f62c697fbb6db17 |
| parent | 3af2202ea4a5950541ee369a005f8e4484d544ab |
| parent | ead9630c135b86c77de9774635f7b5c55ce62f41 |
| signature |
Add support for the statx syscall4 files changed, 142 insertions(+), 9 deletions(-)
lib/std/os/bits/linux.zig+78| ... | ... | @@ -1293,3 +1293,81 @@ pub const utsname = extern struct { |
| 1293 | 1293 | domainname: [65]u8, |
| 1294 | 1294 | }; |
| 1295 | 1295 | pub const HOST_NAME_MAX = 64; |
| 1296 | ||
| 1297 | pub const STATX_TYPE = 0x0001; | |
| 1298 | pub const STATX_MODE = 0x0002; | |
| 1299 | pub const STATX_NLINK = 0x0004; | |
| 1300 | pub const STATX_UID = 0x0008; | |
| 1301 | pub const STATX_GID = 0x0010; | |
| 1302 | pub const STATX_ATIME = 0x0020; | |
| 1303 | pub const STATX_MTIME = 0x0040; | |
| 1304 | pub const STATX_CTIME = 0x0080; | |
| 1305 | pub const STATX_INO = 0x0100; | |
| 1306 | pub const STATX_SIZE = 0x0200; | |
| 1307 | pub const STATX_BLOCKS = 0x0400; | |
| 1308 | pub const STATX_BASIC_STATS = 0x07ff; | |
| 1309 | ||
| 1310 | pub const STATX_BTIME = 0x0800; | |
| 1311 | ||
| 1312 | pub const STATX_ATTR_COMPRESSED = 0x0004; | |
| 1313 | pub const STATX_ATTR_IMMUTABLE = 0x0010; | |
| 1314 | pub const STATX_ATTR_APPEND = 0x0020; | |
| 1315 | pub const STATX_ATTR_NODUMP = 0x0040; | |
| 1316 | pub const STATX_ATTR_ENCRYPTED = 0x0800; | |
| 1317 | pub const STATX_ATTR_AUTOMOUNT = 0x1000; | |
| 1318 | ||
| 1319 | pub const statx_timestamp = extern struct { | |
| 1320 | tv_sec: i64, | |
| 1321 | tv_nsec: u32, | |
| 1322 | __pad1: u32, | |
| 1323 | }; | |
| 1324 | ||
| 1325 | pub 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/bits/linux/arm-eabi.zig+18-9| ... | ... | @@ -6,6 +6,8 @@ const iovec = linux.iovec; |
| 6 | 6 | const iovec_const = linux.iovec_const; |
| 7 | 7 | const stack_t = linux.stack_t; |
| 8 | 8 | const sigset_t = linux.sigset_t; |
| 9 | const uid_t = linux.uid_t; | |
| 10 | const gid_t = linux.gid_t; | |
| 9 | 11 | |
| 10 | 12 | pub const SYS_restart_syscall = 0; |
| 11 | 13 | pub const SYS_exit = 1; |
| ... | ... | @@ -512,7 +514,14 @@ pub const msghdr_const = extern struct { |
| 512 | 514 | msg_flags: i32, |
| 513 | 515 | }; |
| 514 | 516 | |
| 517 | pub const blksize_t = i32; | |
| 518 | pub const nlink_t = u32; | |
| 519 | pub const time_t = isize; | |
| 520 | pub const mode_t = u32; | |
| 515 | 521 | pub const off_t = i64; |
| 522 | pub const ino_t = u64; | |
| 523 | pub const dev_t = u64; | |
| 524 | pub const blkcnt_t = i64; | |
| 516 | 525 | |
| 517 | 526 | /// Renamed to Stat to not conflict with the stat function. |
| 518 | 527 | /// atime, mtime, and ctime have functions to return `timespec`, |
| ... | ... | @@ -521,22 +530,22 @@ pub const off_t = i64; |
| 521 | 530 | /// in C, macros are used to hide the differences. Here we use |
| 522 | 531 | /// methods to accomplish this. |
| 523 | 532 | pub const Stat = extern struct { |
| 524 | dev: u64, | |
| 533 | dev: dev_t, | |
| 525 | 534 | __dev_padding: u32, |
| 526 | 535 | __ino_truncated: u32, |
| 527 | mode: u32, | |
| 528 | nlink: u32, | |
| 529 | uid: u32, | |
| 530 | gid: u32, | |
| 531 | rdev: u64, | |
| 536 | mode: mode_t, | |
| 537 | nlink: nlink_t, | |
| 538 | uid: uid_t, | |
| 539 | gid: gid_t, | |
| 540 | rdev: dev_t, | |
| 532 | 541 | __rdev_padding: u32, |
| 533 | 542 | size: off_t, |
| 534 | blksize: i32, | |
| 535 | blocks: u64, | |
| 543 | blksize: blksize_t, | |
| 544 | blocks: blkcnt_t, | |
| 536 | 545 | atim: timespec, |
| 537 | 546 | mtim: timespec, |
| 538 | 547 | ctim: timespec, |
| 539 | ino: u64, | |
| 548 | ino: ino_t, | |
| 540 | 549 | |
| 541 | 550 | pub fn atime(self: Stat) timespec { |
| 542 | 551 | return self.atim; |
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 | 860 | } |
| 861 | 861 | } |
| 862 | 862 | |
| 863 | pub 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 | 877 | // TODO https://github.com/ziglang/zig/issues/265 |
| 864 | 878 | pub fn listxattr(path: [*]const u8, list: [*]u8, size: usize) usize { |
| 865 | 879 | return syscall3(SYS_listxattr, @ptrToInt(path), @ptrToInt(list), size); |
lib/std/os/linux/test.zig+32| ... | ... | @@ -44,3 +44,35 @@ test "timer" { |
| 44 | 44 | // TODO implicit cast from *[N]T to [*]T |
| 45 | 45 | err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1); |
| 46 | 46 | } |
| 47 | ||
| 48 | const File = std.fs.File; | |
| 49 | ||
| 50 | test "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 | } |