zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

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:
Mlib/c/common.zig | 24++++++++++++++----------
Mlib/c/sys/utsname.zig | 2+-
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 {