authorgravatar for bblack@wikimedia.orgBrandon Black <bblack@wikimedia.org> 2025-09-02 12:20:11-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-03 21:45:03-07:00
log76c62e509b31fa31a537da94966cbd2971dfa79b
tree044897678064354bd51f8dbf11640916b6b8cc4b
parentb1189ab038ad1885f961562bf188f0bd3da12153

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.

4 files changed, 40 insertions(+), 13 deletions(-)

lib/std/c.zig+33-1
...@@ -4171,6 +4171,39 @@ pub const msghdr_const = switch (native_os) {...@@ -4171,6 +4171,39 @@ pub const msghdr_const = switch (native_os) {
4171 },4171 },
4172 else => void,4172 else => void,
4173};4173};
4174pub const cmsghdr = switch (native_os) {
4175 // https://github.com/emscripten-core/emscripten/blob/96371ed7888fc78c040179f4d4faa82a6a07a116/system/lib/libc/musl/include/sys/socket.h#L44
4176 .linux, .emscripten => linux.cmsghdr,
4177 // https://github.com/freebsd/freebsd-src/blob/b197d2abcb6895d78bc9df8404e374397aa44748/sys/sys/socket.h#L492
4178 .freebsd,
4179 // https://github.com/DragonFlyBSD/DragonFlyBSD/blob/107c0518337ba90e7fa49e74845d8d44320c9a6d/sys/sys/socket.h#L452
4180 .dragonfly,
4181 // https://github.com/NetBSD/src/blob/ba8e1774fd9c0c26ecca461c07bc95d9ebb69579/sys/sys/socket.h#L528
4182 .netbsd,
4183 // https://github.com/openbsd/src/blob/master/sys/sys/socket.h#L527
4184 .openbsd,
4185 // https://github.com/kofemann/opensolaris/blob/80192cd83bf665e708269dae856f9145f7190f74/usr/src/uts/common/sys/socket.h#L416
4186 .solaris,
4187 // https://github.com/illumos/illumos-gate/blob/afdf2e523873cb523df379676067bf9785a0f456/usr/src/uts/common/sys/socket.h#L460
4188 .illumos,
4189 // https://github.com/SerenityOS/serenity/blob/4ee360a348a5e2490eeaeeabb3eb19e70dd450eb/Kernel/API/POSIX/sys/socket.h#L68
4190 .serenity,
4191 // https://github.com/haiku/haiku/blob/b54f586058fd6623645512e4631468cede9933b9/headers/posix/sys/socket.h#L132
4192 .haiku,
4193 // https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/socket.h#L1041
4194 .macos,
4195 .driverkit,
4196 .ios,
4197 .tvos,
4198 .visionos,
4199 .watchos,
4200 => extern struct {
4201 len: socklen_t,
4202 level: c_int,
4203 type: c_int,
4204 },
4205 else => void,
4206};
4174pub const nfds_t = switch (native_os) {4207pub const nfds_t = switch (native_os) {
4175 .linux => linux.nfds_t,4208 .linux => linux.nfds_t,
4176 .emscripten => emscripten.nfds_t,4209 .emscripten => emscripten.nfds_t,
...@@ -11010,7 +11043,6 @@ pub const SCM = solaris.SCM;...@@ -11010,7 +11043,6 @@ pub const SCM = solaris.SCM;
11010pub const SETCONTEXT = solaris.SETCONTEXT;11043pub const SETCONTEXT = solaris.SETCONTEXT;
11011pub const SETUSTACK = solaris.GETUSTACK;11044pub const SETUSTACK = solaris.GETUSTACK;
11012pub const SFD = solaris.SFD;11045pub const SFD = solaris.SFD;
11013pub const cmsghdr = solaris.cmsghdr;
11014pub const ctid_t = solaris.ctid_t;11046pub const ctid_t = solaris.ctid_t;
11015pub const file_obj = solaris.file_obj;11047pub const file_obj = solaris.file_obj;
11016pub const fpregset_t = solaris.fpregset_t;11048pub const fpregset_t = solaris.fpregset_t;
lib/std/c/dragonfly.zig-6
...@@ -158,12 +158,6 @@ pub const BADSIG = SIG.ERR;...@@ -158,12 +158,6 @@ pub const BADSIG = SIG.ERR;
158158
159pub const sig_t = *const fn (i32) callconv(.c) void;159pub const sig_t = *const fn (i32) callconv(.c) void;
160160
161pub const cmsghdr = extern struct {
162 len: socklen_t,
163 level: c_int,
164 type: c_int,
165};
166
167pub const cmsgcred = extern struct {161pub const cmsgcred = extern struct {
168 pid: pid_t,162 pid: pid_t,
169 uid: uid_t,163 uid: uid_t,
lib/std/c/solaris.zig-6
...@@ -31,12 +31,6 @@ pub const poolid_t = id_t;...@@ -31,12 +31,6 @@ pub const poolid_t = id_t;
31pub const zoneid_t = id_t;31pub const zoneid_t = id_t;
32pub const ctid_t = id_t;32pub const ctid_t = id_t;
3333
34pub const cmsghdr = extern struct {
35 len: socklen_t,
36 level: i32,
37 type: i32,
38};
39
40pub const SCM = struct {34pub const SCM = struct {
41 pub const UCRED = 0x1012;35 pub const UCRED = 0x1012;
42 pub const RIGHTS = 0x1010;36 pub const RIGHTS = 0x1010;
lib/std/os/linux.zig+7
...@@ -9709,6 +9709,13 @@ pub const msghdr_const = extern struct {...@@ -9709,6 +9709,13 @@ pub const msghdr_const = extern struct {
9709 flags: u32,9709 flags: u32,
9710};9710};
97119711
9712// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/socket.h?id=b320789d6883cc00ac78ce83bccbfe7ed58afcf0#n105
9713pub const cmsghdr = extern struct {
9714 len: usize,
9715 level: i32,
9716 type: i32,
9717};
9718
9712/// The syscalls, but with Zig error sets, going through libc if linking libc,9719/// The syscalls, but with Zig error sets, going through libc if linking libc,
9713/// and with some footguns eliminated.9720/// and with some footguns eliminated.
9714pub const wrapped = struct {9721pub const wrapped = struct {