From 76c62e509b31fa31a537da94966cbd2971dfa79b Mon Sep 17 00:00:00 2001 From: Brandon Black Date: Tue, 2 Sep 2025 12:20:11 -0500 Subject: [PATCH] Fix cmsghdr struct for the *nixes Previously we had a single definition of std.c.cmsghdr for all libc-linking platforms which aliased from the Solaris definition, a superfluous matching one in std.os.dragonfly, and no others. The existing definition from std.c didn't actually work for Linux, as Linux's "len" field is usize in the kernel's definition. Emscripten follows the Linux model of course (but uses the binary-compatible musl definition, which has an endian-sensitive padding scheme to make the len type "socklen_t" even though the kernel uses a usize, which is fair). This unifies and documents all the known *nix-ish cases (I'm not sure if wasi or windows really has cmsghdr support? Could be added later, void for now), such that c.cmsghdr and posix.system.cmsghdr should work correctly for all the known cases here, libc or otherwise. --- lib/std/c.zig | 34 +++++++++++++++++++++++++++++++++- lib/std/c/dragonfly.zig | 6 ------ lib/std/c/solaris.zig | 6 ------ lib/std/os/linux.zig | 7 +++++++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/lib/std/c.zig b/lib/std/c.zig index 380aad88f5ea74ecc9ff39ccd17daa90edd9048d..4b869bf2e488a2099b38b7ed0ea210caed882357 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -4171,6 +4171,39 @@ pub const msghdr_const = switch (native_os) { }, else => void, }; +pub const cmsghdr = switch (native_os) { + // https://github.com/emscripten-core/emscripten/blob/96371ed7888fc78c040179f4d4faa82a6a07a116/system/lib/libc/musl/include/sys/socket.h#L44 + .linux, .emscripten => linux.cmsghdr, + // https://github.com/freebsd/freebsd-src/blob/b197d2abcb6895d78bc9df8404e374397aa44748/sys/sys/socket.h#L492 + .freebsd, + // https://github.com/DragonFlyBSD/DragonFlyBSD/blob/107c0518337ba90e7fa49e74845d8d44320c9a6d/sys/sys/socket.h#L452 + .dragonfly, + // https://github.com/NetBSD/src/blob/ba8e1774fd9c0c26ecca461c07bc95d9ebb69579/sys/sys/socket.h#L528 + .netbsd, + // https://github.com/openbsd/src/blob/master/sys/sys/socket.h#L527 + .openbsd, + // https://github.com/kofemann/opensolaris/blob/80192cd83bf665e708269dae856f9145f7190f74/usr/src/uts/common/sys/socket.h#L416 + .solaris, + // https://github.com/illumos/illumos-gate/blob/afdf2e523873cb523df379676067bf9785a0f456/usr/src/uts/common/sys/socket.h#L460 + .illumos, + // https://github.com/SerenityOS/serenity/blob/4ee360a348a5e2490eeaeeabb3eb19e70dd450eb/Kernel/API/POSIX/sys/socket.h#L68 + .serenity, + // https://github.com/haiku/haiku/blob/b54f586058fd6623645512e4631468cede9933b9/headers/posix/sys/socket.h#L132 + .haiku, + // https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/socket.h#L1041 + .macos, + .driverkit, + .ios, + .tvos, + .visionos, + .watchos, + => extern struct { + len: socklen_t, + level: c_int, + type: c_int, + }, + else => void, +}; pub const nfds_t = switch (native_os) { .linux => linux.nfds_t, .emscripten => emscripten.nfds_t, @@ -11010,7 +11043,6 @@ pub const SCM = solaris.SCM; pub const SETCONTEXT = solaris.SETCONTEXT; pub const SETUSTACK = solaris.GETUSTACK; pub const SFD = solaris.SFD; -pub const cmsghdr = solaris.cmsghdr; pub const ctid_t = solaris.ctid_t; pub const file_obj = solaris.file_obj; pub const fpregset_t = solaris.fpregset_t; diff --git a/lib/std/c/dragonfly.zig b/lib/std/c/dragonfly.zig index cb33fc1e56495a784f388fd0f7d08a508239ae93..c06d7ab8f5325d314b22133347b29103a82cbc51 100644 --- a/lib/std/c/dragonfly.zig +++ b/lib/std/c/dragonfly.zig @@ -158,12 +158,6 @@ pub const BADSIG = SIG.ERR; pub const sig_t = *const fn (i32) callconv(.c) void; -pub const cmsghdr = extern struct { - len: socklen_t, - level: c_int, - type: c_int, -}; - pub const cmsgcred = extern struct { pid: pid_t, uid: uid_t, diff --git a/lib/std/c/solaris.zig b/lib/std/c/solaris.zig index df7dbca16a645932c2ecc6ce22f630e51f3df71f..91d96527d987ab2f7739106ee4d9fc5e2c7dfd88 100644 --- a/lib/std/c/solaris.zig +++ b/lib/std/c/solaris.zig @@ -31,12 +31,6 @@ pub const poolid_t = id_t; pub const zoneid_t = id_t; pub const ctid_t = id_t; -pub const cmsghdr = extern struct { - len: socklen_t, - level: i32, - type: i32, -}; - pub const SCM = struct { pub const UCRED = 0x1012; pub const RIGHTS = 0x1010; diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 7db0634271346f3976405015562d81906de56947..f5ff7767a8a83d0205c726a71ead0c24921fff65 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -9709,6 +9709,13 @@ pub const msghdr_const = extern struct { flags: u32, }; +// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/socket.h?id=b320789d6883cc00ac78ce83bccbfe7ed58afcf0#n105 +pub const cmsghdr = extern struct { + len: usize, + level: i32, + type: i32, +}; + /// The syscalls, but with Zig error sets, going through libc if linking libc, /// and with some footguns eliminated. pub const wrapped = struct { -- 2.54.0