From a2ea36a51767659edf7feeee87eb237263e0dc4a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 21 Jan 2026 18:11:16 -0800 Subject: [PATCH] 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. --- lib/c/common.zig | 24 ++++++++++++++---------- lib/c/sys/utsname.zig | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/c/common.zig b/lib/c/common.zig index 09dc5a8c0cbf2fe18160a2310ab4d33ffbfa7545..8d2a79db54b33515ef75c98bf5eb1defe23cb19a 100644 --- 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 index 06f849ba6df4e8aa642e1361e6f9e5d57fff7367..6082c1b6cecf6c15c8454cf362fef9e49cc1e3e8 100644 --- 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 { -- 2.54.0