Commit 6b4f45f782
Changed files (15)
lib
src
link
lib/std/fs/Dir.zig
@@ -378,7 +378,7 @@ pub const Iterator = switch (native_os) {
self.first_iter = false;
}
const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len);
- switch (linux.E.init(rc)) {
+ switch (linux.errno(rc)) {
.SUCCESS => {},
.BADF => unreachable, // Dir is invalid or was opened without iteration ability
.FAULT => unreachable,
lib/std/Io/Threaded.zig
@@ -1302,7 +1302,7 @@ fn dirStatPathLinux(
linux.STATX_INO | linux.STATX_SIZE | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
&statx,
);
- switch (linux.E.init(rc)) {
+ switch (linux.errno(rc)) {
.SUCCESS => return statFromLinux(&statx),
.INTR => continue,
.CANCELED => return error.Canceled,
@@ -1449,7 +1449,7 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
linux.STATX_INO | linux.STATX_SIZE | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
&statx,
);
- switch (linux.E.init(rc)) {
+ switch (linux.errno(rc)) {
.SUCCESS => return statFromLinux(&statx),
.INTR => continue,
.CANCELED => return error.Canceled,
@@ -2931,7 +2931,7 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);
while (true) {
try t.checkCancel();
- switch (std.os.linux.E.init(std.os.linux.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {
+ switch (std.os.linux.errno(std.os.linux.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {
.none, .duration => false,
.deadline => true,
} }, ×pec, ×pec))) {
@@ -5677,7 +5677,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca
const linux = std.os.linux;
try t.checkCancel();
const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);
- if (is_debug) switch (linux.E.init(rc)) {
+ if (is_debug) switch (linux.errno(rc)) {
.SUCCESS => {}, // notified by `wake()`
.INTR => {}, // gives caller a chance to check cancellation
.AGAIN => {}, // ptr.* != expect
@@ -5764,7 +5764,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
.linux => {
const linux = std.os.linux;
const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);
- switch (linux.E.init(rc)) {
+ switch (linux.errno(rc)) {
.SUCCESS => {}, // notified by `wake()`
.INTR => {}, // gives caller a chance to check cancellation
.AGAIN => {}, // ptr.* != expect
@@ -5827,7 +5827,7 @@ pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect:
const linux = std.os.linux;
var ts = timestampToPosix(timeout.toNanoseconds());
const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, &ts);
- if (is_debug) switch (linux.E.init(rc)) {
+ if (is_debug) switch (linux.errno(rc)) {
.SUCCESS => {}, // notified by `wake()`
.INTR => {}, // gives caller a chance to check cancellation
.AGAIN => {}, // ptr.* != expect
@@ -5861,7 +5861,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
} else switch (native_os) {
.linux => {
const linux = std.os.linux;
- switch (linux.E.init(linux.futex_3arg(
+ switch (linux.errno(linux.futex_3arg(
&ptr.raw,
.{ .cmd = .WAKE, .private = true },
@min(max_waiters, std.math.maxInt(i32)),
lib/std/os/linux/bpf.zig
@@ -1,5 +1,5 @@
const std = @import("../../std.zig");
-const errno = linux.E.init;
+const errno = linux.errno;
const unexpectedErrno = std.posix.unexpectedErrno;
const expectEqual = std.testing.expectEqual;
const expectError = std.testing.expectError;
lib/std/os/linux/IoUring.zig
@@ -46,7 +46,7 @@ pub fn init_params(entries: u16, p: *linux.io_uring_params) !IoUring {
assert(p.resv[2] == 0);
const res = linux.io_uring_setup(entries, p);
- switch (linux.E.init(res)) {
+ switch (linux.errno(res)) {
.SUCCESS => {},
.FAULT => return error.ParamsOutsideAccessibleAddressSpace,
// The resv array contains non-zero data, p.flags contains an unsupported flag,
@@ -175,7 +175,7 @@ pub fn submit_and_wait(self: *IoUring, wait_nr: u32) !u32 {
pub fn enter(self: *IoUring, to_submit: u32, min_complete: u32, flags: u32) !u32 {
assert(self.fd >= 0);
const res = linux.io_uring_enter(self.fd, to_submit, min_complete, flags, null);
- switch (linux.E.init(res)) {
+ switch (linux.errno(res)) {
.SUCCESS => {},
// The kernel was unable to allocate memory or ran out of resources for the request.
// The application should wait for some completions and try again:
@@ -1298,7 +1298,7 @@ pub fn register_buffers(self: *IoUring, buffers: []const posix.iovec) !void {
pub fn unregister_buffers(self: *IoUring) !void {
assert(self.fd >= 0);
const res = linux.io_uring_register(self.fd, .UNREGISTER_BUFFERS, null, 0);
- switch (linux.E.init(res)) {
+ switch (linux.errno(res)) {
.SUCCESS => {},
.NXIO => return error.BuffersNotRegistered,
else => |errno| return posix.unexpectedErrno(errno),
@@ -1316,7 +1316,7 @@ pub fn get_probe(self: *IoUring) !linux.io_uring_probe {
}
fn handle_registration_result(res: usize) !void {
- switch (linux.E.init(res)) {
+ switch (linux.errno(res)) {
.SUCCESS => {},
// One or more fds in the array are invalid, or the kernel does not support sparse sets:
.BADF => return error.FileDescriptorInvalid,
@@ -1341,7 +1341,7 @@ fn handle_registration_result(res: usize) !void {
pub fn unregister_files(self: *IoUring) !void {
assert(self.fd >= 0);
const res = linux.io_uring_register(self.fd, .UNREGISTER_FILES, null, 0);
- switch (linux.E.init(res)) {
+ switch (linux.errno(res)) {
.SUCCESS => {},
.NXIO => return error.FilesNotRegistered,
else => |errno| return posix.unexpectedErrno(errno),
@@ -1771,7 +1771,7 @@ fn register_buf_ring(
.flags = flags,
});
var res = linux.io_uring_register(fd, .REGISTER_PBUF_RING, @as(*const anyopaque, @ptrCast(®)), 1);
- if (linux.E.init(res) == .INVAL and reg.flags.inc) {
+ if (linux.errno(res) == .INVAL and reg.flags.inc) {
// Retry without incremental buffer consumption.
// It is available since kernel 6.12. returns INVAL on older.
reg.flags.inc = false;
@@ -1794,7 +1794,7 @@ fn unregister_buf_ring(fd: linux.fd_t, group_id: u16) !void {
}
fn handle_register_buf_ring_result(res: usize) !void {
- switch (linux.E.init(res)) {
+ switch (linux.errno(res)) {
.SUCCESS => {},
.INVAL => return error.ArgumentsInvalid,
else => |errno| return posix.unexpectedErrno(errno),
@@ -4085,7 +4085,7 @@ inline fn skipKernelLessThan(required: std.SemanticVersion) !void {
var uts: linux.utsname = undefined;
const res = linux.uname(&uts);
- switch (linux.E.init(res)) {
+ switch (linux.errno(res)) {
.SUCCESS => {},
else => |errno| return posix.unexpectedErrno(errno),
}
lib/std/os/linux/test.zig
@@ -22,7 +22,7 @@ test "fallocate" {
try expect((try file.stat()).size == 0);
const len: i64 = 65536;
- switch (linux.E.init(linux.fallocate(file.handle, 0, 0, len))) {
+ switch (linux.errno(linux.fallocate(file.handle, 0, 0, len))) {
.SUCCESS => {},
.NOSYS => return error.SkipZigTest,
.OPNOTSUPP => return error.SkipZigTest,
@@ -42,11 +42,11 @@ test "getppid" {
test "timer" {
const epoll_fd = linux.epoll_create();
- var err: linux.E = linux.E.init(epoll_fd);
+ var err: linux.E = linux.errno(epoll_fd);
try expect(err == .SUCCESS);
const timer_fd = linux.timerfd_create(linux.TIMERFD_CLOCK.MONOTONIC, .{});
- try expect(linux.E.init(timer_fd) == .SUCCESS);
+ try expect(linux.errno(timer_fd) == .SUCCESS);
const time_interval = linux.timespec{
.sec = 0,
@@ -58,7 +58,7 @@ test "timer" {
.it_value = time_interval,
};
- err = linux.E.init(linux.timerfd_settime(@as(i32, @intCast(timer_fd)), .{}, &new_time, null));
+ err = linux.errno(linux.timerfd_settime(@as(i32, @intCast(timer_fd)), .{}, &new_time, null));
try expect(err == .SUCCESS);
var event = linux.epoll_event{
@@ -66,13 +66,13 @@ test "timer" {
.data = linux.epoll_data{ .ptr = 0 },
};
- err = linux.E.init(linux.epoll_ctl(@as(i32, @intCast(epoll_fd)), linux.EPOLL.CTL_ADD, @as(i32, @intCast(timer_fd)), &event));
+ err = linux.errno(linux.epoll_ctl(@as(i32, @intCast(epoll_fd)), linux.EPOLL.CTL_ADD, @as(i32, @intCast(timer_fd)), &event));
try expect(err == .SUCCESS);
const events_one: linux.epoll_event = undefined;
var events = [_]linux.epoll_event{events_one} ** 8;
- err = linux.E.init(linux.epoll_wait(@as(i32, @intCast(epoll_fd)), &events, 8, -1));
+ err = linux.errno(linux.epoll_wait(@as(i32, @intCast(epoll_fd)), &events, 8, -1));
try expect(err == .SUCCESS);
}
@@ -85,7 +85,7 @@ test "statx" {
defer file.close();
var statx_buf: linux.Statx = undefined;
- switch (linux.E.init(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
+ switch (linux.errno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
.SUCCESS => {},
else => unreachable,
}
@@ -93,7 +93,7 @@ test "statx" {
if (builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; // No fstatat, so the rest of the test is meaningless.
var stat_buf: linux.Stat = undefined;
- switch (linux.E.init(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) {
+ switch (linux.errno(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) {
.SUCCESS => {},
else => unreachable,
}
@@ -179,7 +179,7 @@ test "sigemptyset" {
test "sysinfo" {
var info: linux.Sysinfo = undefined;
const result: usize = linux.sysinfo(&info);
- try expect(std.os.linux.E.init(result) == .SUCCESS);
+ try expect(std.os.linux.errno(result) == .SUCCESS);
try expect(info.mem_unit > 0);
try expect(info.mem_unit <= std.heap.page_size_max);
@@ -202,17 +202,17 @@ test "futex v1" {
// No-op wait, lock value is not expected value
rc = linux.futex(&lock.raw, .{ .cmd = .WAIT, .private = true }, 2, .{ .timeout = null }, null, 0);
- try expectEqual(.AGAIN, linux.E.init(rc));
+ try expectEqual(.AGAIN, linux.errno(rc));
rc = linux.futex_4arg(&lock.raw, .{ .cmd = .WAIT, .private = true }, 2, null);
- try expectEqual(.AGAIN, linux.E.init(rc));
+ try expectEqual(.AGAIN, linux.errno(rc));
// Short-fuse wait, timeout kicks in
rc = linux.futex(&lock.raw, .{ .cmd = .WAIT, .private = true }, 1, .{ .timeout = &.{ .sec = 0, .nsec = 2 } }, null, 0);
- try expectEqual(.TIMEDOUT, linux.E.init(rc));
+ try expectEqual(.TIMEDOUT, linux.errno(rc));
rc = linux.futex_4arg(&lock.raw, .{ .cmd = .WAIT, .private = true }, 1, &.{ .sec = 0, .nsec = 2 });
- try expectEqual(.TIMEDOUT, linux.E.init(rc));
+ try expectEqual(.TIMEDOUT, linux.errno(rc));
// Wakeup (no waiters)
rc = linux.futex(&lock.raw, .{ .cmd = .WAKE, .private = true }, 2, .{ .timeout = null }, null, 0);
@@ -223,7 +223,7 @@ test "futex v1" {
// CMP_REQUEUE - val3 mismatch
rc = linux.futex(&lock.raw, .{ .cmd = .CMP_REQUEUE, .private = true }, 2, .{ .val2 = 0 }, null, 99);
- try expectEqual(.AGAIN, linux.E.init(rc));
+ try expectEqual(.AGAIN, linux.errno(rc));
// CMP_REQUEUE - requeue (but no waiters, so ... not much)
{
@@ -256,12 +256,12 @@ test "futex v1" {
{
// val1 return early
rc = linux.futex(&lock.raw, .{ .cmd = .WAIT_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0xfff);
- try expectEqual(.AGAIN, linux.E.init(rc));
+ try expectEqual(.AGAIN, linux.errno(rc));
// timeout wait
const timeout: linux.timespec = .{ .sec = 0, .nsec = 2 };
rc = linux.futex(&lock.raw, .{ .cmd = .WAIT_BITSET, .private = true }, 1, .{ .timeout = &timeout }, null, 0xfff);
- try expectEqual(.TIMEDOUT, linux.E.init(rc));
+ try expectEqual(.TIMEDOUT, linux.errno(rc));
}
// WAKE_BITSET
@@ -271,7 +271,7 @@ test "futex v1" {
// bitmask must have at least 1 bit set:
rc = linux.futex(&lock.raw, .{ .cmd = .WAKE_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0);
- try expectEqual(.INVAL, linux.E.init(rc));
+ try expectEqual(.INVAL, linux.errno(rc));
}
}
@@ -307,7 +307,7 @@ test "futex2_waitv" {
const timeout = linux.kernel_timespec{ .sec = 0, .nsec = 2 }; // absolute timeout, so this is 1970...
const rc = linux.futex2_waitv(&futexes, futexes.len, .{}, &timeout, .MONOTONIC);
- switch (linux.E.init(rc)) {
+ switch (linux.errno(rc)) {
.NOSYS => return error.SkipZigTest, // futex2_waitv added in kernel v5.16
else => |err| try expectEqual(.TIMEDOUT, err),
}
@@ -318,7 +318,7 @@ test "futex2_waitv" {
fn futex2_skip_if_unsupported() !void {
const lock: u32 = 0;
const rc = linux.futex2_wake(&lock, 0, 1, .{ .size = .U32, .private = true });
- if (linux.E.init(rc) == .NOSYS) {
+ if (linux.errno(rc) == .NOSYS) {
return error.SkipZigTest;
}
}
@@ -334,23 +334,23 @@ test "futex2_wait" {
// (at least) they're not implemented.
if (false) {
rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U8, .private = true }, null, .MONOTONIC);
- try expectEqual(.INVAL, linux.E.init(rc));
+ try expectEqual(.INVAL, linux.errno(rc));
rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U16, .private = true }, null, .MONOTONIC);
- try expectEqual(.INVAL, linux.E.init(rc));
+ try expectEqual(.INVAL, linux.errno(rc));
rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U64, .private = true }, null, .MONOTONIC);
- try expectEqual(.INVAL, linux.E.init(rc));
+ try expectEqual(.INVAL, linux.errno(rc));
}
const flags = linux.FUTEX2_FLAGS{ .size = .U32, .private = true };
// no-wait, lock state mismatch
rc = linux.futex2_wait(&lock.raw, 2, mask, flags, null, .MONOTONIC);
- try expectEqual(.AGAIN, linux.E.init(rc));
+ try expectEqual(.AGAIN, linux.errno(rc));
// hit timeout on wait
rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &.{ .sec = 0, .nsec = 2 }, .MONOTONIC);
- try expectEqual(.TIMEDOUT, linux.E.init(rc));
+ try expectEqual(.TIMEDOUT, linux.errno(rc));
// timeout is absolute
{
@@ -364,11 +364,11 @@ test "futex2_wait" {
.nsec = curr.nsec + 2,
};
rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &timeout, .MONOTONIC);
- try expectEqual(.TIMEDOUT, linux.E.init(rc));
+ try expectEqual(.TIMEDOUT, linux.errno(rc));
}
rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &.{ .sec = 0, .nsec = 2 }, .REALTIME);
- try expectEqual(.TIMEDOUT, linux.E.init(rc));
+ try expectEqual(.TIMEDOUT, linux.errno(rc));
}
test "futex2_wake" {
@@ -405,6 +405,14 @@ test "futex2_requeue" {
try expectEqual(0, rc);
}
+test "copy_file_range error" {
+ const fds = try std.posix.pipe();
+ defer std.posix.close(fds[0]);
+ defer std.posix.close(fds[1]);
+
+ try std.testing.expectError(error.InvalidArguments, linux.wrapped.copy_file_range(fds[0], null, fds[1], null, 1, 0));
+}
+
test {
_ = linux.IoUring;
}
lib/std/os/linux/tls.zig
@@ -555,7 +555,7 @@ pub fn initStatic(phdrs: []elf.Phdr) void {
}
const begin_addr = mmap_tls(area_desc.size + area_desc.alignment - 1);
- if (@call(.always_inline, linux.E.init, .{begin_addr}) != .SUCCESS) @trap();
+ if (@call(.always_inline, linux.errno, .{begin_addr}) != .SUCCESS) @trap();
const area_ptr: [*]align(page_size_min) u8 = @ptrFromInt(begin_addr);
lib/std/os/linux.zig
@@ -568,9 +568,8 @@ fn splitValue64(val: i64) [2]u32 {
}
}
-/// Get the errno from a syscall return value, or 0 for no error.
-/// The public API is exposed via the `E` namespace.
-fn errnoFromSyscall(r: usize) E {
+/// Get the errno from a syscall return value. SUCCESS means no error.
+pub fn errno(r: usize) E {
const signed_r: isize = @bitCast(r);
const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
return @enumFromInt(int);
@@ -1961,7 +1960,7 @@ pub fn sigaction(sig: SIG, noalias act: ?*const Sigaction, noalias oact: ?*Sigac
.sparc, .sparc64 => syscall5(.rt_sigaction, @intFromEnum(sig), ksa_arg, oldksa_arg, @intFromPtr(ksa.restorer), mask_size),
else => syscall4(.rt_sigaction, @intFromEnum(sig), ksa_arg, oldksa_arg, mask_size),
};
- if (E.init(result) != .SUCCESS) return result;
+ if (errno(result) != .SUCCESS) return result;
if (oact) |old| {
old.handler.handler = oldksa.handler;
@@ -2402,7 +2401,7 @@ pub fn sched_setaffinity(pid: pid_t, set: *const cpu_set_t) !void {
const size = @sizeOf(cpu_set_t);
const rc = syscall3(.sched_setaffinity, @as(usize, @bitCast(@as(isize, pid))), size, @intFromPtr(set));
- switch (E.init(rc)) {
+ switch (errno(rc)) {
.SUCCESS => return,
else => |err| return std.posix.unexpectedErrno(err),
}
@@ -3003,8 +3002,6 @@ pub const E = switch (native_arch) {
HWPOISON = 168,
DQUOT = 1133,
_,
-
- pub const init = errnoFromSyscall;
},
.sparc, .sparc64 => enum(u16) {
/// No error occurred.
@@ -3148,8 +3145,6 @@ pub const E = switch (native_arch) {
RFKILL = 134,
HWPOISON = 135,
_,
-
- pub const init = errnoFromSyscall;
},
else => enum(u16) {
/// No error occurred.
@@ -3459,8 +3454,6 @@ pub const E = switch (native_arch) {
NSRCNAMELOOP = 177,
_,
-
- pub const init = errnoFromSyscall;
},
};
@@ -9892,7 +9885,7 @@ pub const wrapped = struct {
const adjusted_len = @min(in_len, 0x7ffff000); // Prevents EOVERFLOW.
const sendfileSymbol = if (lfs64_abi) system.sendfile64 else system.sendfile;
const rc = sendfileSymbol(out_fd, in_fd, in_offset, adjusted_len);
- switch (errno(rc)) {
+ switch (system.errno(rc)) {
.SUCCESS => return @intCast(rc),
.BADF => return invalidApiUsage(), // Always a race condition.
.FAULT => return invalidApiUsage(), // Segmentation fault.
@@ -9958,7 +9951,7 @@ pub const wrapped = struct {
const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });
const sys = if (use_c) std.c else std.os.linux;
const rc = sys.copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
- switch (errno(rc)) {
+ switch (sys.errno(rc)) {
.SUCCESS => return @intCast(rc),
.BADF => return error.BadFileFlags,
.FBIG => return error.FileTooBig,
@@ -9982,12 +9975,4 @@ pub const wrapped = struct {
if (builtin.mode == .Debug) @panic("invalid API usage");
return error.Unexpected;
}
-
- fn errno(rc: anytype) E {
- if (builtin.link_libc) {
- return if (rc == -1) @enumFromInt(std.c._errno().*) else .SUCCESS;
- } else {
- return errnoFromSyscall(rc);
- }
- }
};
lib/std/os/plan9.zig
@@ -94,13 +94,15 @@ pub const E = enum(u16) {
OVERFLOW,
LOOP,
TXTBSY,
-
- pub fn init(r: usize) E {
- const signed_r: isize = @bitCast(r);
- const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
- return @enumFromInt(int);
- }
};
+
+/// Get the errno from a syscall return value. SUCCESS means no error.
+pub fn errno(r: usize) E {
+ const signed_r: isize = @bitCast(r);
+ const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
+ return @enumFromInt(int);
+}
+
// The max bytes that can be in the errstr buff
pub const ERRMAX = 128;
var errstr_buf: [ERRMAX]u8 = undefined;
lib/std/Thread/Futex.zig
@@ -269,7 +269,7 @@ const LinuxImpl = struct {
if (timeout != null) &ts else null,
);
- switch (linux.E.init(rc)) {
+ switch (linux.errno(rc)) {
.SUCCESS => {}, // notified by `wake()`
.INTR => {}, // spurious wakeup
.AGAIN => {}, // ptr.* != expect
@@ -290,7 +290,7 @@ const LinuxImpl = struct {
@min(max_waiters, std.math.maxInt(i32)),
);
- switch (linux.E.init(rc)) {
+ switch (linux.errno(rc)) {
.SUCCESS => {}, // successful wake up
.INVAL => {}, // invalid futex_wait() on ptr done elsewhere
.FAULT => {}, // pointer became invalid while doing the wake
lib/std/c.zig
@@ -72,6 +72,11 @@ pub inline fn versionCheck(comptime version: std.SemanticVersion) bool {
};
}
+/// Get the errno if rc is -1 and SUCCESS if rc is not -1.
+pub fn errno(rc: anytype) E {
+ return if (rc == -1) @enumFromInt(_errno().*) else .SUCCESS;
+}
+
pub const ino_t = switch (native_os) {
.linux => linux.ino_t,
.emscripten => emscripten.ino_t,
@@ -11580,6 +11585,6 @@ const private = struct {
extern threadlocal var errno: c_int;
fn errnoFromThreadLocal() *c_int {
- return &errno;
+ return &private.errno;
}
};
lib/std/posix.zig
@@ -272,14 +272,7 @@ pub const socket_t = if (native_os == .windows) windows.ws2_32.SOCKET else fd_t;
/// for others it will use a thread-local errno variable. Therefore, this
/// function only returns a well-defined value when it is called directly after
/// the system function call whose errno value is intended to be observed.
-pub fn errno(rc: anytype) E {
- if (use_libc) {
- return if (rc == -1) @enumFromInt(std.c._errno().*) else .SUCCESS;
- }
- const signed: isize = @bitCast(rc);
- const int = if (signed > -4096 and signed < 0) -signed else 0;
- return @enumFromInt(int);
-}
+pub const errno = system.errno;
/// Closes the file descriptor.
///
@@ -433,7 +426,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
// Later on this should be changed to `system.fchmodat2`
// when the musl/glibc add a wrapper.
const res = linux.fchmodat2(dirfd, &path_c, mode, flags);
- switch (E.init(res)) {
+ switch (linux.errno(res)) {
.SUCCESS => return,
.INTR => continue,
.BADF => unreachable,
@@ -588,7 +581,7 @@ pub const RebootCommand = switch (native_os) {
pub fn reboot(cmd: RebootCommand) RebootError!void {
switch (native_os) {
.linux => {
- switch (linux.E.init(linux.reboot(
+ switch (linux.errno(linux.reboot(
.MAGIC1,
.MAGIC2,
cmd,
@@ -647,7 +640,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
break :res .{ @bitCast(rc), errno(rc) };
} else res: {
const rc = linux.getrandom(buf.ptr, buf.len, 0);
- break :res .{ rc, linux.E.init(rc) };
+ break :res .{ rc, linux.errno(rc) };
};
switch (err) {
@@ -3298,7 +3291,7 @@ pub fn isatty(handle: fd_t) bool {
var wsz: winsize = undefined;
const fd: usize = @bitCast(@as(isize, handle));
const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz));
- switch (linux.E.init(rc)) {
+ switch (linux.errno(rc)) {
.SUCCESS => return true,
.INTR => continue,
else => return false,
@@ -5762,7 +5755,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
while (true) {
const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);
if (native_os == .freebsd) {
- switch (errno(rc)) {
+ switch (sys.errno(rc)) {
.SUCCESS => return @intCast(rc),
.BADF => return error.FilesOpenedWithWrongFlags,
.FBIG => return error.FileTooBig,
@@ -5775,7 +5768,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
else => |err| return unexpectedErrno(err),
}
} else { // assume linux
- switch (errno(rc)) {
+ switch (sys.errno(rc)) {
.SUCCESS => return @intCast(rc),
.BADF => return error.FilesOpenedWithWrongFlags,
.FBIG => return error.FileTooBig,
@@ -6070,7 +6063,7 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 30, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });
const sys = if (use_c) std.c else linux;
const rc = sys.memfd_create(name, flags);
- switch (errno(rc)) {
+ switch (sys.errno(rc)) {
.SUCCESS => return @intCast(rc),
.FAULT => unreachable, // name has invalid memory
.INVAL => return error.NameTooLong, // or, program has a bug and flags are faulty
@@ -6494,7 +6487,7 @@ pub fn perf_event_open(
if (native_os == .linux) {
// There is no syscall wrapper for this function exposed by libcs
const rc = linux.perf_event_open(attr, pid, cpu, group_fd, flags);
- switch (errno(rc)) {
+ switch (linux.errno(rc)) {
.SUCCESS => return @intCast(rc),
.@"2BIG" => return error.TooBig,
.ACCES => return error.PermissionDenied,
lib/std/process.zig
@@ -1772,7 +1772,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
.linux => {
var info: std.os.linux.Sysinfo = undefined;
const result: usize = std.os.linux.sysinfo(&info);
- if (std.os.linux.E.init(result) != .SUCCESS) {
+ if (std.os.linux.errno(result) != .SUCCESS) {
return error.UnknownTotalSystemMemory;
}
// Promote to u64 to avoid overflow on systems where info.totalram is a 32-bit usize
lib/std/Thread.zig
@@ -1622,7 +1622,7 @@ const LinuxThreadImpl = struct {
linux.CLONE.PARENT_SETTID | linux.CLONE.CHILD_CLEARTID |
linux.CLONE.SIGHAND | linux.CLONE.SYSVSEM | linux.CLONE.SETTLS;
- switch (linux.E.init(linux.clone(
+ switch (linux.errno(linux.clone(
Instance.entryFn,
@intFromPtr(&mapped[stack_offset]),
flags,
@@ -1661,7 +1661,7 @@ const LinuxThreadImpl = struct {
const tid = self.thread.child_tid.load(.seq_cst);
if (tid == 0) break;
- switch (linux.E.init(linux.futex_4arg(
+ switch (linux.errno(linux.futex_4arg(
&self.thread.child_tid.raw,
.{ .cmd = .WAIT, .private = false },
@bitCast(tid),
src/link/Elf/ZigObject.zig
@@ -1437,7 +1437,7 @@ fn updateNavCode(
.len = code.len,
}};
const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0);
- switch (std.os.linux.E.init(rc)) {
+ switch (std.os.linux.errno(rc)) {
.SUCCESS => assert(rc == code.len),
else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
}
@@ -2026,7 +2026,7 @@ fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void {
.len = out.len,
}};
const rc = std.os.linux.process_vm_writev(pid, &local_vec, &remote_vec, 0);
- switch (std.os.linux.E.init(rc)) {
+ switch (std.os.linux.errno(rc)) {
.SUCCESS => assert(rc == out.len),
else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
}
src/link/MappedFile.zig
@@ -645,7 +645,7 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested
@intCast(requested_size +| requested_size / growth_factor),
) - old_size;
_, const file_size = Node.Index.root.location(mf).resolve(mf);
- while (true) switch (linux.E.init(switch (std.math.order(range_file_offset, file_size)) {
+ while (true) switch (linux.errno(switch (std.math.order(range_file_offset, file_size)) {
.lt => linux.fallocate(
mf.file.handle,
linux.FALLOC.FL_INSERT_RANGE,
@@ -858,7 +858,7 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size:
// delete the copy of this node at the old location
if (is_linux and !mf.flags.fallocate_punch_hole_unsupported and
size >= mf.flags.block_size.toByteUnits() * 2 - 1) while (true)
- switch (linux.E.init(linux.fallocate(
+ switch (linux.errno(linux.fallocate(
mf.file.handle,
linux.FALLOC.FL_PUNCH_HOLE | linux.FALLOC.FL_KEEP_SIZE,
@intCast(old_file_offset),
@@ -910,7 +910,7 @@ fn copyFileRange(
@intCast(remaining_size),
0,
);
- switch (linux.E.init(copy_len)) {
+ switch (linux.errno(copy_len)) {
.SUCCESS => {
if (copy_len == 0) break;
remaining_size -= copy_len;