@@ -342,7 +342,7 @@ pub fn seekTo(self: File, offset: u64) SeekError!void {
342
342
return posix .lseek_SET (self .handle , offset );
343
343
}
344
344
345
- pub const GetSeekPosError = posix .SeekError || posix . FStatError ;
345
+ pub const GetSeekPosError = posix .SeekError || StatError ;
346
346
347
347
/// TODO: integrate with async I/O
348
348
pub fn getPos (self : File ) GetSeekPosError ! u64 {
@@ -357,7 +357,7 @@ pub fn getEndPos(self: File) GetSeekPosError!u64 {
357
357
return (try self .stat ()).size ;
358
358
}
359
359
360
- pub const ModeError = posix . FStatError ;
360
+ pub const ModeError = StatError ;
361
361
362
362
/// TODO: integrate with async I/O
363
363
pub fn mode (self : File ) ModeError ! Mode {
@@ -392,7 +392,7 @@ pub const Stat = struct {
392
392
/// Last status/metadata change time in nanoseconds, relative to UTC 1970-01-01.
393
393
ctime : i128 ,
394
394
395
- pub fn fromSystem (st : posix.Stat ) Stat {
395
+ pub fn fromPosix (st : posix.Stat ) Stat {
396
396
const atime = st .atime ();
397
397
const mtime = st .mtime ();
398
398
const ctime = st .ctime ();
@@ -426,6 +426,31 @@ pub const Stat = struct {
426
426
};
427
427
}
428
428
429
+ pub fn fromLinux (stx : linux.Statx ) Stat {
430
+ const atime = stx .atime ;
431
+ const mtime = stx .mtime ;
432
+ const ctime = stx .ctime ;
433
+
434
+ return .{
435
+ .inode = stx .ino ,
436
+ .size = stx .size ,
437
+ .mode = stx .mode ,
438
+ .kind = switch (stx .mode & linux .S .IFMT ) {
439
+ linux .S .IFDIR = > .directory ,
440
+ linux .S .IFCHR = > .character_device ,
441
+ linux .S .IFBLK = > .block_device ,
442
+ linux .S .IFREG = > .file ,
443
+ linux .S .IFIFO = > .named_pipe ,
444
+ linux .S .IFLNK = > .sym_link ,
445
+ linux .S .IFSOCK = > .unix_domain_socket ,
446
+ else = > .unknown ,
447
+ },
448
+ .atime = @as (i128 , atime .sec ) * std .time .ns_per_s + atime .nsec ,
449
+ .mtime = @as (i128 , mtime .sec ) * std .time .ns_per_s + mtime .nsec ,
450
+ .ctime = @as (i128 , ctime .sec ) * std .time .ns_per_s + ctime .nsec ,
451
+ };
452
+ }
453
+
429
454
pub fn fromWasi (st : std.os.wasi.filestat_t ) Stat {
430
455
return .{
431
456
.inode = st .ino ,
@@ -502,8 +527,34 @@ pub fn stat(self: File) StatError!Stat {
502
527
return Stat .fromWasi (st );
503
528
}
504
529
530
+ if (builtin .os .tag == .linux ) {
531
+ var stx = std .mem .zeroes (linux .Statx );
532
+
533
+ const rc = linux .statx (
534
+ self .handle ,
535
+ "" ,
536
+ linux .AT .EMPTY_PATH ,
537
+ linux .STATX_TYPE | linux .STATX_MODE | linux .STATX_ATIME | linux .STATX_MTIME | linux .STATX_CTIME ,
538
+ & stx ,
539
+ );
540
+
541
+ return switch (linux .E .init (rc )) {
542
+ .SUCCESS = > Stat .fromLinux (stx ),
543
+ .ACCES = > unreachable ,
544
+ .BADF = > unreachable ,
545
+ .FAULT = > unreachable ,
546
+ .INVAL = > unreachable ,
547
+ .LOOP = > unreachable ,
548
+ .NAMETOOLONG = > unreachable ,
549
+ .NOENT = > unreachable ,
550
+ .NOMEM = > error .SystemResources ,
551
+ .NOTDIR = > unreachable ,
552
+ else = > | err | posix .unexpectedErrno (err ),
553
+ };
554
+ }
555
+
505
556
const st = try posix .fstat (self .handle );
506
- return Stat .fromSystem (st );
557
+ return Stat .fromPosix (st );
507
558
}
508
559
509
560
pub const ChmodError = posix .FChmodError ;
@@ -1009,16 +1060,29 @@ pub fn metadata(self: File) MetadataError!Metadata {
1009
1060
};
1010
1061
},
1011
1062
.linux = > blk : {
1012
- const l = std .os .linux ;
1013
- var stx = std .mem .zeroes (l .Statx );
1014
- const rcx = l .statx (self .handle , "\x00 " , l .AT .EMPTY_PATH , l .STATX_TYPE |
1015
- l .STATX_MODE | l .STATX_ATIME | l .STATX_MTIME | l .STATX_BTIME , & stx );
1016
-
1017
- switch (posix .errno (rcx )) {
1063
+ var stx = std .mem .zeroes (linux .Statx );
1064
+
1065
+ // We are gathering information for Metadata, which is meant to contain all the
1066
+ // native OS information about the file, so use all known flags.
1067
+ const rc = linux .statx (
1068
+ self .handle ,
1069
+ "" ,
1070
+ linux .AT .EMPTY_PATH ,
1071
+ linux .STATX_BASIC_STATS | linux .STATX_BTIME ,
1072
+ & stx ,
1073
+ );
1074
+
1075
+ switch (posix .errno (rc )) {
1018
1076
.SUCCESS = > {},
1077
+ .ACCES = > unreachable ,
1019
1078
.BADF = > unreachable ,
1020
1079
.FAULT = > unreachable ,
1080
+ .INVAL = > unreachable ,
1081
+ .LOOP = > unreachable ,
1082
+ .NAMETOOLONG = > unreachable ,
1083
+ .NOENT = > unreachable ,
1021
1084
.NOMEM = > return error .SystemResources ,
1085
+ .NOTDIR = > unreachable ,
1022
1086
else = > | err | return posix .unexpectedErrno (err ),
1023
1087
}
1024
1088
@@ -1712,6 +1776,7 @@ const posix = std.posix;
1712
1776
const io = std .io ;
1713
1777
const math = std .math ;
1714
1778
const assert = std .debug .assert ;
1779
+ const linux = std .os .linux ;
1715
1780
const windows = std .os .windows ;
1716
1781
const Os = std .builtin .Os ;
1717
1782
const maxInt = std .math .maxInt ;
0 commit comments