Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions lib/std/os/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2201,10 +2201,12 @@ pub fn accept4(fd: i32, noalias addr: ?*sockaddr, noalias len: ?*socklen_t, flag
return syscall4(.accept4, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(addr), @intFromPtr(len), flags);
}

// riscv32 and loongarch have made the interesting decision to not implement some of
// the older stat syscalls, including this one.
pub const have_fstat = !(native_arch == .riscv32 or is_loongarch);

pub fn fstat(fd: i32, stat_buf: *Stat) usize {
if (native_arch == .riscv32 or native_arch.isLoongArch()) {
// riscv32 and loongarch have made the interesting decision to not implement some of
// the older stat syscalls, including this one.
if (!have_fstat) {
@compileError("No fstat syscall on this architecture.");
} else if (@hasField(SYS, "fstat64")) {
return syscall2(.fstat64, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(stat_buf));
Expand All @@ -2214,9 +2216,7 @@ pub fn fstat(fd: i32, stat_buf: *Stat) usize {
}

pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize {
if (native_arch == .riscv32 or native_arch.isLoongArch()) {
// riscv32 and loongarch have made the interesting decision to not implement some of
// the older stat syscalls, including this one.
if (!have_fstat) {
@compileError("No stat syscall on this architecture.");
} else if (@hasField(SYS, "stat64")) {
return syscall2(.stat64, @intFromPtr(pathname), @intFromPtr(statbuf));
Expand All @@ -2226,9 +2226,7 @@ pub fn stat(pathname: [*:0]const u8, statbuf: *Stat) usize {
}

pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize {
if (native_arch == .riscv32 or native_arch.isLoongArch()) {
// riscv32 and loongarch have made the interesting decision to not implement some of
// the older stat syscalls, including this one.
if (!have_fstat) {
@compileError("No lstat syscall on this architecture.");
} else if (@hasField(SYS, "lstat64")) {
return syscall2(.lstat64, @intFromPtr(pathname), @intFromPtr(statbuf));
Expand All @@ -2238,9 +2236,7 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize {
}

pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usize {
if (native_arch == .riscv32 or native_arch.isLoongArch()) {
// riscv32 and loongarch have made the interesting decision to not implement some of
// the older stat syscalls, including this one.
if (!have_fstat) {
@compileError("No fstatat syscall on this architecture.");
} else if (@hasField(SYS, "fstatat64")) {
return syscall4(.fstatat64, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(stat_buf), flags);
Expand Down
11 changes: 11 additions & 0 deletions src/link/MappedFile.zig
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ pub fn init(file: std.Io.File, gpa: std.mem.Allocator) !MappedFile {
else => std.heap.page_size_max,
},
};
} else if (is_linux) {
var statx: linux.Statx = undefined;
switch (linux.errno(linux.statx(mf.file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_TYPE | linux.STATX_SIZE, &statx))) {
.SUCCESS => {},
.INVAL, .LOOP => unreachable,
.NOMEM => return error.SystemResources,
.ACCES => return error.AccessDenied,
else => |err| return std.posix.unexpectedErrno(err),
}
if (statx.mode != linux.S.IFREG) return error.PathAlreadyExists;
break :stat .{ statx.size, @max(std.heap.pageSize(), statx.blksize) };
}
const stat = try std.posix.fstat(mf.file.handle);
if (!std.posix.S.ISREG(stat.mode)) return error.PathAlreadyExists;
Expand Down
Loading