authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-21 18:11:16-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-24 20:18:18+01:00
loga2ea36a51767659edf7feeee87eb237263e0dc4a
treee39546b1e6be149d7dbfe9a73ff57599a657ece3
parent9d63dfaa81716a87b9c8c6dc5bdf1d07a8278b55

zig libc: modify errno helper to eliminate `@intCast`

The vast majority of libc functions return `c_int` for the return value, when setting errno. This utility function is for those cases. Other cases can hand-roll the logic, or additional helpers can be added.

2 files changed, 15 insertions(+), 11 deletions(-)

lib/c/common.zig+14-10
......@@ -14,16 +14,20 @@ pub const visibility: std.builtin.SymbolVisibility = if (linkage != .internal)
1414else
1515 .default;
1616
17/// Checks whether the syscall has had an error, storing it in `std.c.errno` and returning -1.
18/// Otherwise returns the result.
19pub fn linuxErrno(r: usize) isize {
20 const linux = std.os.linux;
21
22 return switch (linux.errno(r)) {
23 .SUCCESS => @bitCast(r),
24 else => |err| blk: {
25 std.c._errno().* = @intFromEnum(err);
26 break :blk -1;
17/// Given a low-level syscall return value, sets errno and returns `-1`, or on
18/// success returns the result.
19pub fn errno(syscall_return_value: usize) c_int {
20 return switch (builtin.os.tag) {
21 .linux => {
22 const signed: isize = @bitCast(syscall_return_value);
23 const casted: c_int = @intCast(signed);
24 if (casted < 0) {
25 @branchHint(.unlikely);
26 std.c._errno().* = -casted;
27 return -1;
28 }
29 return casted;
2730 },
31 else => comptime unreachable,
2832 };
2933}
lib/c/sys/utsname.zig+1-1
......@@ -13,7 +13,7 @@ comptime {
1313}
1414
1515fn unameLinux(uts: *std.os.linux.utsname) callconv(.c) c_int {
16 return @intCast(common.linuxErrno(std.os.linux.uname(uts)));
16 return common.errno(std.os.linux.uname(uts));
1717}
1818
1919fn unameWasi(uts: *std.c.utsname) callconv(.c) c_int {