authorgravatar for rpkak@noreply.codeberg.orgrpkak <rpkak@noreply.codeberg.org> 2025-11-14 23:16:55+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-11-20 15:03:23-08:00
log6b4f45f782fb9c8906d3fcbfca9e21fc3771c2dd
treeee11cca9b35e72958e2dc66576b4cb8e4a82d6f5
parent4b5351bc0ddc248d6935d7d160a57cb4dfe4dedd

system specific errno


15 files changed, 91 insertions(+), 98 deletions(-)

lib/std/Io/Threaded.zig+7-7
...@@ -1302,7 +1302,7 @@ fn dirStatPathLinux(...@@ -1302,7 +1302,7 @@ fn dirStatPathLinux(
1302 linux.STATX_INO | linux.STATX_SIZE | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,1302 linux.STATX_INO | linux.STATX_SIZE | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
1303 &statx,1303 &statx,
1304 );1304 );
1305 switch (linux.E.init(rc)) {1305 switch (linux.errno(rc)) {
1306 .SUCCESS => return statFromLinux(&statx),1306 .SUCCESS => return statFromLinux(&statx),
1307 .INTR => continue,1307 .INTR => continue,
1308 .CANCELED => return error.Canceled,1308 .CANCELED => return error.Canceled,
...@@ -1449,7 +1449,7 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File...@@ -1449,7 +1449,7 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
1449 linux.STATX_INO | linux.STATX_SIZE | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,1449 linux.STATX_INO | linux.STATX_SIZE | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
1450 &statx,1450 &statx,
1451 );1451 );
1452 switch (linux.E.init(rc)) {1452 switch (linux.errno(rc)) {
1453 .SUCCESS => return statFromLinux(&statx),1453 .SUCCESS => return statFromLinux(&statx),
1454 .INTR => continue,1454 .INTR => continue,
1455 .CANCELED => return error.Canceled,1455 .CANCELED => return error.Canceled,
...@@ -2931,7 +2931,7 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -2931,7 +2931,7 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
2931 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);2931 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);
2932 while (true) {2932 while (true) {
2933 try t.checkCancel();2933 try t.checkCancel();
2934 switch (std.os.linux.E.init(std.os.linux.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {2934 switch (std.os.linux.errno(std.os.linux.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {
2935 .none, .duration => false,2935 .none, .duration => false,
2936 .deadline => true,2936 .deadline => true,
2937 } }, &timespec, &timespec))) {2937 } }, &timespec, &timespec))) {
...@@ -5677,7 +5677,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca...@@ -5677,7 +5677,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca
5677 const linux = std.os.linux;5677 const linux = std.os.linux;
5678 try t.checkCancel();5678 try t.checkCancel();
5679 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);5679 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);
5680 if (is_debug) switch (linux.E.init(rc)) {5680 if (is_debug) switch (linux.errno(rc)) {
5681 .SUCCESS => {}, // notified by `wake()`5681 .SUCCESS => {}, // notified by `wake()`
5682 .INTR => {}, // gives caller a chance to check cancellation5682 .INTR => {}, // gives caller a chance to check cancellation
5683 .AGAIN => {}, // ptr.* != expect5683 .AGAIN => {}, // ptr.* != expect
...@@ -5764,7 +5764,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi...@@ -5764,7 +5764,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
5764 .linux => {5764 .linux => {
5765 const linux = std.os.linux;5765 const linux = std.os.linux;
5766 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);5766 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);
5767 switch (linux.E.init(rc)) {5767 switch (linux.errno(rc)) {
5768 .SUCCESS => {}, // notified by `wake()`5768 .SUCCESS => {}, // notified by `wake()`
5769 .INTR => {}, // gives caller a chance to check cancellation5769 .INTR => {}, // gives caller a chance to check cancellation
5770 .AGAIN => {}, // ptr.* != expect5770 .AGAIN => {}, // ptr.* != expect
...@@ -5827,7 +5827,7 @@ pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect:...@@ -5827,7 +5827,7 @@ pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect:
5827 const linux = std.os.linux;5827 const linux = std.os.linux;
5828 var ts = timestampToPosix(timeout.toNanoseconds());5828 var ts = timestampToPosix(timeout.toNanoseconds());
5829 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, &ts);5829 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, &ts);
5830 if (is_debug) switch (linux.E.init(rc)) {5830 if (is_debug) switch (linux.errno(rc)) {
5831 .SUCCESS => {}, // notified by `wake()`5831 .SUCCESS => {}, // notified by `wake()`
5832 .INTR => {}, // gives caller a chance to check cancellation5832 .INTR => {}, // gives caller a chance to check cancellation
5833 .AGAIN => {}, // ptr.* != expect5833 .AGAIN => {}, // ptr.* != expect
...@@ -5861,7 +5861,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {...@@ -5861,7 +5861,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
5861 } else switch (native_os) {5861 } else switch (native_os) {
5862 .linux => {5862 .linux => {
5863 const linux = std.os.linux;5863 const linux = std.os.linux;
5864 switch (linux.E.init(linux.futex_3arg(5864 switch (linux.errno(linux.futex_3arg(
5865 &ptr.raw,5865 &ptr.raw,
5866 .{ .cmd = .WAKE, .private = true },5866 .{ .cmd = .WAKE, .private = true },
5867 @min(max_waiters, std.math.maxInt(i32)),5867 @min(max_waiters, std.math.maxInt(i32)),
lib/std/Thread.zig+2-2
...@@ -1622,7 +1622,7 @@ const LinuxThreadImpl = struct {...@@ -1622,7 +1622,7 @@ const LinuxThreadImpl = struct {
1622 linux.CLONE.PARENT_SETTID | linux.CLONE.CHILD_CLEARTID |1622 linux.CLONE.PARENT_SETTID | linux.CLONE.CHILD_CLEARTID |
1623 linux.CLONE.SIGHAND | linux.CLONE.SYSVSEM | linux.CLONE.SETTLS;1623 linux.CLONE.SIGHAND | linux.CLONE.SYSVSEM | linux.CLONE.SETTLS;
16241624
1625 switch (linux.E.init(linux.clone(1625 switch (linux.errno(linux.clone(
1626 Instance.entryFn,1626 Instance.entryFn,
1627 @intFromPtr(&mapped[stack_offset]),1627 @intFromPtr(&mapped[stack_offset]),
1628 flags,1628 flags,
...@@ -1661,7 +1661,7 @@ const LinuxThreadImpl = struct {...@@ -1661,7 +1661,7 @@ const LinuxThreadImpl = struct {
1661 const tid = self.thread.child_tid.load(.seq_cst);1661 const tid = self.thread.child_tid.load(.seq_cst);
1662 if (tid == 0) break;1662 if (tid == 0) break;
16631663
1664 switch (linux.E.init(linux.futex_4arg(1664 switch (linux.errno(linux.futex_4arg(
1665 &self.thread.child_tid.raw,1665 &self.thread.child_tid.raw,
1666 .{ .cmd = .WAIT, .private = false },1666 .{ .cmd = .WAIT, .private = false },
1667 @bitCast(tid),1667 @bitCast(tid),
lib/std/Thread/Futex.zig+2-2
...@@ -269,7 +269,7 @@ const LinuxImpl = struct {...@@ -269,7 +269,7 @@ const LinuxImpl = struct {
269 if (timeout != null) &ts else null,269 if (timeout != null) &ts else null,
270 );270 );
271271
272 switch (linux.E.init(rc)) {272 switch (linux.errno(rc)) {
273 .SUCCESS => {}, // notified by `wake()`273 .SUCCESS => {}, // notified by `wake()`
274 .INTR => {}, // spurious wakeup274 .INTR => {}, // spurious wakeup
275 .AGAIN => {}, // ptr.* != expect275 .AGAIN => {}, // ptr.* != expect
...@@ -290,7 +290,7 @@ const LinuxImpl = struct {...@@ -290,7 +290,7 @@ const LinuxImpl = struct {
290 @min(max_waiters, std.math.maxInt(i32)),290 @min(max_waiters, std.math.maxInt(i32)),
291 );291 );
292292
293 switch (linux.E.init(rc)) {293 switch (linux.errno(rc)) {
294 .SUCCESS => {}, // successful wake up294 .SUCCESS => {}, // successful wake up
295 .INVAL => {}, // invalid futex_wait() on ptr done elsewhere295 .INVAL => {}, // invalid futex_wait() on ptr done elsewhere
296 .FAULT => {}, // pointer became invalid while doing the wake296 .FAULT => {}, // pointer became invalid while doing the wake
lib/std/c.zig+6-1
...@@ -72,6 +72,11 @@ pub inline fn versionCheck(comptime version: std.SemanticVersion) bool {...@@ -72,6 +72,11 @@ pub inline fn versionCheck(comptime version: std.SemanticVersion) bool {
72 };72 };
73}73}
7474
75/// Get the errno if rc is -1 and SUCCESS if rc is not -1.
76pub fn errno(rc: anytype) E {
77 return if (rc == -1) @enumFromInt(_errno().*) else .SUCCESS;
78}
79
75pub const ino_t = switch (native_os) {80pub const ino_t = switch (native_os) {
76 .linux => linux.ino_t,81 .linux => linux.ino_t,
77 .emscripten => emscripten.ino_t,82 .emscripten => emscripten.ino_t,
...@@ -11580,6 +11585,6 @@ const private = struct {...@@ -11580,6 +11585,6 @@ const private = struct {
11580 extern threadlocal var errno: c_int;11585 extern threadlocal var errno: c_int;
1158111586
11582 fn errnoFromThreadLocal() *c_int {11587 fn errnoFromThreadLocal() *c_int {
11583 return &errno;11588 return &private.errno;
11584 }11589 }
11585};11590};
lib/std/fs/Dir.zig+1-1
...@@ -378,7 +378,7 @@ pub const Iterator = switch (native_os) {...@@ -378,7 +378,7 @@ pub const Iterator = switch (native_os) {
378 self.first_iter = false;378 self.first_iter = false;
379 }379 }
380 const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len);380 const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len);
381 switch (linux.E.init(rc)) {381 switch (linux.errno(rc)) {
382 .SUCCESS => {},382 .SUCCESS => {},
383 .BADF => unreachable, // Dir is invalid or was opened without iteration ability383 .BADF => unreachable, // Dir is invalid or was opened without iteration ability
384 .FAULT => unreachable,384 .FAULT => unreachable,
lib/std/os/linux.zig+6-21
...@@ -568,9 +568,8 @@ fn splitValue64(val: i64) [2]u32 {...@@ -568,9 +568,8 @@ fn splitValue64(val: i64) [2]u32 {
568 }568 }
569}569}
570570
571/// Get the errno from a syscall return value, or 0 for no error.571/// Get the errno from a syscall return value. SUCCESS means no error.
572/// The public API is exposed via the `E` namespace.572pub fn errno(r: usize) E {
573fn errnoFromSyscall(r: usize) E {
574 const signed_r: isize = @bitCast(r);573 const signed_r: isize = @bitCast(r);
575 const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;574 const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
576 return @enumFromInt(int);575 return @enumFromInt(int);
...@@ -1961,7 +1960,7 @@ pub fn sigaction(sig: SIG, noalias act: ?*const Sigaction, noalias oact: ?*Sigac...@@ -1961,7 +1960,7 @@ pub fn sigaction(sig: SIG, noalias act: ?*const Sigaction, noalias oact: ?*Sigac
1961 .sparc, .sparc64 => syscall5(.rt_sigaction, @intFromEnum(sig), ksa_arg, oldksa_arg, @intFromPtr(ksa.restorer), mask_size),1960 .sparc, .sparc64 => syscall5(.rt_sigaction, @intFromEnum(sig), ksa_arg, oldksa_arg, @intFromPtr(ksa.restorer), mask_size),
1962 else => syscall4(.rt_sigaction, @intFromEnum(sig), ksa_arg, oldksa_arg, mask_size),1961 else => syscall4(.rt_sigaction, @intFromEnum(sig), ksa_arg, oldksa_arg, mask_size),
1963 };1962 };
1964 if (E.init(result) != .SUCCESS) return result;1963 if (errno(result) != .SUCCESS) return result;
19651964
1966 if (oact) |old| {1965 if (oact) |old| {
1967 old.handler.handler = oldksa.handler;1966 old.handler.handler = oldksa.handler;
...@@ -2402,7 +2401,7 @@ pub fn sched_setaffinity(pid: pid_t, set: *const cpu_set_t) !void {...@@ -2402,7 +2401,7 @@ pub fn sched_setaffinity(pid: pid_t, set: *const cpu_set_t) !void {
2402 const size = @sizeOf(cpu_set_t);2401 const size = @sizeOf(cpu_set_t);
2403 const rc = syscall3(.sched_setaffinity, @as(usize, @bitCast(@as(isize, pid))), size, @intFromPtr(set));2402 const rc = syscall3(.sched_setaffinity, @as(usize, @bitCast(@as(isize, pid))), size, @intFromPtr(set));
24042403
2405 switch (E.init(rc)) {2404 switch (errno(rc)) {
2406 .SUCCESS => return,2405 .SUCCESS => return,
2407 else => |err| return std.posix.unexpectedErrno(err),2406 else => |err| return std.posix.unexpectedErrno(err),
2408 }2407 }
...@@ -3003,8 +3002,6 @@ pub const E = switch (native_arch) {...@@ -3003,8 +3002,6 @@ pub const E = switch (native_arch) {
3003 HWPOISON = 168,3002 HWPOISON = 168,
3004 DQUOT = 1133,3003 DQUOT = 1133,
3005 _,3004 _,
3006
3007 pub const init = errnoFromSyscall;
3008 },3005 },
3009 .sparc, .sparc64 => enum(u16) {3006 .sparc, .sparc64 => enum(u16) {
3010 /// No error occurred.3007 /// No error occurred.
...@@ -3148,8 +3145,6 @@ pub const E = switch (native_arch) {...@@ -3148,8 +3145,6 @@ pub const E = switch (native_arch) {
3148 RFKILL = 134,3145 RFKILL = 134,
3149 HWPOISON = 135,3146 HWPOISON = 135,
3150 _,3147 _,
3151
3152 pub const init = errnoFromSyscall;
3153 },3148 },
3154 else => enum(u16) {3149 else => enum(u16) {
3155 /// No error occurred.3150 /// No error occurred.
...@@ -3459,8 +3454,6 @@ pub const E = switch (native_arch) {...@@ -3459,8 +3454,6 @@ pub const E = switch (native_arch) {
3459 NSRCNAMELOOP = 177,3454 NSRCNAMELOOP = 177,
34603455
3461 _,3456 _,
3462
3463 pub const init = errnoFromSyscall;
3464 },3457 },
3465};3458};
34663459
...@@ -9892,7 +9885,7 @@ pub const wrapped = struct {...@@ -9892,7 +9885,7 @@ pub const wrapped = struct {
9892 const adjusted_len = @min(in_len, 0x7ffff000); // Prevents EOVERFLOW.9885 const adjusted_len = @min(in_len, 0x7ffff000); // Prevents EOVERFLOW.
9893 const sendfileSymbol = if (lfs64_abi) system.sendfile64 else system.sendfile;9886 const sendfileSymbol = if (lfs64_abi) system.sendfile64 else system.sendfile;
9894 const rc = sendfileSymbol(out_fd, in_fd, in_offset, adjusted_len);9887 const rc = sendfileSymbol(out_fd, in_fd, in_offset, adjusted_len);
9895 switch (errno(rc)) {9888 switch (system.errno(rc)) {
9896 .SUCCESS => return @intCast(rc),9889 .SUCCESS => return @intCast(rc),
9897 .BADF => return invalidApiUsage(), // Always a race condition.9890 .BADF => return invalidApiUsage(), // Always a race condition.
9898 .FAULT => return invalidApiUsage(), // Segmentation fault.9891 .FAULT => return invalidApiUsage(), // Segmentation fault.
...@@ -9958,7 +9951,7 @@ pub const wrapped = struct {...@@ -9958,7 +9951,7 @@ pub const wrapped = struct {
9958 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });9951 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });
9959 const sys = if (use_c) std.c else std.os.linux;9952 const sys = if (use_c) std.c else std.os.linux;
9960 const rc = sys.copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);9953 const rc = sys.copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
9961 switch (errno(rc)) {9954 switch (sys.errno(rc)) {
9962 .SUCCESS => return @intCast(rc),9955 .SUCCESS => return @intCast(rc),
9963 .BADF => return error.BadFileFlags,9956 .BADF => return error.BadFileFlags,
9964 .FBIG => return error.FileTooBig,9957 .FBIG => return error.FileTooBig,
...@@ -9982,12 +9975,4 @@ pub const wrapped = struct {...@@ -9982,12 +9975,4 @@ pub const wrapped = struct {
9982 if (builtin.mode == .Debug) @panic("invalid API usage");9975 if (builtin.mode == .Debug) @panic("invalid API usage");
9983 return error.Unexpected;9976 return error.Unexpected;
9984 }9977 }
9985
9986 fn errno(rc: anytype) E {
9987 if (builtin.link_libc) {
9988 return if (rc == -1) @enumFromInt(std.c._errno().*) else .SUCCESS;
9989 } else {
9990 return errnoFromSyscall(rc);
9991 }
9992 }
9993};9978};
lib/std/os/linux/IoUring.zig+8-8
...@@ -46,7 +46,7 @@ pub fn init_params(entries: u16, p: *linux.io_uring_params) !IoUring {...@@ -46,7 +46,7 @@ pub fn init_params(entries: u16, p: *linux.io_uring_params) !IoUring {
46 assert(p.resv[2] == 0);46 assert(p.resv[2] == 0);
4747
48 const res = linux.io_uring_setup(entries, p);48 const res = linux.io_uring_setup(entries, p);
49 switch (linux.E.init(res)) {49 switch (linux.errno(res)) {
50 .SUCCESS => {},50 .SUCCESS => {},
51 .FAULT => return error.ParamsOutsideAccessibleAddressSpace,51 .FAULT => return error.ParamsOutsideAccessibleAddressSpace,
52 // The resv array contains non-zero data, p.flags contains an unsupported flag,52 // 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 {...@@ -175,7 +175,7 @@ pub fn submit_and_wait(self: *IoUring, wait_nr: u32) !u32 {
175pub fn enter(self: *IoUring, to_submit: u32, min_complete: u32, flags: u32) !u32 {175pub fn enter(self: *IoUring, to_submit: u32, min_complete: u32, flags: u32) !u32 {
176 assert(self.fd >= 0);176 assert(self.fd >= 0);
177 const res = linux.io_uring_enter(self.fd, to_submit, min_complete, flags, null);177 const res = linux.io_uring_enter(self.fd, to_submit, min_complete, flags, null);
178 switch (linux.E.init(res)) {178 switch (linux.errno(res)) {
179 .SUCCESS => {},179 .SUCCESS => {},
180 // The kernel was unable to allocate memory or ran out of resources for the request.180 // The kernel was unable to allocate memory or ran out of resources for the request.
181 // The application should wait for some completions and try again:181 // 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 {...@@ -1298,7 +1298,7 @@ pub fn register_buffers(self: *IoUring, buffers: []const posix.iovec) !void {
1298pub fn unregister_buffers(self: *IoUring) !void {1298pub fn unregister_buffers(self: *IoUring) !void {
1299 assert(self.fd >= 0);1299 assert(self.fd >= 0);
1300 const res = linux.io_uring_register(self.fd, .UNREGISTER_BUFFERS, null, 0);1300 const res = linux.io_uring_register(self.fd, .UNREGISTER_BUFFERS, null, 0);
1301 switch (linux.E.init(res)) {1301 switch (linux.errno(res)) {
1302 .SUCCESS => {},1302 .SUCCESS => {},
1303 .NXIO => return error.BuffersNotRegistered,1303 .NXIO => return error.BuffersNotRegistered,
1304 else => |errno| return posix.unexpectedErrno(errno),1304 else => |errno| return posix.unexpectedErrno(errno),
...@@ -1316,7 +1316,7 @@ pub fn get_probe(self: *IoUring) !linux.io_uring_probe {...@@ -1316,7 +1316,7 @@ pub fn get_probe(self: *IoUring) !linux.io_uring_probe {
1316}1316}
13171317
1318fn handle_registration_result(res: usize) !void {1318fn handle_registration_result(res: usize) !void {
1319 switch (linux.E.init(res)) {1319 switch (linux.errno(res)) {
1320 .SUCCESS => {},1320 .SUCCESS => {},
1321 // One or more fds in the array are invalid, or the kernel does not support sparse sets:1321 // One or more fds in the array are invalid, or the kernel does not support sparse sets:
1322 .BADF => return error.FileDescriptorInvalid,1322 .BADF => return error.FileDescriptorInvalid,
...@@ -1341,7 +1341,7 @@ fn handle_registration_result(res: usize) !void {...@@ -1341,7 +1341,7 @@ fn handle_registration_result(res: usize) !void {
1341pub fn unregister_files(self: *IoUring) !void {1341pub fn unregister_files(self: *IoUring) !void {
1342 assert(self.fd >= 0);1342 assert(self.fd >= 0);
1343 const res = linux.io_uring_register(self.fd, .UNREGISTER_FILES, null, 0);1343 const res = linux.io_uring_register(self.fd, .UNREGISTER_FILES, null, 0);
1344 switch (linux.E.init(res)) {1344 switch (linux.errno(res)) {
1345 .SUCCESS => {},1345 .SUCCESS => {},
1346 .NXIO => return error.FilesNotRegistered,1346 .NXIO => return error.FilesNotRegistered,
1347 else => |errno| return posix.unexpectedErrno(errno),1347 else => |errno| return posix.unexpectedErrno(errno),
...@@ -1771,7 +1771,7 @@ fn register_buf_ring(...@@ -1771,7 +1771,7 @@ fn register_buf_ring(
1771 .flags = flags,1771 .flags = flags,
1772 });1772 });
1773 var res = linux.io_uring_register(fd, .REGISTER_PBUF_RING, @as(*const anyopaque, @ptrCast(&reg)), 1);1773 var res = linux.io_uring_register(fd, .REGISTER_PBUF_RING, @as(*const anyopaque, @ptrCast(&reg)), 1);
1774 if (linux.E.init(res) == .INVAL and reg.flags.inc) {1774 if (linux.errno(res) == .INVAL and reg.flags.inc) {
1775 // Retry without incremental buffer consumption.1775 // Retry without incremental buffer consumption.
1776 // It is available since kernel 6.12. returns INVAL on older.1776 // It is available since kernel 6.12. returns INVAL on older.
1777 reg.flags.inc = false;1777 reg.flags.inc = false;
...@@ -1794,7 +1794,7 @@ fn unregister_buf_ring(fd: linux.fd_t, group_id: u16) !void {...@@ -1794,7 +1794,7 @@ fn unregister_buf_ring(fd: linux.fd_t, group_id: u16) !void {
1794}1794}
17951795
1796fn handle_register_buf_ring_result(res: usize) !void {1796fn handle_register_buf_ring_result(res: usize) !void {
1797 switch (linux.E.init(res)) {1797 switch (linux.errno(res)) {
1798 .SUCCESS => {},1798 .SUCCESS => {},
1799 .INVAL => return error.ArgumentsInvalid,1799 .INVAL => return error.ArgumentsInvalid,
1800 else => |errno| return posix.unexpectedErrno(errno),1800 else => |errno| return posix.unexpectedErrno(errno),
...@@ -4085,7 +4085,7 @@ inline fn skipKernelLessThan(required: std.SemanticVersion) !void {...@@ -4085,7 +4085,7 @@ inline fn skipKernelLessThan(required: std.SemanticVersion) !void {
40854085
4086 var uts: linux.utsname = undefined;4086 var uts: linux.utsname = undefined;
4087 const res = linux.uname(&uts);4087 const res = linux.uname(&uts);
4088 switch (linux.E.init(res)) {4088 switch (linux.errno(res)) {
4089 .SUCCESS => {},4089 .SUCCESS => {},
4090 else => |errno| return posix.unexpectedErrno(errno),4090 else => |errno| return posix.unexpectedErrno(errno),
4091 }4091 }
lib/std/os/linux/bpf.zig+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1const std = @import("../../std.zig");1const std = @import("../../std.zig");
2const errno = linux.E.init;2const errno = linux.errno;
3const unexpectedErrno = std.posix.unexpectedErrno;3const unexpectedErrno = std.posix.unexpectedErrno;
4const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
5const expectError = std.testing.expectError;5const expectError = std.testing.expectError;
lib/std/os/linux/test.zig+34-26
...@@ -22,7 +22,7 @@ test "fallocate" {...@@ -22,7 +22,7 @@ test "fallocate" {
22 try expect((try file.stat()).size == 0);22 try expect((try file.stat()).size == 0);
2323
24 const len: i64 = 65536;24 const len: i64 = 65536;
25 switch (linux.E.init(linux.fallocate(file.handle, 0, 0, len))) {25 switch (linux.errno(linux.fallocate(file.handle, 0, 0, len))) {
26 .SUCCESS => {},26 .SUCCESS => {},
27 .NOSYS => return error.SkipZigTest,27 .NOSYS => return error.SkipZigTest,
28 .OPNOTSUPP => return error.SkipZigTest,28 .OPNOTSUPP => return error.SkipZigTest,
...@@ -42,11 +42,11 @@ test "getppid" {...@@ -42,11 +42,11 @@ test "getppid" {
4242
43test "timer" {43test "timer" {
44 const epoll_fd = linux.epoll_create();44 const epoll_fd = linux.epoll_create();
45 var err: linux.E = linux.E.init(epoll_fd);45 var err: linux.E = linux.errno(epoll_fd);
46 try expect(err == .SUCCESS);46 try expect(err == .SUCCESS);
4747
48 const timer_fd = linux.timerfd_create(linux.TIMERFD_CLOCK.MONOTONIC, .{});48 const timer_fd = linux.timerfd_create(linux.TIMERFD_CLOCK.MONOTONIC, .{});
49 try expect(linux.E.init(timer_fd) == .SUCCESS);49 try expect(linux.errno(timer_fd) == .SUCCESS);
5050
51 const time_interval = linux.timespec{51 const time_interval = linux.timespec{
52 .sec = 0,52 .sec = 0,
...@@ -58,7 +58,7 @@ test "timer" {...@@ -58,7 +58,7 @@ test "timer" {
58 .it_value = time_interval,58 .it_value = time_interval,
59 };59 };
6060
61 err = linux.E.init(linux.timerfd_settime(@as(i32, @intCast(timer_fd)), .{}, &new_time, null));61 err = linux.errno(linux.timerfd_settime(@as(i32, @intCast(timer_fd)), .{}, &new_time, null));
62 try expect(err == .SUCCESS);62 try expect(err == .SUCCESS);
6363
64 var event = linux.epoll_event{64 var event = linux.epoll_event{
...@@ -66,13 +66,13 @@ test "timer" {...@@ -66,13 +66,13 @@ test "timer" {
66 .data = linux.epoll_data{ .ptr = 0 },66 .data = linux.epoll_data{ .ptr = 0 },
67 };67 };
6868
69 err = linux.E.init(linux.epoll_ctl(@as(i32, @intCast(epoll_fd)), linux.EPOLL.CTL_ADD, @as(i32, @intCast(timer_fd)), &event));69 err = linux.errno(linux.epoll_ctl(@as(i32, @intCast(epoll_fd)), linux.EPOLL.CTL_ADD, @as(i32, @intCast(timer_fd)), &event));
70 try expect(err == .SUCCESS);70 try expect(err == .SUCCESS);
7171
72 const events_one: linux.epoll_event = undefined;72 const events_one: linux.epoll_event = undefined;
73 var events = [_]linux.epoll_event{events_one} ** 8;73 var events = [_]linux.epoll_event{events_one} ** 8;
7474
75 err = linux.E.init(linux.epoll_wait(@as(i32, @intCast(epoll_fd)), &events, 8, -1));75 err = linux.errno(linux.epoll_wait(@as(i32, @intCast(epoll_fd)), &events, 8, -1));
76 try expect(err == .SUCCESS);76 try expect(err == .SUCCESS);
77}77}
7878
...@@ -85,7 +85,7 @@ test "statx" {...@@ -85,7 +85,7 @@ test "statx" {
85 defer file.close();85 defer file.close();
8686
87 var statx_buf: linux.Statx = undefined;87 var statx_buf: linux.Statx = undefined;
88 switch (linux.E.init(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {88 switch (linux.errno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
89 .SUCCESS => {},89 .SUCCESS => {},
90 else => unreachable,90 else => unreachable,
91 }91 }
...@@ -93,7 +93,7 @@ test "statx" {...@@ -93,7 +93,7 @@ test "statx" {
93 if (builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; // No fstatat, so the rest of the test is meaningless.93 if (builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; // No fstatat, so the rest of the test is meaningless.
9494
95 var stat_buf: linux.Stat = undefined;95 var stat_buf: linux.Stat = undefined;
96 switch (linux.E.init(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) {96 switch (linux.errno(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) {
97 .SUCCESS => {},97 .SUCCESS => {},
98 else => unreachable,98 else => unreachable,
99 }99 }
...@@ -179,7 +179,7 @@ test "sigemptyset" {...@@ -179,7 +179,7 @@ test "sigemptyset" {
179test "sysinfo" {179test "sysinfo" {
180 var info: linux.Sysinfo = undefined;180 var info: linux.Sysinfo = undefined;
181 const result: usize = linux.sysinfo(&info);181 const result: usize = linux.sysinfo(&info);
182 try expect(std.os.linux.E.init(result) == .SUCCESS);182 try expect(std.os.linux.errno(result) == .SUCCESS);
183183
184 try expect(info.mem_unit > 0);184 try expect(info.mem_unit > 0);
185 try expect(info.mem_unit <= std.heap.page_size_max);185 try expect(info.mem_unit <= std.heap.page_size_max);
...@@ -202,17 +202,17 @@ test "futex v1" {...@@ -202,17 +202,17 @@ test "futex v1" {
202202
203 // No-op wait, lock value is not expected value203 // No-op wait, lock value is not expected value
204 rc = linux.futex(&lock.raw, .{ .cmd = .WAIT, .private = true }, 2, .{ .timeout = null }, null, 0);204 rc = linux.futex(&lock.raw, .{ .cmd = .WAIT, .private = true }, 2, .{ .timeout = null }, null, 0);
205 try expectEqual(.AGAIN, linux.E.init(rc));205 try expectEqual(.AGAIN, linux.errno(rc));
206206
207 rc = linux.futex_4arg(&lock.raw, .{ .cmd = .WAIT, .private = true }, 2, null);207 rc = linux.futex_4arg(&lock.raw, .{ .cmd = .WAIT, .private = true }, 2, null);
208 try expectEqual(.AGAIN, linux.E.init(rc));208 try expectEqual(.AGAIN, linux.errno(rc));
209209
210 // Short-fuse wait, timeout kicks in210 // Short-fuse wait, timeout kicks in
211 rc = linux.futex(&lock.raw, .{ .cmd = .WAIT, .private = true }, 1, .{ .timeout = &.{ .sec = 0, .nsec = 2 } }, null, 0);211 rc = linux.futex(&lock.raw, .{ .cmd = .WAIT, .private = true }, 1, .{ .timeout = &.{ .sec = 0, .nsec = 2 } }, null, 0);
212 try expectEqual(.TIMEDOUT, linux.E.init(rc));212 try expectEqual(.TIMEDOUT, linux.errno(rc));
213213
214 rc = linux.futex_4arg(&lock.raw, .{ .cmd = .WAIT, .private = true }, 1, &.{ .sec = 0, .nsec = 2 });214 rc = linux.futex_4arg(&lock.raw, .{ .cmd = .WAIT, .private = true }, 1, &.{ .sec = 0, .nsec = 2 });
215 try expectEqual(.TIMEDOUT, linux.E.init(rc));215 try expectEqual(.TIMEDOUT, linux.errno(rc));
216216
217 // Wakeup (no waiters)217 // Wakeup (no waiters)
218 rc = linux.futex(&lock.raw, .{ .cmd = .WAKE, .private = true }, 2, .{ .timeout = null }, null, 0);218 rc = linux.futex(&lock.raw, .{ .cmd = .WAKE, .private = true }, 2, .{ .timeout = null }, null, 0);
...@@ -223,7 +223,7 @@ test "futex v1" {...@@ -223,7 +223,7 @@ test "futex v1" {
223223
224 // CMP_REQUEUE - val3 mismatch224 // CMP_REQUEUE - val3 mismatch
225 rc = linux.futex(&lock.raw, .{ .cmd = .CMP_REQUEUE, .private = true }, 2, .{ .val2 = 0 }, null, 99);225 rc = linux.futex(&lock.raw, .{ .cmd = .CMP_REQUEUE, .private = true }, 2, .{ .val2 = 0 }, null, 99);
226 try expectEqual(.AGAIN, linux.E.init(rc));226 try expectEqual(.AGAIN, linux.errno(rc));
227227
228 // CMP_REQUEUE - requeue (but no waiters, so ... not much)228 // CMP_REQUEUE - requeue (but no waiters, so ... not much)
229 {229 {
...@@ -256,12 +256,12 @@ test "futex v1" {...@@ -256,12 +256,12 @@ test "futex v1" {
256 {256 {
257 // val1 return early257 // val1 return early
258 rc = linux.futex(&lock.raw, .{ .cmd = .WAIT_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0xfff);258 rc = linux.futex(&lock.raw, .{ .cmd = .WAIT_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0xfff);
259 try expectEqual(.AGAIN, linux.E.init(rc));259 try expectEqual(.AGAIN, linux.errno(rc));
260260
261 // timeout wait261 // timeout wait
262 const timeout: linux.timespec = .{ .sec = 0, .nsec = 2 };262 const timeout: linux.timespec = .{ .sec = 0, .nsec = 2 };
263 rc = linux.futex(&lock.raw, .{ .cmd = .WAIT_BITSET, .private = true }, 1, .{ .timeout = &timeout }, null, 0xfff);263 rc = linux.futex(&lock.raw, .{ .cmd = .WAIT_BITSET, .private = true }, 1, .{ .timeout = &timeout }, null, 0xfff);
264 try expectEqual(.TIMEDOUT, linux.E.init(rc));264 try expectEqual(.TIMEDOUT, linux.errno(rc));
265 }265 }
266266
267 // WAKE_BITSET267 // WAKE_BITSET
...@@ -271,7 +271,7 @@ test "futex v1" {...@@ -271,7 +271,7 @@ test "futex v1" {
271271
272 // bitmask must have at least 1 bit set:272 // bitmask must have at least 1 bit set:
273 rc = linux.futex(&lock.raw, .{ .cmd = .WAKE_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0);273 rc = linux.futex(&lock.raw, .{ .cmd = .WAKE_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0);
274 try expectEqual(.INVAL, linux.E.init(rc));274 try expectEqual(.INVAL, linux.errno(rc));
275 }275 }
276}276}
277277
...@@ -307,7 +307,7 @@ test "futex2_waitv" {...@@ -307,7 +307,7 @@ test "futex2_waitv" {
307307
308 const timeout = linux.kernel_timespec{ .sec = 0, .nsec = 2 }; // absolute timeout, so this is 1970...308 const timeout = linux.kernel_timespec{ .sec = 0, .nsec = 2 }; // absolute timeout, so this is 1970...
309 const rc = linux.futex2_waitv(&futexes, futexes.len, .{}, &timeout, .MONOTONIC);309 const rc = linux.futex2_waitv(&futexes, futexes.len, .{}, &timeout, .MONOTONIC);
310 switch (linux.E.init(rc)) {310 switch (linux.errno(rc)) {
311 .NOSYS => return error.SkipZigTest, // futex2_waitv added in kernel v5.16311 .NOSYS => return error.SkipZigTest, // futex2_waitv added in kernel v5.16
312 else => |err| try expectEqual(.TIMEDOUT, err),312 else => |err| try expectEqual(.TIMEDOUT, err),
313 }313 }
...@@ -318,7 +318,7 @@ test "futex2_waitv" {...@@ -318,7 +318,7 @@ test "futex2_waitv" {
318fn futex2_skip_if_unsupported() !void {318fn futex2_skip_if_unsupported() !void {
319 const lock: u32 = 0;319 const lock: u32 = 0;
320 const rc = linux.futex2_wake(&lock, 0, 1, .{ .size = .U32, .private = true });320 const rc = linux.futex2_wake(&lock, 0, 1, .{ .size = .U32, .private = true });
321 if (linux.E.init(rc) == .NOSYS) {321 if (linux.errno(rc) == .NOSYS) {
322 return error.SkipZigTest;322 return error.SkipZigTest;
323 }323 }
324}324}
...@@ -334,23 +334,23 @@ test "futex2_wait" {...@@ -334,23 +334,23 @@ test "futex2_wait" {
334 // (at least) they're not implemented.334 // (at least) they're not implemented.
335 if (false) {335 if (false) {
336 rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U8, .private = true }, null, .MONOTONIC);336 rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U8, .private = true }, null, .MONOTONIC);
337 try expectEqual(.INVAL, linux.E.init(rc));337 try expectEqual(.INVAL, linux.errno(rc));
338338
339 rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U16, .private = true }, null, .MONOTONIC);339 rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U16, .private = true }, null, .MONOTONIC);
340 try expectEqual(.INVAL, linux.E.init(rc));340 try expectEqual(.INVAL, linux.errno(rc));
341341
342 rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U64, .private = true }, null, .MONOTONIC);342 rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U64, .private = true }, null, .MONOTONIC);
343 try expectEqual(.INVAL, linux.E.init(rc));343 try expectEqual(.INVAL, linux.errno(rc));
344 }344 }
345345
346 const flags = linux.FUTEX2_FLAGS{ .size = .U32, .private = true };346 const flags = linux.FUTEX2_FLAGS{ .size = .U32, .private = true };
347 // no-wait, lock state mismatch347 // no-wait, lock state mismatch
348 rc = linux.futex2_wait(&lock.raw, 2, mask, flags, null, .MONOTONIC);348 rc = linux.futex2_wait(&lock.raw, 2, mask, flags, null, .MONOTONIC);
349 try expectEqual(.AGAIN, linux.E.init(rc));349 try expectEqual(.AGAIN, linux.errno(rc));
350350
351 // hit timeout on wait351 // hit timeout on wait
352 rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &.{ .sec = 0, .nsec = 2 }, .MONOTONIC);352 rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &.{ .sec = 0, .nsec = 2 }, .MONOTONIC);
353 try expectEqual(.TIMEDOUT, linux.E.init(rc));353 try expectEqual(.TIMEDOUT, linux.errno(rc));
354354
355 // timeout is absolute355 // timeout is absolute
356 {356 {
...@@ -364,11 +364,11 @@ test "futex2_wait" {...@@ -364,11 +364,11 @@ test "futex2_wait" {
364 .nsec = curr.nsec + 2,364 .nsec = curr.nsec + 2,
365 };365 };
366 rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &timeout, .MONOTONIC);366 rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &timeout, .MONOTONIC);
367 try expectEqual(.TIMEDOUT, linux.E.init(rc));367 try expectEqual(.TIMEDOUT, linux.errno(rc));
368 }368 }
369369
370 rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &.{ .sec = 0, .nsec = 2 }, .REALTIME);370 rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &.{ .sec = 0, .nsec = 2 }, .REALTIME);
371 try expectEqual(.TIMEDOUT, linux.E.init(rc));371 try expectEqual(.TIMEDOUT, linux.errno(rc));
372}372}
373373
374test "futex2_wake" {374test "futex2_wake" {
...@@ -405,6 +405,14 @@ test "futex2_requeue" {...@@ -405,6 +405,14 @@ test "futex2_requeue" {
405 try expectEqual(0, rc);405 try expectEqual(0, rc);
406}406}
407407
408test "copy_file_range error" {
409 const fds = try std.posix.pipe();
410 defer std.posix.close(fds[0]);
411 defer std.posix.close(fds[1]);
412
413 try std.testing.expectError(error.InvalidArguments, linux.wrapped.copy_file_range(fds[0], null, fds[1], null, 1, 0));
414}
415
408test {416test {
409 _ = linux.IoUring;417 _ = linux.IoUring;
410}418}
lib/std/os/linux/tls.zig+1-1
...@@ -555,7 +555,7 @@ pub fn initStatic(phdrs: []elf.Phdr) void {...@@ -555,7 +555,7 @@ pub fn initStatic(phdrs: []elf.Phdr) void {
555 }555 }
556556
557 const begin_addr = mmap_tls(area_desc.size + area_desc.alignment - 1);557 const begin_addr = mmap_tls(area_desc.size + area_desc.alignment - 1);
558 if (@call(.always_inline, linux.E.init, .{begin_addr}) != .SUCCESS) @trap();558 if (@call(.always_inline, linux.errno, .{begin_addr}) != .SUCCESS) @trap();
559559
560 const area_ptr: [*]align(page_size_min) u8 = @ptrFromInt(begin_addr);560 const area_ptr: [*]align(page_size_min) u8 = @ptrFromInt(begin_addr);
561561
lib/std/os/plan9.zig+8-6
...@@ -94,13 +94,15 @@ pub const E = enum(u16) {...@@ -94,13 +94,15 @@ pub const E = enum(u16) {
94 OVERFLOW,94 OVERFLOW,
95 LOOP,95 LOOP,
96 TXTBSY,96 TXTBSY,
97
98 pub fn init(r: usize) E {
99 const signed_r: isize = @bitCast(r);
100 const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
101 return @enumFromInt(int);
102 }
103};97};
98
99/// Get the errno from a syscall return value. SUCCESS means no error.
100pub fn errno(r: usize) E {
101 const signed_r: isize = @bitCast(r);
102 const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
103 return @enumFromInt(int);
104}
105
104// The max bytes that can be in the errstr buff106// The max bytes that can be in the errstr buff
105pub const ERRMAX = 128;107pub const ERRMAX = 128;
106var errstr_buf: [ERRMAX]u8 = undefined;108var errstr_buf: [ERRMAX]u8 = undefined;
lib/std/posix.zig+9-16
...@@ -272,14 +272,7 @@ pub const socket_t = if (native_os == .windows) windows.ws2_32.SOCKET else fd_t;...@@ -272,14 +272,7 @@ pub const socket_t = if (native_os == .windows) windows.ws2_32.SOCKET else fd_t;
272/// for others it will use a thread-local errno variable. Therefore, this272/// for others it will use a thread-local errno variable. Therefore, this
273/// function only returns a well-defined value when it is called directly after273/// function only returns a well-defined value when it is called directly after
274/// the system function call whose errno value is intended to be observed.274/// the system function call whose errno value is intended to be observed.
275pub fn errno(rc: anytype) E {275pub const errno = system.errno;
276 if (use_libc) {
277 return if (rc == -1) @enumFromInt(std.c._errno().*) else .SUCCESS;
278 }
279 const signed: isize = @bitCast(rc);
280 const int = if (signed > -4096 and signed < 0) -signed else 0;
281 return @enumFromInt(int);
282}
283276
284/// Closes the file descriptor.277/// Closes the file descriptor.
285///278///
...@@ -433,7 +426,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr...@@ -433,7 +426,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
433 // Later on this should be changed to `system.fchmodat2`426 // Later on this should be changed to `system.fchmodat2`
434 // when the musl/glibc add a wrapper.427 // when the musl/glibc add a wrapper.
435 const res = linux.fchmodat2(dirfd, &path_c, mode, flags);428 const res = linux.fchmodat2(dirfd, &path_c, mode, flags);
436 switch (E.init(res)) {429 switch (linux.errno(res)) {
437 .SUCCESS => return,430 .SUCCESS => return,
438 .INTR => continue,431 .INTR => continue,
439 .BADF => unreachable,432 .BADF => unreachable,
...@@ -588,7 +581,7 @@ pub const RebootCommand = switch (native_os) {...@@ -588,7 +581,7 @@ pub const RebootCommand = switch (native_os) {
588pub fn reboot(cmd: RebootCommand) RebootError!void {581pub fn reboot(cmd: RebootCommand) RebootError!void {
589 switch (native_os) {582 switch (native_os) {
590 .linux => {583 .linux => {
591 switch (linux.E.init(linux.reboot(584 switch (linux.errno(linux.reboot(
592 .MAGIC1,585 .MAGIC1,
593 .MAGIC2,586 .MAGIC2,
594 cmd,587 cmd,
...@@ -647,7 +640,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {...@@ -647,7 +640,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
647 break :res .{ @bitCast(rc), errno(rc) };640 break :res .{ @bitCast(rc), errno(rc) };
648 } else res: {641 } else res: {
649 const rc = linux.getrandom(buf.ptr, buf.len, 0);642 const rc = linux.getrandom(buf.ptr, buf.len, 0);
650 break :res .{ rc, linux.E.init(rc) };643 break :res .{ rc, linux.errno(rc) };
651 };644 };
652645
653 switch (err) {646 switch (err) {
...@@ -3298,7 +3291,7 @@ pub fn isatty(handle: fd_t) bool {...@@ -3298,7 +3291,7 @@ pub fn isatty(handle: fd_t) bool {
3298 var wsz: winsize = undefined;3291 var wsz: winsize = undefined;
3299 const fd: usize = @bitCast(@as(isize, handle));3292 const fd: usize = @bitCast(@as(isize, handle));
3300 const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz));3293 const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz));
3301 switch (linux.E.init(rc)) {3294 switch (linux.errno(rc)) {
3302 .SUCCESS => return true,3295 .SUCCESS => return true,
3303 .INTR => continue,3296 .INTR => continue,
3304 else => return false,3297 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...@@ -5762,7 +5755,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
5762 while (true) {5755 while (true) {
5763 const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);5756 const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);
5764 if (native_os == .freebsd) {5757 if (native_os == .freebsd) {
5765 switch (errno(rc)) {5758 switch (sys.errno(rc)) {
5766 .SUCCESS => return @intCast(rc),5759 .SUCCESS => return @intCast(rc),
5767 .BADF => return error.FilesOpenedWithWrongFlags,5760 .BADF => return error.FilesOpenedWithWrongFlags,
5768 .FBIG => return error.FileTooBig,5761 .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...@@ -5775,7 +5768,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
5775 else => |err| return unexpectedErrno(err),5768 else => |err| return unexpectedErrno(err),
5776 }5769 }
5777 } else { // assume linux5770 } else { // assume linux
5778 switch (errno(rc)) {5771 switch (sys.errno(rc)) {
5779 .SUCCESS => return @intCast(rc),5772 .SUCCESS => return @intCast(rc),
5780 .BADF => return error.FilesOpenedWithWrongFlags,5773 .BADF => return error.FilesOpenedWithWrongFlags,
5781 .FBIG => return error.FileTooBig,5774 .FBIG => return error.FileTooBig,
...@@ -6070,7 +6063,7 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {...@@ -6070,7 +6063,7 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
6070 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 30, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });6063 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 30, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });
6071 const sys = if (use_c) std.c else linux;6064 const sys = if (use_c) std.c else linux;
6072 const rc = sys.memfd_create(name, flags);6065 const rc = sys.memfd_create(name, flags);
6073 switch (errno(rc)) {6066 switch (sys.errno(rc)) {
6074 .SUCCESS => return @intCast(rc),6067 .SUCCESS => return @intCast(rc),
6075 .FAULT => unreachable, // name has invalid memory6068 .FAULT => unreachable, // name has invalid memory
6076 .INVAL => return error.NameTooLong, // or, program has a bug and flags are faulty6069 .INVAL => return error.NameTooLong, // or, program has a bug and flags are faulty
...@@ -6494,7 +6487,7 @@ pub fn perf_event_open(...@@ -6494,7 +6487,7 @@ pub fn perf_event_open(
6494 if (native_os == .linux) {6487 if (native_os == .linux) {
6495 // There is no syscall wrapper for this function exposed by libcs6488 // There is no syscall wrapper for this function exposed by libcs
6496 const rc = linux.perf_event_open(attr, pid, cpu, group_fd, flags);6489 const rc = linux.perf_event_open(attr, pid, cpu, group_fd, flags);
6497 switch (errno(rc)) {6490 switch (linux.errno(rc)) {
6498 .SUCCESS => return @intCast(rc),6491 .SUCCESS => return @intCast(rc),
6499 .@"2BIG" => return error.TooBig,6492 .@"2BIG" => return error.TooBig,
6500 .ACCES => return error.PermissionDenied,6493 .ACCES => return error.PermissionDenied,
lib/std/process.zig+1-1
...@@ -1772,7 +1772,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {...@@ -1772,7 +1772,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
1772 .linux => {1772 .linux => {
1773 var info: std.os.linux.Sysinfo = undefined;1773 var info: std.os.linux.Sysinfo = undefined;
1774 const result: usize = std.os.linux.sysinfo(&info);1774 const result: usize = std.os.linux.sysinfo(&info);
1775 if (std.os.linux.E.init(result) != .SUCCESS) {1775 if (std.os.linux.errno(result) != .SUCCESS) {
1776 return error.UnknownTotalSystemMemory;1776 return error.UnknownTotalSystemMemory;
1777 }1777 }
1778 // Promote to u64 to avoid overflow on systems where info.totalram is a 32-bit usize1778 // Promote to u64 to avoid overflow on systems where info.totalram is a 32-bit usize
src/link/Elf/ZigObject.zig+2-2
...@@ -1437,7 +1437,7 @@ fn updateNavCode(...@@ -1437,7 +1437,7 @@ fn updateNavCode(
1437 .len = code.len,1437 .len = code.len,
1438 }};1438 }};
1439 const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0);1439 const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0);
1440 switch (std.os.linux.E.init(rc)) {1440 switch (std.os.linux.errno(rc)) {
1441 .SUCCESS => assert(rc == code.len),1441 .SUCCESS => assert(rc == code.len),
1442 else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),1442 else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
1443 }1443 }
...@@ -2026,7 +2026,7 @@ fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void {...@@ -2026,7 +2026,7 @@ fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void {
2026 .len = out.len,2026 .len = out.len,
2027 }};2027 }};
2028 const rc = std.os.linux.process_vm_writev(pid, &local_vec, &remote_vec, 0);2028 const rc = std.os.linux.process_vm_writev(pid, &local_vec, &remote_vec, 0);
2029 switch (std.os.linux.E.init(rc)) {2029 switch (std.os.linux.errno(rc)) {
2030 .SUCCESS => assert(rc == out.len),2030 .SUCCESS => assert(rc == out.len),
2031 else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),2031 else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
2032 }2032 }
src/link/MappedFile.zig+3-3
...@@ -645,7 +645,7 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested...@@ -645,7 +645,7 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested
645 @intCast(requested_size +| requested_size / growth_factor),645 @intCast(requested_size +| requested_size / growth_factor),
646 ) - old_size;646 ) - old_size;
647 _, const file_size = Node.Index.root.location(mf).resolve(mf);647 _, const file_size = Node.Index.root.location(mf).resolve(mf);
648 while (true) switch (linux.E.init(switch (std.math.order(range_file_offset, file_size)) {648 while (true) switch (linux.errno(switch (std.math.order(range_file_offset, file_size)) {
649 .lt => linux.fallocate(649 .lt => linux.fallocate(
650 mf.file.handle,650 mf.file.handle,
651 linux.FALLOC.FL_INSERT_RANGE,651 linux.FALLOC.FL_INSERT_RANGE,
...@@ -858,7 +858,7 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size:...@@ -858,7 +858,7 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size:
858 // delete the copy of this node at the old location858 // delete the copy of this node at the old location
859 if (is_linux and !mf.flags.fallocate_punch_hole_unsupported and859 if (is_linux and !mf.flags.fallocate_punch_hole_unsupported and
860 size >= mf.flags.block_size.toByteUnits() * 2 - 1) while (true)860 size >= mf.flags.block_size.toByteUnits() * 2 - 1) while (true)
861 switch (linux.E.init(linux.fallocate(861 switch (linux.errno(linux.fallocate(
862 mf.file.handle,862 mf.file.handle,
863 linux.FALLOC.FL_PUNCH_HOLE | linux.FALLOC.FL_KEEP_SIZE,863 linux.FALLOC.FL_PUNCH_HOLE | linux.FALLOC.FL_KEEP_SIZE,
864 @intCast(old_file_offset),864 @intCast(old_file_offset),
...@@ -910,7 +910,7 @@ fn copyFileRange(...@@ -910,7 +910,7 @@ fn copyFileRange(
910 @intCast(remaining_size),910 @intCast(remaining_size),
911 0,911 0,
912 );912 );
913 switch (linux.E.init(copy_len)) {913 switch (linux.errno(copy_len)) {
914 .SUCCESS => {914 .SUCCESS => {
915 if (copy_len == 0) break;915 if (copy_len == 0) break;
916 remaining_size -= copy_len;916 remaining_size -= copy_len;