commit a2ea36a51767659edf7feeee87eb237263e0dc4a (tree)
parent 9d63dfaa81716a87b9c8c6dc5bdf1d07a8278b55
Author: Andrew Kelley <andrew@ziglang.org>
Date: Wed, 21 Jan 2026 18:11:16 -0800
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.
Diffstat:
2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/lib/c/common.zig b/lib/c/common.zig
@@ -14,16 +14,20 @@ pub const visibility: std.builtin.SymbolVisibility = if (linkage != .internal)
else
.default;
-/// Checks whether the syscall has had an error, storing it in `std.c.errno` and returning -1.
-/// Otherwise returns the result.
-pub fn linuxErrno(r: usize) isize {
- const linux = std.os.linux;
-
- return switch (linux.errno(r)) {
- .SUCCESS => @bitCast(r),
- else => |err| blk: {
- std.c._errno().* = @intFromEnum(err);
- break :blk -1;
+/// Given a low-level syscall return value, sets errno and returns `-1`, or on
+/// success returns the result.
+pub fn errno(syscall_return_value: usize) c_int {
+ return switch (builtin.os.tag) {
+ .linux => {
+ const signed: isize = @bitCast(syscall_return_value);
+ const casted: c_int = @intCast(signed);
+ if (casted < 0) {
+ @branchHint(.unlikely);
+ std.c._errno().* = -casted;
+ return -1;
+ }
+ return casted;
},
+ else => comptime unreachable,
};
}
diff --git a/lib/c/sys/utsname.zig b/lib/c/sys/utsname.zig
@@ -13,7 +13,7 @@ comptime {
}
fn unameLinux(uts: *std.os.linux.utsname) callconv(.c) c_int {
- return @intCast(common.linuxErrno(std.os.linux.uname(uts)));
+ return common.errno(std.os.linux.uname(uts));
}
fn unameWasi(uts: *std.c.utsname) callconv(.c) c_int {