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.
This commit is contained in:
Brandon Black 2025-09-02 12:20:11 -05:00 committed by Andrew Kelley
parent b1189ab038
commit 76c62e509b
4 changed files with 40 additions and 13 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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 {