@@ -48,6 +48,9 @@ else switch (native_os) {
48
48
else = > struct {},
49
49
};
50
50
51
+ // riscv32-linux only has the statx syscall; no fstat or fstatat.
52
+ const no_stat = ! use_libc and native_os == .linux and builtin .cpu .arch == .riscv32 ;
53
+
51
54
pub const AF = system .AF ;
52
55
pub const AF_SUN = system .AF_SUN ;
53
56
pub const ARCH = system .ARCH ;
@@ -103,7 +106,35 @@ pub const STDIN_FILENO = system.STDIN_FILENO;
103
106
pub const STDOUT_FILENO = system .STDOUT_FILENO ;
104
107
pub const SYS = system .SYS ;
105
108
pub const Sigaction = system .Sigaction ;
106
- pub const Stat = system .Stat ;
109
+ pub const Stat = if (no_stat ) struct {
110
+ // The system does not have a native stat structure. Make one up.
111
+
112
+ dev : dev_t ,
113
+ ino : ino_t ,
114
+ mode : mode_t ,
115
+ nlink : nlink_t ,
116
+ uid : uid_t ,
117
+ gid : gid_t ,
118
+ rdev : dev_t ,
119
+ size : off_t ,
120
+ blksize : blksize_t ,
121
+ blocks : blkcnt_t ,
122
+ atim : timespec ,
123
+ mtim : timespec ,
124
+ ctim : timespec ,
125
+
126
+ pub fn atime (self : @This ()) timespec {
127
+ return self .atim ;
128
+ }
129
+
130
+ pub fn mtime (self : @This ()) timespec {
131
+ return self .mtim ;
132
+ }
133
+
134
+ pub fn ctime (self : @This ()) timespec {
135
+ return self .ctim ;
136
+ }
137
+ } else system .Stat ;
107
138
pub const T = system .T ;
108
139
pub const TCSA = system .TCSA ;
109
140
pub const TCP = system .TCP ;
@@ -4292,6 +4323,17 @@ pub fn fstat(fd: fd_t) FStatError!Stat {
4292
4323
@compileError ("fstat is not yet implemented on Windows" );
4293
4324
}
4294
4325
4326
+ if (no_stat ) {
4327
+ return fstatatZ (fd , "\x00 " , AT .EMPTY_PATH ) catch | err | switch (err ) {
4328
+ error .FileNotFound ,
4329
+ error .NameTooLong ,
4330
+ error .InvalidUtf8 ,
4331
+ error .SymLinkLoop ,
4332
+ = > unreachable ,
4333
+ else = > | e | return e ,
4334
+ };
4335
+ }
4336
+
4295
4337
const fstat_sym = if (lfs64_abi ) system .fstat64 else system .fstat ;
4296
4338
var stat = mem .zeroes (Stat );
4297
4339
switch (errno (fstat_sym (fd , & stat ))) {
@@ -4331,6 +4373,46 @@ pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat
4331
4373
}
4332
4374
}
4333
4375
4376
+ // MKDEV in the kernel.
4377
+ inline fn makedevLinux (major : u32 , minor : u32 ) dev_t {
4378
+ return (major << 20 ) | minor ;
4379
+ }
4380
+
4381
+ fn fstatatStatxZ (dirfd : fd_t , pathname : [* :0 ]const u8 , stat_buf : * Stat , flags : u32 ) usize {
4382
+ var statx = mem .zeroes (linux .Statx );
4383
+ const rc = linux .statx (dirfd , pathname , flags | AT .NO_AUTOMOUNT , linux .STATX_BASIC_STATS , & statx );
4384
+ const rcs : isize = @bitCast (rc );
4385
+
4386
+ if (rcs > -4096 ) return rc ;
4387
+
4388
+ stat_buf .* = .{
4389
+ .dev = makedevLinux (statx .dev_major , statx .dev_minor ),
4390
+ .rdev = makedevLinux (statx .rdev_major , statx .rdev_minor ),
4391
+ .ino = statx .ino ,
4392
+ .mode = statx .mode ,
4393
+ .nlink = statx .nlink ,
4394
+ .uid = statx .uid ,
4395
+ .gid = statx .gid ,
4396
+ .atim = .{
4397
+ .tv_sec = statx .atime .tv_sec ,
4398
+ .tv_nsec = statx .atime .tv_nsec ,
4399
+ },
4400
+ .mtim = .{
4401
+ .tv_sec = statx .mtime .tv_sec ,
4402
+ .tv_nsec = statx .mtime .tv_nsec ,
4403
+ },
4404
+ .ctim = .{
4405
+ .tv_sec = statx .ctime .tv_sec ,
4406
+ .tv_nsec = statx .ctime .tv_nsec ,
4407
+ },
4408
+ .size = @as (i64 , @intCast (statx .size )),
4409
+ .blocks = @as (i64 , @intCast (statx .blocks )),
4410
+ .blksize = @as (i32 , @intCast (statx .blksize )),
4411
+ };
4412
+
4413
+ return rc ;
4414
+ }
4415
+
4334
4416
/// Same as `fstatat` but `pathname` is null-terminated.
4335
4417
/// See also `fstatat`.
4336
4418
pub fn fstatatZ (dirfd : fd_t , pathname : [* :0 ]const u8 , flags : u32 ) FStatAtError ! Stat {
@@ -4341,7 +4423,13 @@ pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!S
4341
4423
return Stat .fromFilestat (filestat );
4342
4424
}
4343
4425
4344
- const fstatat_sym = if (lfs64_abi ) system .fstatat64 else system .fstatat ;
4426
+ const fstatat_sym = if (no_stat )
4427
+ fstatatStatxZ
4428
+ else if (lfs64_abi )
4429
+ system .fstatat64
4430
+ else
4431
+ system .fstatat ;
4432
+
4345
4433
var stat = mem .zeroes (Stat );
4346
4434
switch (errno (fstatat_sym (dirfd , pathname , & stat , flags ))) {
4347
4435
.SUCCESS = > return stat ,
0 commit comments