Skip to content

Commit 0210bb7

Browse files
committed
std.posix: Add riscv32 support.
1 parent 820c093 commit 0210bb7

File tree

1 file changed

+90
-2
lines changed

1 file changed

+90
-2
lines changed

lib/std/posix.zig

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ else switch (native_os) {
4848
else => struct {},
4949
};
5050

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+
5154
pub const AF = system.AF;
5255
pub const AF_SUN = system.AF_SUN;
5356
pub const ARCH = system.ARCH;
@@ -103,7 +106,35 @@ pub const STDIN_FILENO = system.STDIN_FILENO;
103106
pub const STDOUT_FILENO = system.STDOUT_FILENO;
104107
pub const SYS = system.SYS;
105108
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;
107138
pub const T = system.T;
108139
pub const TCSA = system.TCSA;
109140
pub const TCP = system.TCP;
@@ -4292,6 +4323,17 @@ pub fn fstat(fd: fd_t) FStatError!Stat {
42924323
@compileError("fstat is not yet implemented on Windows");
42934324
}
42944325

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+
42954337
const fstat_sym = if (lfs64_abi) system.fstat64 else system.fstat;
42964338
var stat = mem.zeroes(Stat);
42974339
switch (errno(fstat_sym(fd, &stat))) {
@@ -4331,6 +4373,46 @@ pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat
43314373
}
43324374
}
43334375

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+
43344416
/// Same as `fstatat` but `pathname` is null-terminated.
43354417
/// See also `fstatat`.
43364418
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
43414423
return Stat.fromFilestat(filestat);
43424424
}
43434425

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+
43454433
var stat = mem.zeroes(Stat);
43464434
switch (errno(fstatat_sym(dirfd, pathname, &stat, flags))) {
43474435
.SUCCESS => return stat,

0 commit comments

Comments
 (0)