Skip to content

Commit 6b4f45f

Browse files
rpkakandrewrk
authored andcommitted
system specific errno
1 parent 4b5351b commit 6b4f45f

File tree

15 files changed

+91
-98
lines changed

15 files changed

+91
-98
lines changed

lib/std/Io/Threaded.zig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,7 @@ fn dirStatPathLinux(
13021302
linux.STATX_INO | linux.STATX_SIZE | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
13031303
&statx,
13041304
);
1305-
switch (linux.E.init(rc)) {
1305+
switch (linux.errno(rc)) {
13061306
.SUCCESS => return statFromLinux(&statx),
13071307
.INTR => continue,
13081308
.CANCELED => return error.Canceled,
@@ -1449,7 +1449,7 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
14491449
linux.STATX_INO | linux.STATX_SIZE | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
14501450
&statx,
14511451
);
1452-
switch (linux.E.init(rc)) {
1452+
switch (linux.errno(rc)) {
14531453
.SUCCESS => return statFromLinux(&statx),
14541454
.INTR => continue,
14551455
.CANCELED => return error.Canceled,
@@ -2931,7 +2931,7 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
29312931
var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);
29322932
while (true) {
29332933
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) {
29352935
.none, .duration => false,
29362936
.deadline => true,
29372937
} }, &timespec, &timespec))) {
@@ -5677,7 +5677,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca
56775677
const linux = std.os.linux;
56785678
try t.checkCancel();
56795679
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)) {
56815681
.SUCCESS => {}, // notified by `wake()`
56825682
.INTR => {}, // gives caller a chance to check cancellation
56835683
.AGAIN => {}, // ptr.* != expect
@@ -5764,7 +5764,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
57645764
.linux => {
57655765
const linux = std.os.linux;
57665766
const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);
5767-
switch (linux.E.init(rc)) {
5767+
switch (linux.errno(rc)) {
57685768
.SUCCESS => {}, // notified by `wake()`
57695769
.INTR => {}, // gives caller a chance to check cancellation
57705770
.AGAIN => {}, // ptr.* != expect
@@ -5827,7 +5827,7 @@ pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect:
58275827
const linux = std.os.linux;
58285828
var ts = timestampToPosix(timeout.toNanoseconds());
58295829
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)) {
58315831
.SUCCESS => {}, // notified by `wake()`
58325832
.INTR => {}, // gives caller a chance to check cancellation
58335833
.AGAIN => {}, // ptr.* != expect
@@ -5861,7 +5861,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
58615861
} else switch (native_os) {
58625862
.linux => {
58635863
const linux = std.os.linux;
5864-
switch (linux.E.init(linux.futex_3arg(
5864+
switch (linux.errno(linux.futex_3arg(
58655865
&ptr.raw,
58665866
.{ .cmd = .WAKE, .private = true },
58675867
@min(max_waiters, std.math.maxInt(i32)),

lib/std/Thread.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,7 +1622,7 @@ const LinuxThreadImpl = struct {
16221622
linux.CLONE.PARENT_SETTID | linux.CLONE.CHILD_CLEARTID |
16231623
linux.CLONE.SIGHAND | linux.CLONE.SYSVSEM | linux.CLONE.SETTLS;
16241624

1625-
switch (linux.E.init(linux.clone(
1625+
switch (linux.errno(linux.clone(
16261626
Instance.entryFn,
16271627
@intFromPtr(&mapped[stack_offset]),
16281628
flags,
@@ -1661,7 +1661,7 @@ const LinuxThreadImpl = struct {
16611661
const tid = self.thread.child_tid.load(.seq_cst);
16621662
if (tid == 0) break;
16631663

1664-
switch (linux.E.init(linux.futex_4arg(
1664+
switch (linux.errno(linux.futex_4arg(
16651665
&self.thread.child_tid.raw,
16661666
.{ .cmd = .WAIT, .private = false },
16671667
@bitCast(tid),

lib/std/Thread/Futex.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ const LinuxImpl = struct {
269269
if (timeout != null) &ts else null,
270270
);
271271

272-
switch (linux.E.init(rc)) {
272+
switch (linux.errno(rc)) {
273273
.SUCCESS => {}, // notified by `wake()`
274274
.INTR => {}, // spurious wakeup
275275
.AGAIN => {}, // ptr.* != expect
@@ -290,7 +290,7 @@ const LinuxImpl = struct {
290290
@min(max_waiters, std.math.maxInt(i32)),
291291
);
292292

293-
switch (linux.E.init(rc)) {
293+
switch (linux.errno(rc)) {
294294
.SUCCESS => {}, // successful wake up
295295
.INVAL => {}, // invalid futex_wait() on ptr done elsewhere
296296
.FAULT => {}, // pointer became invalid while doing the wake

lib/std/c.zig

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ pub inline fn versionCheck(comptime version: std.SemanticVersion) bool {
7272
};
7373
}
7474

75+
/// Get the errno if rc is -1 and SUCCESS if rc is not -1.
76+
pub fn errno(rc: anytype) E {
77+
return if (rc == -1) @enumFromInt(_errno().*) else .SUCCESS;
78+
}
79+
7580
pub const ino_t = switch (native_os) {
7681
.linux => linux.ino_t,
7782
.emscripten => emscripten.ino_t,
@@ -11580,6 +11585,6 @@ const private = struct {
1158011585
extern threadlocal var errno: c_int;
1158111586

1158211587
fn errnoFromThreadLocal() *c_int {
11583-
return &errno;
11588+
return &private.errno;
1158411589
}
1158511590
};

lib/std/fs/Dir.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ pub const Iterator = switch (native_os) {
378378
self.first_iter = false;
379379
}
380380
const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len);
381-
switch (linux.E.init(rc)) {
381+
switch (linux.errno(rc)) {
382382
.SUCCESS => {},
383383
.BADF => unreachable, // Dir is invalid or was opened without iteration ability
384384
.FAULT => unreachable,

lib/std/os/linux.zig

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -568,9 +568,8 @@ fn splitValue64(val: i64) [2]u32 {
568568
}
569569
}
570570

571-
/// Get the errno from a syscall return value, or 0 for no error.
572-
/// The public API is exposed via the `E` namespace.
573-
fn errnoFromSyscall(r: usize) E {
571+
/// Get the errno from a syscall return value. SUCCESS means no error.
572+
pub fn errno(r: usize) E {
574573
const signed_r: isize = @bitCast(r);
575574
const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
576575
return @enumFromInt(int);
@@ -1961,7 +1960,7 @@ pub fn sigaction(sig: SIG, noalias act: ?*const Sigaction, noalias oact: ?*Sigac
19611960
.sparc, .sparc64 => syscall5(.rt_sigaction, @intFromEnum(sig), ksa_arg, oldksa_arg, @intFromPtr(ksa.restorer), mask_size),
19621961
else => syscall4(.rt_sigaction, @intFromEnum(sig), ksa_arg, oldksa_arg, mask_size),
19631962
};
1964-
if (E.init(result) != .SUCCESS) return result;
1963+
if (errno(result) != .SUCCESS) return result;
19651964

19661965
if (oact) |old| {
19671966
old.handler.handler = oldksa.handler;
@@ -2402,7 +2401,7 @@ pub fn sched_setaffinity(pid: pid_t, set: *const cpu_set_t) !void {
24022401
const size = @sizeOf(cpu_set_t);
24032402
const rc = syscall3(.sched_setaffinity, @as(usize, @bitCast(@as(isize, pid))), size, @intFromPtr(set));
24042403

2405-
switch (E.init(rc)) {
2404+
switch (errno(rc)) {
24062405
.SUCCESS => return,
24072406
else => |err| return std.posix.unexpectedErrno(err),
24082407
}
@@ -3003,8 +3002,6 @@ pub const E = switch (native_arch) {
30033002
HWPOISON = 168,
30043003
DQUOT = 1133,
30053004
_,
3006-
3007-
pub const init = errnoFromSyscall;
30083005
},
30093006
.sparc, .sparc64 => enum(u16) {
30103007
/// No error occurred.
@@ -3148,8 +3145,6 @@ pub const E = switch (native_arch) {
31483145
RFKILL = 134,
31493146
HWPOISON = 135,
31503147
_,
3151-
3152-
pub const init = errnoFromSyscall;
31533148
},
31543149
else => enum(u16) {
31553150
/// No error occurred.
@@ -3459,8 +3454,6 @@ pub const E = switch (native_arch) {
34593454
NSRCNAMELOOP = 177,
34603455

34613456
_,
3462-
3463-
pub const init = errnoFromSyscall;
34643457
},
34653458
};
34663459

@@ -9892,7 +9885,7 @@ pub const wrapped = struct {
98929885
const adjusted_len = @min(in_len, 0x7ffff000); // Prevents EOVERFLOW.
98939886
const sendfileSymbol = if (lfs64_abi) system.sendfile64 else system.sendfile;
98949887
const rc = sendfileSymbol(out_fd, in_fd, in_offset, adjusted_len);
9895-
switch (errno(rc)) {
9888+
switch (system.errno(rc)) {
98969889
.SUCCESS => return @intCast(rc),
98979890
.BADF => return invalidApiUsage(), // Always a race condition.
98989891
.FAULT => return invalidApiUsage(), // Segmentation fault.
@@ -9958,7 +9951,7 @@ pub const wrapped = struct {
99589951
const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });
99599952
const sys = if (use_c) std.c else std.os.linux;
99609953
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)) {
99629955
.SUCCESS => return @intCast(rc),
99639956
.BADF => return error.BadFileFlags,
99649957
.FBIG => return error.FileTooBig,
@@ -9982,12 +9975,4 @@ pub const wrapped = struct {
99829975
if (builtin.mode == .Debug) @panic("invalid API usage");
99839976
return error.Unexpected;
99849977
}
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-
}
99939978
};

lib/std/os/linux/IoUring.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub fn init_params(entries: u16, p: *linux.io_uring_params) !IoUring {
4646
assert(p.resv[2] == 0);
4747

4848
const res = linux.io_uring_setup(entries, p);
49-
switch (linux.E.init(res)) {
49+
switch (linux.errno(res)) {
5050
.SUCCESS => {},
5151
.FAULT => return error.ParamsOutsideAccessibleAddressSpace,
5252
// 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 {
175175
pub fn enter(self: *IoUring, to_submit: u32, min_complete: u32, flags: u32) !u32 {
176176
assert(self.fd >= 0);
177177
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)) {
179179
.SUCCESS => {},
180180
// The kernel was unable to allocate memory or ran out of resources for the request.
181181
// 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 {
12981298
pub fn unregister_buffers(self: *IoUring) !void {
12991299
assert(self.fd >= 0);
13001300
const res = linux.io_uring_register(self.fd, .UNREGISTER_BUFFERS, null, 0);
1301-
switch (linux.E.init(res)) {
1301+
switch (linux.errno(res)) {
13021302
.SUCCESS => {},
13031303
.NXIO => return error.BuffersNotRegistered,
13041304
else => |errno| return posix.unexpectedErrno(errno),
@@ -1316,7 +1316,7 @@ pub fn get_probe(self: *IoUring) !linux.io_uring_probe {
13161316
}
13171317

13181318
fn handle_registration_result(res: usize) !void {
1319-
switch (linux.E.init(res)) {
1319+
switch (linux.errno(res)) {
13201320
.SUCCESS => {},
13211321
// One or more fds in the array are invalid, or the kernel does not support sparse sets:
13221322
.BADF => return error.FileDescriptorInvalid,
@@ -1341,7 +1341,7 @@ fn handle_registration_result(res: usize) !void {
13411341
pub fn unregister_files(self: *IoUring) !void {
13421342
assert(self.fd >= 0);
13431343
const res = linux.io_uring_register(self.fd, .UNREGISTER_FILES, null, 0);
1344-
switch (linux.E.init(res)) {
1344+
switch (linux.errno(res)) {
13451345
.SUCCESS => {},
13461346
.NXIO => return error.FilesNotRegistered,
13471347
else => |errno| return posix.unexpectedErrno(errno),
@@ -1771,7 +1771,7 @@ fn register_buf_ring(
17711771
.flags = flags,
17721772
});
17731773
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) {
17751775
// Retry without incremental buffer consumption.
17761776
// It is available since kernel 6.12. returns INVAL on older.
17771777
reg.flags.inc = false;
@@ -1794,7 +1794,7 @@ fn unregister_buf_ring(fd: linux.fd_t, group_id: u16) !void {
17941794
}
17951795

17961796
fn handle_register_buf_ring_result(res: usize) !void {
1797-
switch (linux.E.init(res)) {
1797+
switch (linux.errno(res)) {
17981798
.SUCCESS => {},
17991799
.INVAL => return error.ArgumentsInvalid,
18001800
else => |errno| return posix.unexpectedErrno(errno),
@@ -4085,7 +4085,7 @@ inline fn skipKernelLessThan(required: std.SemanticVersion) !void {
40854085

40864086
var uts: linux.utsname = undefined;
40874087
const res = linux.uname(&uts);
4088-
switch (linux.E.init(res)) {
4088+
switch (linux.errno(res)) {
40894089
.SUCCESS => {},
40904090
else => |errno| return posix.unexpectedErrno(errno),
40914091
}

lib/std/os/linux/bpf.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const std = @import("../../std.zig");
2-
const errno = linux.E.init;
2+
const errno = linux.errno;
33
const unexpectedErrno = std.posix.unexpectedErrno;
44
const expectEqual = std.testing.expectEqual;
55
const expectError = std.testing.expectError;

0 commit comments

Comments
 (0)