Commit 8b269f7e18

Andrew Kelley <andrew@ziglang.org>
2025-10-28 00:16:49
std: make signal numbers into an enum
fixes start logic for checking whether IO/POLL exist
1 parent cc751c0
lib/std/Io/Threaded.zig
@@ -75,10 +75,10 @@ const Closure = struct {
             .none, .canceling => {},
             else => |tid| {
                 if (std.Thread.use_pthreads) {
-                    const rc = std.c.pthread_kill(tid.toThreadId(), posix.SIG.IO);
+                    const rc = std.c.pthread_kill(tid.toThreadId(), .IO);
                     if (is_debug) assert(rc == 0);
                 } else if (native_os == .linux) {
-                    _ = std.os.linux.tgkill(std.os.linux.getpid(), @bitCast(tid.toThreadId()), posix.SIG.IO);
+                    _ = std.os.linux.tgkill(std.os.linux.getpid(), @bitCast(tid.toThreadId()), .IO);
                 }
             },
         }
lib/std/os/linux/test.zig
@@ -1,5 +1,7 @@
-const std = @import("../../std.zig");
 const builtin = @import("builtin");
+
+const std = @import("../../std.zig");
+const assert = std.debug.assert;
 const linux = std.os.linux;
 const mem = std.mem;
 const elf = std.elf;
@@ -128,58 +130,32 @@ test "fadvise" {
 }
 
 test "sigset_t" {
-    std.debug.assert(@sizeOf(linux.sigset_t) == (linux.NSIG / 8));
+    const SIG = linux.SIG;
+    assert(@sizeOf(linux.sigset_t) == (linux.NSIG / 8));
 
     var sigset = linux.sigemptyset();
 
     // See that none are set, then set each one, see that they're all set, then
     // remove them all, and then see that none are set.
     for (1..linux.NSIG) |i| {
-        try expectEqual(linux.sigismember(&sigset, @truncate(i)), false);
+        const sig = std.meta.intToEnum(SIG, i) catch continue;
+        try expectEqual(false, linux.sigismember(&sigset, sig));
     }
     for (1..linux.NSIG) |i| {
-        linux.sigaddset(&sigset, @truncate(i));
+        const sig = std.meta.intToEnum(SIG, i) catch continue;
+        linux.sigaddset(&sigset, sig);
     }
     for (1..linux.NSIG) |i| {
-        try expectEqual(linux.sigismember(&sigset, @truncate(i)), true);
+        const sig = std.meta.intToEnum(SIG, i) catch continue;
+        try expectEqual(true, linux.sigismember(&sigset, sig));
     }
     for (1..linux.NSIG) |i| {
-        linux.sigdelset(&sigset, @truncate(i));
+        const sig = std.meta.intToEnum(SIG, i) catch continue;
+        linux.sigdelset(&sigset, sig);
     }
     for (1..linux.NSIG) |i| {
-        try expectEqual(linux.sigismember(&sigset, @truncate(i)), false);
-    }
-
-    // Kernel sigset_t is either 2+ 32-bit values or 1+ 64-bit value(s).
-    const sigset_len = @typeInfo(linux.sigset_t).array.len;
-    const sigset_elemis64 = 64 == @bitSizeOf(@typeInfo(linux.sigset_t).array.child);
-
-    linux.sigaddset(&sigset, 1);
-    try expectEqual(sigset[0], 1);
-    if (sigset_len > 1) {
-        try expectEqual(sigset[1], 0);
-    }
-
-    linux.sigaddset(&sigset, 31);
-    try expectEqual(sigset[0], 0x4000_0001);
-    if (sigset_len > 1) {
-        try expectEqual(sigset[1], 0);
-    }
-
-    linux.sigaddset(&sigset, 36);
-    if (sigset_elemis64) {
-        try expectEqual(sigset[0], 0x8_4000_0001);
-    } else {
-        try expectEqual(sigset[0], 0x4000_0001);
-        try expectEqual(sigset[1], 0x8);
-    }
-
-    linux.sigaddset(&sigset, 64);
-    if (sigset_elemis64) {
-        try expectEqual(sigset[0], 0x8000_0008_4000_0001);
-    } else {
-        try expectEqual(sigset[0], 0x4000_0001);
-        try expectEqual(sigset[1], 0x8000_0008);
+        const sig = std.meta.intToEnum(SIG, i) catch continue;
+        try expectEqual(false, linux.sigismember(&sigset, sig));
     }
 }
 
@@ -187,14 +163,16 @@ test "sigfillset" {
     // unlike the C library, all the signals are set in the kernel-level fillset
     const sigset = linux.sigfillset();
     for (1..linux.NSIG) |i| {
-        try expectEqual(linux.sigismember(&sigset, @truncate(i)), true);
+        const sig = std.meta.intToEnum(linux.SIG, i) catch continue;
+        try expectEqual(true, linux.sigismember(&sigset, sig));
     }
 }
 
 test "sigemptyset" {
     const sigset = linux.sigemptyset();
     for (1..linux.NSIG) |i| {
-        try expectEqual(linux.sigismember(&sigset, @truncate(i)), false);
+        const sig = std.meta.intToEnum(linux.SIG, i) catch continue;
+        try expectEqual(false, linux.sigismember(&sigset, sig));
     }
 }
 
@@ -208,14 +186,14 @@ test "sysinfo" {
 }
 
 comptime {
-    std.debug.assert(128 == @as(u32, @bitCast(linux.FUTEX_OP{ .cmd = @enumFromInt(0), .private = true, .realtime = false })));
-    std.debug.assert(256 == @as(u32, @bitCast(linux.FUTEX_OP{ .cmd = @enumFromInt(0), .private = false, .realtime = true })));
+    assert(128 == @as(u32, @bitCast(linux.FUTEX_OP{ .cmd = @enumFromInt(0), .private = true, .realtime = false })));
+    assert(256 == @as(u32, @bitCast(linux.FUTEX_OP{ .cmd = @enumFromInt(0), .private = false, .realtime = true })));
 
     // Check futex_param4 union is packed correctly
     const param_union = linux.futex_param4{
         .val2 = 0xaabbcc,
     };
-    std.debug.assert(@intFromPtr(param_union.timeout) == 0xaabbcc);
+    assert(@intFromPtr(param_union.timeout) == 0xaabbcc);
 }
 
 test "futex v1" {
@@ -298,8 +276,8 @@ test "futex v1" {
 }
 
 comptime {
-    std.debug.assert(2 == @as(u32, @bitCast(linux.FUTEX2_FLAGS{ .size = .U32, .private = false })));
-    std.debug.assert(128 == @as(u32, @bitCast(linux.FUTEX2_FLAGS{ .size = @enumFromInt(0), .private = true })));
+    assert(2 == @as(u32, @bitCast(linux.FUTEX2_FLAGS{ .size = .U32, .private = false })));
+    assert(128 == @as(u32, @bitCast(linux.FUTEX2_FLAGS{ .size = @enumFromInt(0), .private = true })));
 }
 
 test "futex2_waitv" {
lib/std/os/emscripten.zig
@@ -479,50 +479,7 @@ pub const SHUT = struct {
     pub const RDWR = 2;
 };
 
-pub const SIG = struct {
-    pub const BLOCK = 0;
-    pub const UNBLOCK = 1;
-    pub const SETMASK = 2;
-
-    pub const HUP = 1;
-    pub const INT = 2;
-    pub const QUIT = 3;
-    pub const ILL = 4;
-    pub const TRAP = 5;
-    pub const ABRT = 6;
-    pub const IOT = ABRT;
-    pub const BUS = 7;
-    pub const FPE = 8;
-    pub const KILL = 9;
-    pub const USR1 = 10;
-    pub const SEGV = 11;
-    pub const USR2 = 12;
-    pub const PIPE = 13;
-    pub const ALRM = 14;
-    pub const TERM = 15;
-    pub const STKFLT = 16;
-    pub const CHLD = 17;
-    pub const CONT = 18;
-    pub const STOP = 19;
-    pub const TSTP = 20;
-    pub const TTIN = 21;
-    pub const TTOU = 22;
-    pub const URG = 23;
-    pub const XCPU = 24;
-    pub const XFSZ = 25;
-    pub const VTALRM = 26;
-    pub const PROF = 27;
-    pub const WINCH = 28;
-    pub const IO = 29;
-    pub const POLL = 29;
-    pub const PWR = 30;
-    pub const SYS = 31;
-    pub const UNUSED = SIG.SYS;
-
-    pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(std.math.maxInt(usize));
-    pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
-    pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
-};
+pub const SIG = linux.SIG;
 
 pub const Sigaction = extern struct {
     pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
lib/std/os/linux.zig
@@ -622,7 +622,7 @@ pub fn fork() usize {
     } else if (@hasField(SYS, "fork")) {
         return syscall0(.fork);
     } else {
-        return syscall2(.clone, SIG.CHLD, 0);
+        return syscall2(.clone, @intFromEnum(SIG.CHLD), 0);
     }
 }
 
@@ -1532,16 +1532,16 @@ pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
     return syscall3(.getrandom, @intFromPtr(buf), count, flags);
 }
 
-pub fn kill(pid: pid_t, sig: i32) usize {
-    return syscall2(.kill, @as(usize, @bitCast(@as(isize, pid))), @as(usize, @bitCast(@as(isize, sig))));
+pub fn kill(pid: pid_t, sig: SIG) usize {
+    return syscall2(.kill, @as(usize, @bitCast(@as(isize, pid))), @intFromEnum(sig));
 }
 
-pub fn tkill(tid: pid_t, sig: i32) usize {
-    return syscall2(.tkill, @as(usize, @bitCast(@as(isize, tid))), @as(usize, @bitCast(@as(isize, sig))));
+pub fn tkill(tid: pid_t, sig: SIG) usize {
+    return syscall2(.tkill, @as(usize, @bitCast(@as(isize, tid))), @intFromEnum(sig));
 }
 
-pub fn tgkill(tgid: pid_t, tid: pid_t, sig: i32) usize {
-    return syscall3(.tgkill, @as(usize, @bitCast(@as(isize, tgid))), @as(usize, @bitCast(@as(isize, tid))), @as(usize, @bitCast(@as(isize, sig))));
+pub fn tgkill(tgid: pid_t, tid: pid_t, sig: SIG) usize {
+    return syscall3(.tgkill, @as(usize, @bitCast(@as(isize, tgid))), @as(usize, @bitCast(@as(isize, tid))), @intFromEnum(sig));
 }
 
 pub fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8) usize {
@@ -1923,11 +1923,11 @@ pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?*
     return syscall4(.rt_sigprocmask, flags, @intFromPtr(set), @intFromPtr(oldset), NSIG / 8);
 }
 
-pub fn sigaction(sig: u8, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) usize {
-    assert(sig > 0);
-    assert(sig < NSIG);
-    assert(sig != SIG.KILL);
-    assert(sig != SIG.STOP);
+pub fn sigaction(sig: SIG, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) usize {
+    assert(@intFromEnum(sig) > 0);
+    assert(@intFromEnum(sig) < NSIG);
+    assert(sig != .KILL);
+    assert(sig != .STOP);
 
     var ksa: k_sigaction = undefined;
     var oldksa: k_sigaction = undefined;
@@ -1958,8 +1958,8 @@ pub fn sigaction(sig: u8, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
 
     const result = switch (native_arch) {
         // The sparc version of rt_sigaction needs the restorer function to be passed as an argument too.
-        .sparc, .sparc64 => syscall5(.rt_sigaction, sig, ksa_arg, oldksa_arg, @intFromPtr(ksa.restorer), mask_size),
-        else => syscall4(.rt_sigaction, sig, ksa_arg, oldksa_arg, mask_size),
+        .sparc, .sparc64 => syscall5(.rt_sigaction, @intFromEnum(sig), ksa_arg, oldksa_arg, @intFromPtr(ksa.restorer), mask_size),
+        else => syscall4(.rt_sigaction, @intFromEnum(sig), ksa_arg, oldksa_arg, mask_size),
     };
     if (E.init(result) != .SUCCESS) return result;
 
@@ -2009,27 +2009,27 @@ pub fn sigfillset() sigset_t {
     return [_]SigsetElement{~@as(SigsetElement, 0)} ** sigset_len;
 }
 
-fn sigset_bit_index(sig: usize) struct { word: usize, mask: SigsetElement } {
-    assert(sig > 0);
-    assert(sig < NSIG);
-    const bit = sig - 1;
+fn sigset_bit_index(sig: SIG) struct { word: usize, mask: SigsetElement } {
+    assert(@intFromEnum(sig) > 0);
+    assert(@intFromEnum(sig) < NSIG);
+    const bit = @intFromEnum(sig) - 1;
     return .{
         .word = bit / @bitSizeOf(SigsetElement),
         .mask = @as(SigsetElement, 1) << @truncate(bit % @bitSizeOf(SigsetElement)),
     };
 }
 
-pub fn sigaddset(set: *sigset_t, sig: usize) void {
+pub fn sigaddset(set: *sigset_t, sig: SIG) void {
     const index = sigset_bit_index(sig);
     (set.*)[index.word] |= index.mask;
 }
 
-pub fn sigdelset(set: *sigset_t, sig: usize) void {
+pub fn sigdelset(set: *sigset_t, sig: SIG) void {
     const index = sigset_bit_index(sig);
     (set.*)[index.word] ^= index.mask;
 }
 
-pub fn sigismember(set: *const sigset_t, sig: usize) bool {
+pub fn sigismember(set: *const sigset_t, sig: SIG) bool {
     const index = sigset_bit_index(sig);
     return ((set.*)[index.word] & index.mask) != 0;
 }
@@ -2635,11 +2635,11 @@ pub fn pidfd_getfd(pidfd: fd_t, targetfd: fd_t, flags: u32) usize {
     );
 }
 
-pub fn pidfd_send_signal(pidfd: fd_t, sig: i32, info: ?*siginfo_t, flags: u32) usize {
+pub fn pidfd_send_signal(pidfd: fd_t, sig: SIG, info: ?*siginfo_t, flags: u32) usize {
     return syscall4(
         .pidfd_send_signal,
         @as(usize, @bitCast(@as(isize, pidfd))),
-        @as(usize, @bitCast(@as(isize, sig))),
+        @intFromEnum(sig),
         @intFromPtr(info),
         flags,
     );
@@ -3736,136 +3736,138 @@ pub const SA = if (is_mips) struct {
     pub const RESTORER = 0x04000000;
 };
 
-pub const SIG = if (is_mips) struct {
+pub const SIG = if (is_mips) enum(u32) {
     pub const BLOCK = 1;
     pub const UNBLOCK = 2;
     pub const SETMASK = 3;
 
-    // https://github.com/torvalds/linux/blob/ca91b9500108d4cf083a635c2e11c884d5dd20ea/arch/mips/include/uapi/asm/signal.h#L25
-    pub const HUP = 1;
-    pub const INT = 2;
-    pub const QUIT = 3;
-    pub const ILL = 4;
-    pub const TRAP = 5;
-    pub const ABRT = 6;
-    pub const IOT = ABRT;
-    pub const EMT = 7;
-    pub const FPE = 8;
-    pub const KILL = 9;
-    pub const BUS = 10;
-    pub const SEGV = 11;
-    pub const SYS = 12;
-    pub const PIPE = 13;
-    pub const ALRM = 14;
-    pub const TERM = 15;
-    pub const USR1 = 16;
-    pub const USR2 = 17;
-    pub const CHLD = 18;
-    pub const PWR = 19;
-    pub const WINCH = 20;
-    pub const URG = 21;
-    pub const IO = 22;
-    pub const POLL = IO;
-    pub const STOP = 23;
-    pub const TSTP = 24;
-    pub const CONT = 25;
-    pub const TTIN = 26;
-    pub const TTOU = 27;
-    pub const VTALRM = 28;
-    pub const PROF = 29;
-    pub const XCPU = 30;
-    pub const XFZ = 31;
-
     pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
     pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
     pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
-} else if (is_sparc) struct {
+
+    pub const IOT: SIG = .ABRT;
+    pub const POLL: SIG = .IO;
+
+    // /arch/mips/include/uapi/asm/signal.h#L25
+    HUP = 1,
+    INT = 2,
+    QUIT = 3,
+    ILL = 4,
+    TRAP = 5,
+    ABRT = 6,
+    EMT = 7,
+    FPE = 8,
+    KILL = 9,
+    BUS = 10,
+    SEGV = 11,
+    SYS = 12,
+    PIPE = 13,
+    ALRM = 14,
+    TERM = 15,
+    USR1 = 16,
+    USR2 = 17,
+    CHLD = 18,
+    PWR = 19,
+    WINCH = 20,
+    URG = 21,
+    IO = 22,
+    STOP = 23,
+    TSTP = 24,
+    CONT = 25,
+    TTIN = 26,
+    TTOU = 27,
+    VTALRM = 28,
+    PROF = 29,
+    XCPU = 30,
+    XFZ = 31,
+} else if (is_sparc) enum(u32) {
     pub const BLOCK = 1;
     pub const UNBLOCK = 2;
     pub const SETMASK = 4;
 
-    pub const HUP = 1;
-    pub const INT = 2;
-    pub const QUIT = 3;
-    pub const ILL = 4;
-    pub const TRAP = 5;
-    pub const ABRT = 6;
-    pub const EMT = 7;
-    pub const FPE = 8;
-    pub const KILL = 9;
-    pub const BUS = 10;
-    pub const SEGV = 11;
-    pub const SYS = 12;
-    pub const PIPE = 13;
-    pub const ALRM = 14;
-    pub const TERM = 15;
-    pub const URG = 16;
-    pub const STOP = 17;
-    pub const TSTP = 18;
-    pub const CONT = 19;
-    pub const CHLD = 20;
-    pub const TTIN = 21;
-    pub const TTOU = 22;
-    pub const POLL = 23;
-    pub const XCPU = 24;
-    pub const XFSZ = 25;
-    pub const VTALRM = 26;
-    pub const PROF = 27;
-    pub const WINCH = 28;
-    pub const LOST = 29;
-    pub const USR1 = 30;
-    pub const USR2 = 31;
-    pub const IOT = ABRT;
-    pub const CLD = CHLD;
-    pub const PWR = LOST;
-    pub const IO = SIG.POLL;
-
     pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
     pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
     pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
-} else struct {
+
+    pub const IOT: SIG = .ABRT;
+    pub const CLD: SIG = .CHLD;
+    pub const PWR: SIG = .LOST;
+    pub const POLL: SIG = .IO;
+
+    HUP = 1,
+    INT = 2,
+    QUIT = 3,
+    ILL = 4,
+    TRAP = 5,
+    ABRT = 6,
+    EMT = 7,
+    FPE = 8,
+    KILL = 9,
+    BUS = 10,
+    SEGV = 11,
+    SYS = 12,
+    PIPE = 13,
+    ALRM = 14,
+    TERM = 15,
+    URG = 16,
+    STOP = 17,
+    TSTP = 18,
+    CONT = 19,
+    CHLD = 20,
+    TTIN = 21,
+    TTOU = 22,
+    IO = 23,
+    XCPU = 24,
+    XFSZ = 25,
+    VTALRM = 26,
+    PROF = 27,
+    WINCH = 28,
+    LOST = 29,
+    USR1 = 30,
+    USR2 = 31,
+} else enum(u32) {
     pub const BLOCK = 0;
     pub const UNBLOCK = 1;
     pub const SETMASK = 2;
 
-    pub const HUP = 1;
-    pub const INT = 2;
-    pub const QUIT = 3;
-    pub const ILL = 4;
-    pub const TRAP = 5;
-    pub const ABRT = 6;
-    pub const IOT = ABRT;
-    pub const BUS = 7;
-    pub const FPE = 8;
-    pub const KILL = 9;
-    pub const USR1 = 10;
-    pub const SEGV = 11;
-    pub const USR2 = 12;
-    pub const PIPE = 13;
-    pub const ALRM = 14;
-    pub const TERM = 15;
-    pub const STKFLT = 16;
-    pub const CHLD = 17;
-    pub const CONT = 18;
-    pub const STOP = 19;
-    pub const TSTP = 20;
-    pub const TTIN = 21;
-    pub const TTOU = 22;
-    pub const URG = 23;
-    pub const XCPU = 24;
-    pub const XFSZ = 25;
-    pub const VTALRM = 26;
-    pub const PROF = 27;
-    pub const WINCH = 28;
-    pub const IO = 29;
-    pub const POLL = 29;
-    pub const PWR = 30;
-    pub const SYS = 31;
-    pub const UNUSED = SIG.SYS;
-
     pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
     pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
     pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
+
+    pub const POLL: SIG = .IO;
+    pub const IOT: SIG = .ABRT;
+
+    HUP = 1,
+    INT = 2,
+    QUIT = 3,
+    ILL = 4,
+    TRAP = 5,
+    ABRT = 6,
+    BUS = 7,
+    FPE = 8,
+    KILL = 9,
+    USR1 = 10,
+    SEGV = 11,
+    USR2 = 12,
+    PIPE = 13,
+    ALRM = 14,
+    TERM = 15,
+    STKFLT = 16,
+    CHLD = 17,
+    CONT = 18,
+    STOP = 19,
+    TSTP = 20,
+    TTIN = 21,
+    TTOU = 22,
+    URG = 23,
+    XCPU = 24,
+    XFSZ = 25,
+    VTALRM = 26,
+    PROF = 27,
+    WINCH = 28,
+    IO = 29,
+    PWR = 30,
+    SYS = 31,
 };
 
 pub const kernel_rwf = u32;
@@ -5786,7 +5788,7 @@ pub const TFD = switch (native_arch) {
 };
 
 const k_sigaction_funcs = struct {
-    const handler = ?*align(1) const fn (i32) callconv(.c) void;
+    const handler = ?*align(1) const fn (SIG) callconv(.c) void;
     const restorer = *const fn () callconv(.c) void;
 };
 
@@ -5817,8 +5819,8 @@ pub const k_sigaction = switch (native_arch) {
 ///
 /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
 pub const Sigaction = struct {
-    pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-    pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+    pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+    pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
     handler: extern union {
         handler: ?handler_fn,
@@ -6260,14 +6262,14 @@ const siginfo_fields_union = extern union {
 
 pub const siginfo_t = if (is_mips)
     extern struct {
-        signo: i32,
+        signo: SIG,
         code: i32,
         errno: i32,
         fields: siginfo_fields_union,
     }
 else
     extern struct {
-        signo: i32,
+        signo: SIG,
         errno: i32,
         code: i32,
         fields: siginfo_fields_union,
lib/std/posix/test.zig
@@ -536,14 +536,15 @@ test "sigset empty/full" {
 
     var set: posix.sigset_t = posix.sigemptyset();
     for (1..posix.NSIG) |i| {
-        try expectEqual(false, posix.sigismember(&set, @truncate(i)));
+        const sig = std.meta.intToEnum(posix.SIG, i) catch continue;
+        try expectEqual(false, posix.sigismember(&set, sig));
     }
 
     // The C library can reserve some (unnamed) signals, so can't check the full
     // NSIG set is defined, but just test a couple:
     set = posix.sigfillset();
-    try expectEqual(true, posix.sigismember(&set, @truncate(posix.SIG.CHLD)));
-    try expectEqual(true, posix.sigismember(&set, @truncate(posix.SIG.INT)));
+    try expectEqual(true, posix.sigismember(&set, .CHLD));
+    try expectEqual(true, posix.sigismember(&set, .INT));
 }
 
 // Some signals (i.e., 32 - 34 on glibc/musl) are not allowed to be added to a
@@ -564,25 +565,30 @@ test "sigset add/del" {
     // See that none are set, then set each one, see that they're all set, then
     // remove them all, and then see that none are set.
     for (1..posix.NSIG) |i| {
-        try expectEqual(false, posix.sigismember(&sigset, @truncate(i)));
+        const sig = std.meta.intToEnum(posix.SIG, i) catch continue;
+        try expectEqual(false, posix.sigismember(&sigset, sig));
     }
     for (1..posix.NSIG) |i| {
         if (!reserved_signo(i)) {
-            posix.sigaddset(&sigset, @truncate(i));
+            const sig = std.meta.intToEnum(posix.SIG, i) catch continue;
+            posix.sigaddset(&sigset, sig);
         }
     }
     for (1..posix.NSIG) |i| {
         if (!reserved_signo(i)) {
-            try expectEqual(true, posix.sigismember(&sigset, @truncate(i)));
+            const sig = std.meta.intToEnum(posix.SIG, i) catch continue;
+            try expectEqual(true, posix.sigismember(&sigset, sig));
         }
     }
     for (1..posix.NSIG) |i| {
         if (!reserved_signo(i)) {
-            posix.sigdelset(&sigset, @truncate(i));
+            const sig = std.meta.intToEnum(posix.SIG, i) catch continue;
+            posix.sigdelset(&sigset, sig);
         }
     }
     for (1..posix.NSIG) |i| {
-        try expectEqual(false, posix.sigismember(&sigset, @truncate(i)));
+        const sig = std.meta.intToEnum(posix.SIG, i) catch continue;
+        try expectEqual(false, posix.sigismember(&sigset, sig));
     }
 }
 
lib/std/c.zig
@@ -2587,25 +2587,24 @@ pub const SHUT = switch (native_os) {
 
 /// Signal types
 pub const SIG = switch (native_os) {
-    .linux => linux.SIG,
-    .emscripten => emscripten.SIG,
-    .windows => struct {
+    .linux, .emscripten => linux.SIG,
+    .windows => enum(u32) {
         /// interrupt
-        pub const INT = 2;
+        INT = 2,
         /// illegal instruction - invalid function image
-        pub const ILL = 4;
+        ILL = 4,
         /// floating point exception
-        pub const FPE = 8;
+        FPE = 8,
         /// segment violation
-        pub const SEGV = 11;
+        SEGV = 11,
         /// Software termination signal from kill
-        pub const TERM = 15;
+        TERM = 15,
         /// Ctrl-Break sequence
-        pub const BREAK = 21;
+        BREAK = 21,
         /// abnormal termination triggered by abort call
-        pub const ABRT = 22;
+        ABRT = 22,
         /// SIGABRT compatible with other platforms, same as SIGABRT
-        pub const ABRT_COMPAT = 6;
+        ABRT_COMPAT = 6,
 
         // Signal action codes
         /// default signal action
@@ -2621,7 +2620,7 @@ pub const SIG = switch (native_os) {
         /// Signal error value (returned by signal call on error)
         pub const ERR = -1;
     },
-    .macos, .ios, .tvos, .watchos, .visionos => struct {
+    .macos, .ios, .tvos, .watchos, .visionos => enum(u32) {
         pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
         pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
         pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
@@ -2633,113 +2632,74 @@ pub const SIG = switch (native_os) {
         pub const UNBLOCK = 2;
         /// set specified signal set
         pub const SETMASK = 3;
+
+        pub const IOT: SIG = .ABRT;
+        pub const POLL: SIG = .EMT;
+
         /// hangup
-        pub const HUP = 1;
+        HUP = 1,
         /// interrupt
-        pub const INT = 2;
+        INT = 2,
         /// quit
-        pub const QUIT = 3;
+        QUIT = 3,
         /// illegal instruction (not reset when caught)
-        pub const ILL = 4;
+        ILL = 4,
         /// trace trap (not reset when caught)
-        pub const TRAP = 5;
+        TRAP = 5,
         /// abort()
-        pub const ABRT = 6;
-        /// pollable event ([XSR] generated, not supported)
-        pub const POLL = 7;
-        /// compatibility
-        pub const IOT = ABRT;
+        ABRT = 6,
         /// EMT instruction
-        pub const EMT = 7;
+        EMT = 7,
         /// floating point exception
-        pub const FPE = 8;
+        FPE = 8,
         /// kill (cannot be caught or ignored)
-        pub const KILL = 9;
+        KILL = 9,
         /// bus error
-        pub const BUS = 10;
+        BUS = 10,
         /// segmentation violation
-        pub const SEGV = 11;
+        SEGV = 11,
         /// bad argument to system call
-        pub const SYS = 12;
+        SYS = 12,
         /// write on a pipe with no one to read it
-        pub const PIPE = 13;
+        PIPE = 13,
         /// alarm clock
-        pub const ALRM = 14;
+        ALRM = 14,
         /// software termination signal from kill
-        pub const TERM = 15;
+        TERM = 15,
         /// urgent condition on IO channel
-        pub const URG = 16;
+        URG = 16,
         /// sendable stop signal not from tty
-        pub const STOP = 17;
+        STOP = 17,
         /// stop signal from tty
-        pub const TSTP = 18;
+        TSTP = 18,
         /// continue a stopped process
-        pub const CONT = 19;
+        CONT = 19,
         /// to parent on child stop or exit
-        pub const CHLD = 20;
+        CHLD = 20,
         /// to readers pgrp upon background tty read
-        pub const TTIN = 21;
+        TTIN = 21,
         /// like TTIN for output if (tp->t_local&LTOSTOP)
-        pub const TTOU = 22;
+        TTOU = 22,
         /// input/output possible signal
-        pub const IO = 23;
+        IO = 23,
         /// exceeded CPU time limit
-        pub const XCPU = 24;
+        XCPU = 24,
         /// exceeded file size limit
-        pub const XFSZ = 25;
+        XFSZ = 25,
         /// virtual time alarm
-        pub const VTALRM = 26;
+        VTALRM = 26,
         /// profiling time alarm
-        pub const PROF = 27;
+        PROF = 27,
         /// window size changes
-        pub const WINCH = 28;
+        WINCH = 28,
         /// information request
-        pub const INFO = 29;
+        INFO = 29,
         /// user defined signal 1
-        pub const USR1 = 30;
+        USR1 = 30,
         /// user defined signal 2
-        pub const USR2 = 31;
+        USR2 = 31,
     },
-    .freebsd => struct {
-        pub const HUP = 1;
-        pub const INT = 2;
-        pub const QUIT = 3;
-        pub const ILL = 4;
-        pub const TRAP = 5;
-        pub const ABRT = 6;
-        pub const IOT = ABRT;
-        pub const EMT = 7;
-        pub const FPE = 8;
-        pub const KILL = 9;
-        pub const BUS = 10;
-        pub const SEGV = 11;
-        pub const SYS = 12;
-        pub const PIPE = 13;
-        pub const ALRM = 14;
-        pub const TERM = 15;
-        pub const URG = 16;
-        pub const STOP = 17;
-        pub const TSTP = 18;
-        pub const CONT = 19;
-        pub const CHLD = 20;
-        pub const TTIN = 21;
-        pub const TTOU = 22;
-        pub const IO = 23;
-        pub const XCPU = 24;
-        pub const XFSZ = 25;
-        pub const VTALRM = 26;
-        pub const PROF = 27;
-        pub const WINCH = 28;
-        pub const INFO = 29;
-        pub const USR1 = 30;
-        pub const USR2 = 31;
-        pub const THR = 32;
-        pub const LWP = THR;
-        pub const LIBRT = 33;
-
-        pub const RTMIN = 65;
-        pub const RTMAX = 126;
-
+    .freebsd => enum(u32) {
         pub const BLOCK = 1;
         pub const UNBLOCK = 2;
         pub const SETMASK = 3;
@@ -2763,8 +2723,48 @@ pub const SIG = switch (native_os) {
         pub inline fn VALID(sig: usize) usize {
             return sig <= MAXSIG and sig > 0;
         }
+
+        pub const IOT: SIG = .ABRT;
+        pub const LWP: SIG = .THR;
+
+        pub const RTMIN = 65;
+        pub const RTMAX = 126;
+
+        HUP = 1,
+        INT = 2,
+        QUIT = 3,
+        ILL = 4,
+        TRAP = 5,
+        ABRT = 6,
+        EMT = 7,
+        FPE = 8,
+        KILL = 9,
+        BUS = 10,
+        SEGV = 11,
+        SYS = 12,
+        PIPE = 13,
+        ALRM = 14,
+        TERM = 15,
+        URG = 16,
+        STOP = 17,
+        TSTP = 18,
+        CONT = 19,
+        CHLD = 20,
+        TTIN = 21,
+        TTOU = 22,
+        IO = 23,
+        XCPU = 24,
+        XFSZ = 25,
+        VTALRM = 26,
+        PROF = 27,
+        WINCH = 28,
+        INFO = 29,
+        USR1 = 30,
+        USR2 = 31,
+        THR = 32,
+        LIBRT = 33,
     },
-    .illumos => struct {
+    .illumos => enum(u32) {
         pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
         pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
         pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
@@ -2773,54 +2773,9 @@ pub const SIG = switch (native_os) {
         pub const WORDS = 4;
         pub const MAXSIG = 75;
 
-        pub const SIG_BLOCK = 1;
-        pub const SIG_UNBLOCK = 2;
-        pub const SIG_SETMASK = 3;
-
-        pub const HUP = 1;
-        pub const INT = 2;
-        pub const QUIT = 3;
-        pub const ILL = 4;
-        pub const TRAP = 5;
-        pub const IOT = 6;
-        pub const ABRT = 6;
-        pub const EMT = 7;
-        pub const FPE = 8;
-        pub const KILL = 9;
-        pub const BUS = 10;
-        pub const SEGV = 11;
-        pub const SYS = 12;
-        pub const PIPE = 13;
-        pub const ALRM = 14;
-        pub const TERM = 15;
-        pub const USR1 = 16;
-        pub const USR2 = 17;
-        pub const CLD = 18;
-        pub const CHLD = 18;
-        pub const PWR = 19;
-        pub const WINCH = 20;
-        pub const URG = 21;
-        pub const POLL = 22;
-        pub const IO = .POLL;
-        pub const STOP = 23;
-        pub const TSTP = 24;
-        pub const CONT = 25;
-        pub const TTIN = 26;
-        pub const TTOU = 27;
-        pub const VTALRM = 28;
-        pub const PROF = 29;
-        pub const XCPU = 30;
-        pub const XFSZ = 31;
-        pub const WAITING = 32;
-        pub const LWP = 33;
-        pub const FREEZE = 34;
-        pub const THAW = 35;
-        pub const CANCEL = 36;
-        pub const LOST = 37;
-        pub const XRES = 38;
-        pub const JVM1 = 39;
-        pub const JVM2 = 40;
-        pub const INFO = 41;
+        pub const BLOCK = 1;
+        pub const UNBLOCK = 2;
+        pub const SETMASK = 3;
 
         pub const RTMIN = 42;
         pub const RTMAX = 74;
@@ -2837,8 +2792,54 @@ pub const SIG = switch (native_os) {
         pub inline fn VALID(sig: usize) usize {
             return sig <= MAXSIG and sig > 0;
         }
+
+        pub const POLL: SIG = .IO;
+
+        HUP = 1,
+        INT = 2,
+        QUIT = 3,
+        ILL = 4,
+        TRAP = 5,
+        IOT = 6,
+        ABRT = 6,
+        EMT = 7,
+        FPE = 8,
+        KILL = 9,
+        BUS = 10,
+        SEGV = 11,
+        SYS = 12,
+        PIPE = 13,
+        ALRM = 14,
+        TERM = 15,
+        USR1 = 16,
+        USR2 = 17,
+        CLD = 18,
+        CHLD = 18,
+        PWR = 19,
+        WINCH = 20,
+        URG = 21,
+        IO = 22,
+        STOP = 23,
+        TSTP = 24,
+        CONT = 25,
+        TTIN = 26,
+        TTOU = 27,
+        VTALRM = 28,
+        PROF = 29,
+        XCPU = 30,
+        XFSZ = 31,
+        WAITING = 32,
+        LWP = 33,
+        FREEZE = 34,
+        THAW = 35,
+        CANCEL = 36,
+        LOST = 37,
+        XRES = 38,
+        JVM1 = 39,
+        JVM2 = 40,
+        INFO = 41,
     },
-    .netbsd => struct {
+    .netbsd => enum(u32) {
         pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
         pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
         pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
@@ -2850,40 +2851,6 @@ pub const SIG = switch (native_os) {
         pub const UNBLOCK = 2;
         pub const SETMASK = 3;
 
-        pub const HUP = 1;
-        pub const INT = 2;
-        pub const QUIT = 3;
-        pub const ILL = 4;
-        pub const TRAP = 5;
-        pub const ABRT = 6;
-        pub const IOT = ABRT;
-        pub const EMT = 7;
-        pub const FPE = 8;
-        pub const KILL = 9;
-        pub const BUS = 10;
-        pub const SEGV = 11;
-        pub const SYS = 12;
-        pub const PIPE = 13;
-        pub const ALRM = 14;
-        pub const TERM = 15;
-        pub const URG = 16;
-        pub const STOP = 17;
-        pub const TSTP = 18;
-        pub const CONT = 19;
-        pub const CHLD = 20;
-        pub const TTIN = 21;
-        pub const TTOU = 22;
-        pub const IO = 23;
-        pub const XCPU = 24;
-        pub const XFSZ = 25;
-        pub const VTALRM = 26;
-        pub const PROF = 27;
-        pub const WINCH = 28;
-        pub const INFO = 29;
-        pub const USR1 = 30;
-        pub const USR2 = 31;
-        pub const PWR = 32;
-
         pub const RTMIN = 33;
         pub const RTMAX = 63;
 
@@ -2899,8 +2866,43 @@ pub const SIG = switch (native_os) {
         pub inline fn VALID(sig: usize) usize {
             return sig <= MAXSIG and sig > 0;
         }
+
+        pub const IOT: SIG = .ABRT;
+
+        HUP = 1,
+        INT = 2,
+        QUIT = 3,
+        ILL = 4,
+        TRAP = 5,
+        ABRT = 6,
+        EMT = 7,
+        FPE = 8,
+        KILL = 9,
+        BUS = 10,
+        SEGV = 11,
+        SYS = 12,
+        PIPE = 13,
+        ALRM = 14,
+        TERM = 15,
+        URG = 16,
+        STOP = 17,
+        TSTP = 18,
+        CONT = 19,
+        CHLD = 20,
+        TTIN = 21,
+        TTOU = 22,
+        IO = 23,
+        XCPU = 24,
+        XFSZ = 25,
+        VTALRM = 26,
+        PROF = 27,
+        WINCH = 28,
+        INFO = 29,
+        USR1 = 30,
+        USR2 = 31,
+        PWR = 32,
     },
-    .dragonfly => struct {
+    .dragonfly => enum(u32) {
         pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
         pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
         pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
@@ -2909,137 +2911,140 @@ pub const SIG = switch (native_os) {
         pub const UNBLOCK = 2;
         pub const SETMASK = 3;
 
-        pub const IOT = ABRT;
-        pub const HUP = 1;
-        pub const INT = 2;
-        pub const QUIT = 3;
-        pub const ILL = 4;
-        pub const TRAP = 5;
-        pub const ABRT = 6;
-        pub const EMT = 7;
-        pub const FPE = 8;
-        pub const KILL = 9;
-        pub const BUS = 10;
-        pub const SEGV = 11;
-        pub const SYS = 12;
-        pub const PIPE = 13;
-        pub const ALRM = 14;
-        pub const TERM = 15;
-        pub const URG = 16;
-        pub const STOP = 17;
-        pub const TSTP = 18;
-        pub const CONT = 19;
-        pub const CHLD = 20;
-        pub const TTIN = 21;
-        pub const TTOU = 22;
-        pub const IO = 23;
-        pub const XCPU = 24;
-        pub const XFSZ = 25;
-        pub const VTALRM = 26;
-        pub const PROF = 27;
-        pub const WINCH = 28;
-        pub const INFO = 29;
-        pub const USR1 = 30;
-        pub const USR2 = 31;
-        pub const THR = 32;
-        pub const CKPT = 33;
-        pub const CKPTEXIT = 34;
-
         pub const WORDS = 4;
-    },
-    .haiku => struct {
+
+        pub const IOT: SIG = .ABRT;
+
+        HUP = 1,
+        INT = 2,
+        QUIT = 3,
+        ILL = 4,
+        TRAP = 5,
+        ABRT = 6,
+        EMT = 7,
+        FPE = 8,
+        KILL = 9,
+        BUS = 10,
+        SEGV = 11,
+        SYS = 12,
+        PIPE = 13,
+        ALRM = 14,
+        TERM = 15,
+        URG = 16,
+        STOP = 17,
+        TSTP = 18,
+        CONT = 19,
+        CHLD = 20,
+        TTIN = 21,
+        TTOU = 22,
+        IO = 23,
+        XCPU = 24,
+        XFSZ = 25,
+        VTALRM = 26,
+        PROF = 27,
+        WINCH = 28,
+        INFO = 29,
+        USR1 = 30,
+        USR2 = 31,
+        THR = 32,
+        CKPT = 33,
+        CKPTEXIT = 34,
+    },
+    .haiku => enum(u32) {
         pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
         pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
         pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
 
         pub const HOLD: ?Sigaction.handler_fn = @ptrFromInt(3);
 
-        pub const HUP = 1;
-        pub const INT = 2;
-        pub const QUIT = 3;
-        pub const ILL = 4;
-        pub const CHLD = 5;
-        pub const ABRT = 6;
-        pub const IOT = ABRT;
-        pub const PIPE = 7;
-        pub const FPE = 8;
-        pub const KILL = 9;
-        pub const STOP = 10;
-        pub const SEGV = 11;
-        pub const CONT = 12;
-        pub const TSTP = 13;
-        pub const ALRM = 14;
-        pub const TERM = 15;
-        pub const TTIN = 16;
-        pub const TTOU = 17;
-        pub const USR1 = 18;
-        pub const USR2 = 19;
-        pub const WINCH = 20;
-        pub const KILLTHR = 21;
-        pub const TRAP = 22;
-        pub const POLL = 23;
-        pub const PROF = 24;
-        pub const SYS = 25;
-        pub const URG = 26;
-        pub const VTALRM = 27;
-        pub const XCPU = 28;
-        pub const XFSZ = 29;
-        pub const BUS = 30;
-        pub const RESERVED1 = 31;
-        pub const RESERVED2 = 32;
-
         pub const BLOCK = 1;
         pub const UNBLOCK = 2;
         pub const SETMASK = 3;
+
+        pub const IOT: SIG = .ABRT;
+
+        HUP = 1,
+        INT = 2,
+        QUIT = 3,
+        ILL = 4,
+        CHLD = 5,
+        ABRT = 6,
+        PIPE = 7,
+        FPE = 8,
+        KILL = 9,
+        STOP = 10,
+        SEGV = 11,
+        CONT = 12,
+        TSTP = 13,
+        ALRM = 14,
+        TERM = 15,
+        TTIN = 16,
+        TTOU = 17,
+        USR1 = 18,
+        USR2 = 19,
+        WINCH = 20,
+        KILLTHR = 21,
+        TRAP = 22,
+        POLL = 23,
+        PROF = 24,
+        SYS = 25,
+        URG = 26,
+        VTALRM = 27,
+        XCPU = 28,
+        XFSZ = 29,
+        BUS = 30,
+        RESERVED1 = 31,
+        RESERVED2 = 32,
     },
-    .openbsd => struct {
+    .openbsd => enum(u32) {
         pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
         pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
         pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
         pub const CATCH: ?Sigaction.handler_fn = @ptrFromInt(2);
         pub const HOLD: ?Sigaction.handler_fn = @ptrFromInt(3);
 
-        pub const HUP = 1;
-        pub const INT = 2;
-        pub const QUIT = 3;
-        pub const ILL = 4;
-        pub const TRAP = 5;
-        pub const ABRT = 6;
-        pub const IOT = ABRT;
-        pub const EMT = 7;
-        pub const FPE = 8;
-        pub const KILL = 9;
-        pub const BUS = 10;
-        pub const SEGV = 11;
-        pub const SYS = 12;
-        pub const PIPE = 13;
-        pub const ALRM = 14;
-        pub const TERM = 15;
-        pub const URG = 16;
-        pub const STOP = 17;
-        pub const TSTP = 18;
-        pub const CONT = 19;
-        pub const CHLD = 20;
-        pub const TTIN = 21;
-        pub const TTOU = 22;
-        pub const IO = 23;
-        pub const XCPU = 24;
-        pub const XFSZ = 25;
-        pub const VTALRM = 26;
-        pub const PROF = 27;
-        pub const WINCH = 28;
-        pub const INFO = 29;
-        pub const USR1 = 30;
-        pub const USR2 = 31;
-        pub const PWR = 32;
-
         pub const BLOCK = 1;
         pub const UNBLOCK = 2;
         pub const SETMASK = 3;
+
+        pub const IOT: SIG = .ABRT;
+
+        HUP = 1,
+        INT = 2,
+        QUIT = 3,
+        ILL = 4,
+        TRAP = 5,
+        ABRT = 6,
+        EMT = 7,
+        FPE = 8,
+        KILL = 9,
+        BUS = 10,
+        SEGV = 11,
+        SYS = 12,
+        PIPE = 13,
+        ALRM = 14,
+        TERM = 15,
+        URG = 16,
+        STOP = 17,
+        TSTP = 18,
+        CONT = 19,
+        CHLD = 20,
+        TTIN = 21,
+        TTOU = 22,
+        IO = 23,
+        XCPU = 24,
+        XFSZ = 25,
+        VTALRM = 26,
+        PROF = 27,
+        WINCH = 28,
+        INFO = 29,
+        USR1 = 30,
+        USR2 = 31,
+        PWR = 32,
     },
     // https://github.com/SerenityOS/serenity/blob/046c23f567a17758d762a33bdf04bacbfd088f9f/Kernel/API/POSIX/signal.h
     // https://github.com/SerenityOS/serenity/blob/046c23f567a17758d762a33bdf04bacbfd088f9f/Kernel/API/POSIX/signal_numbers.h
-    .serenity => struct {
+    .serenity => enum(u32) {
         pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
         pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
         pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
@@ -3048,39 +3053,39 @@ pub const SIG = switch (native_os) {
         pub const UNBLOCK = 2;
         pub const SETMASK = 3;
 
-        pub const INVAL = 0;
-        pub const HUP = 1;
-        pub const INT = 2;
-        pub const QUIT = 3;
-        pub const ILL = 4;
-        pub const TRAP = 5;
-        pub const ABRT = 6;
-        pub const BUS = 7;
-        pub const FPE = 8;
-        pub const KILL = 9;
-        pub const USR1 = 10;
-        pub const SEGV = 11;
-        pub const USR2 = 12;
-        pub const PIPE = 13;
-        pub const ALRM = 14;
-        pub const TERM = 15;
-        pub const STKFLT = 16;
-        pub const CHLD = 17;
-        pub const CONT = 18;
-        pub const STOP = 19;
-        pub const TSTP = 20;
-        pub const TTIN = 21;
-        pub const TTOU = 22;
-        pub const URG = 23;
-        pub const XCPU = 24;
-        pub const XFSZ = 25;
-        pub const VTALRM = 26;
-        pub const PROF = 27;
-        pub const WINCH = 28;
-        pub const IO = 29;
-        pub const INFO = 30;
-        pub const SYS = 31;
-        pub const CANCEL = 32;
+        INVAL = 0,
+        HUP = 1,
+        INT = 2,
+        QUIT = 3,
+        ILL = 4,
+        TRAP = 5,
+        ABRT = 6,
+        BUS = 7,
+        FPE = 8,
+        KILL = 9,
+        USR1 = 10,
+        SEGV = 11,
+        USR2 = 12,
+        PIPE = 13,
+        ALRM = 14,
+        TERM = 15,
+        STKFLT = 16,
+        CHLD = 17,
+        CONT = 18,
+        STOP = 19,
+        TSTP = 20,
+        TTIN = 21,
+        TTOU = 22,
+        URG = 23,
+        XCPU = 24,
+        XFSZ = 25,
+        VTALRM = 26,
+        PROF = 27,
+        WINCH = 28,
+        IO = 29,
+        INFO = 30,
+        SYS = 31,
+        CANCEL = 32,
     },
     else => void,
 };
@@ -3117,8 +3122,8 @@ pub const SYS = switch (native_os) {
 
 /// A common format for the Sigaction struct across a variety of Linux flavors.
 const common_linux_Sigaction = extern struct {
-    pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-    pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+    pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+    pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
     handler: extern union {
         handler: ?handler_fn,
@@ -3139,8 +3144,8 @@ pub const Sigaction = switch (native_os) {
         => if (builtin.target.abi.isMusl())
             common_linux_Sigaction
         else if (builtin.target.ptrBitWidth() == 64) extern struct {
-            pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-            pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+            pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+            pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
             flags: c_uint,
             handler: extern union {
@@ -3150,8 +3155,8 @@ pub const Sigaction = switch (native_os) {
             mask: sigset_t,
             restorer: ?*const fn () callconv(.c) void = null,
         } else extern struct {
-            pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-            pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+            pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+            pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
             flags: c_uint,
             handler: extern union {
@@ -3163,8 +3168,8 @@ pub const Sigaction = switch (native_os) {
             __resv: [1]c_int = .{0},
         },
         .s390x => if (builtin.abi == .gnu) extern struct {
-            pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-            pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+            pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+            pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
             handler: extern union {
                 handler: ?handler_fn,
@@ -3179,8 +3184,8 @@ pub const Sigaction = switch (native_os) {
     },
     .emscripten => emscripten.Sigaction,
     .netbsd, .macos, .ios, .tvos, .watchos, .visionos => extern struct {
-        pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-        pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+        pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+        pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
         handler: extern union {
             handler: ?handler_fn,
@@ -3190,8 +3195,8 @@ pub const Sigaction = switch (native_os) {
         flags: c_uint,
     },
     .dragonfly, .freebsd => extern struct {
-        pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-        pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+        pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+        pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
         /// signal handler
         handler: extern union {
@@ -3204,8 +3209,8 @@ pub const Sigaction = switch (native_os) {
         mask: sigset_t,
     },
     .illumos => extern struct {
-        pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-        pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+        pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+        pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
         /// signal options
         flags: c_uint,
@@ -3218,8 +3223,8 @@ pub const Sigaction = switch (native_os) {
         mask: sigset_t,
     },
     .haiku => extern struct {
-        pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-        pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+        pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+        pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
         /// signal handler
         handler: extern union {
@@ -3237,8 +3242,8 @@ pub const Sigaction = switch (native_os) {
         userdata: *allowzero anyopaque = undefined,
     },
     .openbsd => extern struct {
-        pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-        pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+        pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+        pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
         /// signal handler
         handler: extern union {
@@ -3252,8 +3257,8 @@ pub const Sigaction = switch (native_os) {
     },
     // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L39-L46
     .serenity => extern struct {
-        pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
-        pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
+        pub const handler_fn = *align(1) const fn (SIG) callconv(.c) void;
+        pub const sigaction_fn = *const fn (SIG, *const siginfo_t, ?*anyopaque) callconv(.c) void;
 
         handler: extern union {
             handler: ?handler_fn,
@@ -4433,7 +4438,7 @@ pub const siginfo_t = switch (native_os) {
     .linux => linux.siginfo_t,
     .emscripten => emscripten.siginfo_t,
     .driverkit, .macos, .ios, .tvos, .watchos, .visionos => extern struct {
-        signo: c_int,
+        signo: SIG,
         errno: c_int,
         code: c_int,
         pid: pid_t,
@@ -4449,7 +4454,7 @@ pub const siginfo_t = switch (native_os) {
     },
     .freebsd => extern struct {
         // Signal number.
-        signo: c_int,
+        signo: SIG,
         // Errno association.
         errno: c_int,
         /// Signal code.
@@ -4492,7 +4497,7 @@ pub const siginfo_t = switch (native_os) {
         },
     },
     .illumos => extern struct {
-        signo: c_int,
+        signo: SIG,
         code: c_int,
         errno: c_int,
         // 64bit architectures insert 4bytes of padding here, this is done by
@@ -4549,7 +4554,7 @@ pub const siginfo_t = switch (native_os) {
         info: netbsd._ksiginfo,
     },
     .dragonfly => extern struct {
-        signo: c_int,
+        signo: SIG,
         errno: c_int,
         code: c_int,
         pid: c_int,
@@ -4561,7 +4566,7 @@ pub const siginfo_t = switch (native_os) {
         __spare__: [7]c_int,
     },
     .haiku => extern struct {
-        signo: i32,
+        signo: SIG,
         code: i32,
         errno: i32,
 
@@ -4570,7 +4575,7 @@ pub const siginfo_t = switch (native_os) {
         addr: *allowzero anyopaque,
     },
     .openbsd => extern struct {
-        signo: c_int,
+        signo: SIG,
         code: c_int,
         errno: c_int,
         data: extern union {
@@ -4605,7 +4610,7 @@ pub const siginfo_t = switch (native_os) {
     },
     // https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L27-L37
     .serenity => extern struct {
-        signo: c_int,
+        signo: SIG,
         code: c_int,
         errno: c_int,
         pid: pid_t,
@@ -10581,7 +10586,7 @@ pub extern "c" fn lseek(fd: fd_t, offset: off_t, whence: whence_t) off_t;
 pub extern "c" fn open(path: [*:0]const u8, oflag: O, ...) c_int;
 pub extern "c" fn openat(fd: c_int, path: [*:0]const u8, oflag: O, ...) c_int;
 pub extern "c" fn ftruncate(fd: c_int, length: off_t) c_int;
-pub extern "c" fn raise(sig: c_int) c_int;
+pub extern "c" fn raise(sig: SIG) c_int;
 pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;
 pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize;
 pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: off_t) isize;
@@ -10699,7 +10704,7 @@ pub const recvmsg = switch (native_os) {
     else => private.recvmsg,
 };
 
-pub extern "c" fn kill(pid: pid_t, sig: c_int) c_int;
+pub extern "c" fn kill(pid: pid_t, sig: SIG) c_int;
 
 pub extern "c" fn setuid(uid: uid_t) c_int;
 pub extern "c" fn setgid(gid: gid_t) c_int;
@@ -10763,7 +10768,7 @@ pub const pthread_setname_np = switch (native_os) {
 };
 
 pub extern "c" fn pthread_getname_np(thread: pthread_t, name: [*:0]u8, len: usize) c_int;
-pub extern "c" fn pthread_kill(pthread_t, signal: c_int) c_int;
+pub extern "c" fn pthread_kill(pthread_t, signal: SIG) c_int;
 
 pub const pthread_threadid_np = switch (native_os) {
     .macos, .ios, .tvos, .watchos, .visionos => private.pthread_threadid_np,
@@ -11356,12 +11361,12 @@ const private = struct {
     extern "c" fn recvmsg(sockfd: fd_t, msg: *msghdr, flags: u32) isize;
     extern "c" fn sched_yield() c_int;
     extern "c" fn sendfile(out_fd: fd_t, in_fd: fd_t, offset: ?*off_t, count: usize) isize;
-    extern "c" fn sigaction(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;
-    extern "c" fn sigdelset(set: ?*sigset_t, signo: c_int) c_int;
-    extern "c" fn sigaddset(set: ?*sigset_t, signo: c_int) c_int;
+    extern "c" fn sigaction(sig: SIG, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;
+    extern "c" fn sigdelset(set: ?*sigset_t, signo: SIG) c_int;
+    extern "c" fn sigaddset(set: ?*sigset_t, signo: SIG) c_int;
     extern "c" fn sigfillset(set: ?*sigset_t) c_int;
     extern "c" fn sigemptyset(set: ?*sigset_t) c_int;
-    extern "c" fn sigismember(set: ?*const sigset_t, signo: c_int) c_int;
+    extern "c" fn sigismember(set: ?*const sigset_t, signo: SIG) c_int;
     extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
     extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
     extern "c" fn socketpair(domain: c_uint, sock_type: c_uint, protocol: c_uint, sv: *[2]fd_t) c_int;
@@ -11413,7 +11418,7 @@ const private = struct {
     extern "c" fn __libc_thr_yield() c_int;
     extern "c" fn __msync13(addr: *align(page_size) const anyopaque, len: usize, flags: c_int) c_int;
     extern "c" fn __nanosleep50(rqtp: *const timespec, rmtp: ?*timespec) c_int;
-    extern "c" fn __sigaction14(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;
+    extern "c" fn __sigaction14(sig: SIG, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int;
     extern "c" fn __sigemptyset14(set: ?*sigset_t) c_int;
     extern "c" fn __sigfillset14(set: ?*sigset_t) c_int;
     extern "c" fn __sigprocmask14(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
lib/std/debug.zig
@@ -1409,10 +1409,10 @@ pub fn maybeEnableSegfaultHandler() void {
 var windows_segfault_handle: ?windows.HANDLE = null;
 
 pub fn updateSegfaultHandler(act: ?*const posix.Sigaction) void {
-    posix.sigaction(posix.SIG.SEGV, act, null);
-    posix.sigaction(posix.SIG.ILL, act, null);
-    posix.sigaction(posix.SIG.BUS, act, null);
-    posix.sigaction(posix.SIG.FPE, act, null);
+    posix.sigaction(.SEGV, act, null);
+    posix.sigaction(.ILL, act, null);
+    posix.sigaction(.BUS, act, null);
+    posix.sigaction(.FPE, act, null);
 }
 
 /// Attaches a global handler for several signals which, when triggered, prints output to stderr
@@ -1457,7 +1457,7 @@ fn resetSegfaultHandler() void {
     updateSegfaultHandler(&act);
 }
 
-fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.c) noreturn {
+fn handleSegfaultPosix(sig: posix.SIG, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.c) noreturn {
     if (use_trap_panic) @trap();
     const addr: ?usize, const name: []const u8 = info: {
         if (native_os == .linux and native_arch == .x86_64) {
@@ -1469,7 +1469,7 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa
             // for example when reading/writing model-specific registers
             // by executing `rdmsr` or `wrmsr` in user-space (unprivileged mode).
             const SI_KERNEL = 0x80;
-            if (sig == posix.SIG.SEGV and info.code == SI_KERNEL) {
+            if (sig == .SEGV and info.code == SI_KERNEL) {
                 break :info .{ null, "General protection exception" };
             }
         }
@@ -1496,10 +1496,10 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa
             else => comptime unreachable,
         };
         const name = switch (sig) {
-            posix.SIG.SEGV => "Segmentation fault",
-            posix.SIG.ILL => "Illegal instruction",
-            posix.SIG.BUS => "Bus error",
-            posix.SIG.FPE => "Arithmetic exception",
+            .SEGV => "Segmentation fault",
+            .ILL => "Illegal instruction",
+            .BUS => "Bus error",
+            .FPE => "Arithmetic exception",
             else => unreachable,
         };
         break :info .{ addr, name };
lib/std/posix.zig
@@ -708,7 +708,7 @@ pub fn abort() noreturn {
         // for user-defined signal handlers that want to restore some state in
         // some program sections and crash in others.
         // So, the user-installed SIGABRT handler is run, if present.
-        raise(SIG.ABRT) catch {};
+        raise(.ABRT) catch {};
 
         // Disable all signal handlers.
         const filledset = linux.sigfillset();
@@ -728,17 +728,17 @@ pub fn abort() noreturn {
             .mask = sigemptyset(),
             .flags = 0,
         };
-        sigaction(SIG.ABRT, &sigact, null);
+        sigaction(.ABRT, &sigact, null);
 
-        _ = linux.tkill(linux.gettid(), SIG.ABRT);
+        _ = linux.tkill(linux.gettid(), .ABRT);
 
         var sigabrtmask = sigemptyset();
-        sigaddset(&sigabrtmask, SIG.ABRT);
+        sigaddset(&sigabrtmask, .ABRT);
         sigprocmask(SIG.UNBLOCK, &sigabrtmask, null);
 
         // Beyond this point should be unreachable.
         @as(*allowzero volatile u8, @ptrFromInt(0)).* = 0;
-        raise(SIG.KILL) catch {};
+        raise(.KILL) catch {};
         exit(127); // Pid 1 might not be signalled in some containers.
     }
     switch (native_os) {
@@ -749,7 +749,7 @@ pub fn abort() noreturn {
 
 pub const RaiseError = UnexpectedError;
 
-pub fn raise(sig: u8) RaiseError!void {
+pub fn raise(sig: SIG) RaiseError!void {
     if (builtin.link_libc) {
         switch (errno(system.raise(sig))) {
             .SUCCESS => return,
@@ -777,7 +777,7 @@ pub fn raise(sig: u8) RaiseError!void {
 
 pub const KillError = error{ ProcessNotFound, PermissionDenied } || UnexpectedError;
 
-pub fn kill(pid: pid_t, sig: u8) KillError!void {
+pub fn kill(pid: pid_t, sig: SIG) KillError!void {
     switch (errno(system.kill(pid, sig))) {
         .SUCCESS => return,
         .INVAL => unreachable, // invalid signal
@@ -5235,7 +5235,7 @@ pub fn sigemptyset() sigset_t {
     return system.sigemptyset();
 }
 
-pub fn sigaddset(set: *sigset_t, sig: u8) void {
+pub fn sigaddset(set: *sigset_t, sig: SIG) void {
     if (builtin.link_libc) {
         switch (errno(system.sigaddset(set, sig))) {
             .SUCCESS => return,
@@ -5245,7 +5245,7 @@ pub fn sigaddset(set: *sigset_t, sig: u8) void {
     system.sigaddset(set, sig);
 }
 
-pub fn sigdelset(set: *sigset_t, sig: u8) void {
+pub fn sigdelset(set: *sigset_t, sig: SIG) void {
     if (builtin.link_libc) {
         switch (errno(system.sigdelset(set, sig))) {
             .SUCCESS => return,
@@ -5255,7 +5255,7 @@ pub fn sigdelset(set: *sigset_t, sig: u8) void {
     system.sigdelset(set, sig);
 }
 
-pub fn sigismember(set: *const sigset_t, sig: u8) bool {
+pub fn sigismember(set: *const sigset_t, sig: SIG) bool {
     if (builtin.link_libc) {
         const rc = system.sigismember(set, sig);
         switch (errno(rc)) {
@@ -5267,7 +5267,7 @@ pub fn sigismember(set: *const sigset_t, sig: u8) bool {
 }
 
 /// Examine and change a signal action.
-pub fn sigaction(sig: u8, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) void {
+pub fn sigaction(sig: SIG, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) void {
     switch (errno(system.sigaction(sig, act, oact))) {
         .SUCCESS => return,
         // EINVAL means the signal is either invalid or some signal that cannot have its action
lib/std/Progress.zig
@@ -493,7 +493,7 @@ pub fn start(options: Options) Node {
                     .mask = posix.sigemptyset(),
                     .flags = (posix.SA.SIGINFO | posix.SA.RESTART),
                 };
-                posix.sigaction(posix.SIG.WINCH, &act, null);
+                posix.sigaction(.WINCH, &act, null);
             }
 
             if (switch (global_progress.terminal_mode) {
@@ -1535,10 +1535,10 @@ fn maybeUpdateSize(resize_flag: bool) void {
     }
 }
 
-fn handleSigWinch(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.c) void {
+fn handleSigWinch(sig: posix.SIG, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.c) void {
     _ = info;
     _ = ctx_ptr;
-    assert(sig == posix.SIG.WINCH);
+    assert(sig == .WINCH);
     global_progress.redraw_event.set();
 }
 
lib/std/start.zig
@@ -758,45 +758,24 @@ pub fn call_wWinMain() std.os.windows.INT {
 }
 
 fn maybeIgnoreSignals() void {
-    switch (builtin.os.tag) {
-        .linux,
-        .plan9,
-        .illumos,
-        .netbsd,
-        .openbsd,
-        .haiku,
-        .macos,
-        .ios,
-        .watchos,
-        .tvos,
-        .visionos,
-        .dragonfly,
-        .freebsd,
-        .serenity,
-        => {},
-        else => return,
-    }
     const posix = std.posix;
+    if (posix.Sigaction == void) return;
     const act: posix.Sigaction = .{
-        // Set handler to a noop function instead of `SIG.IGN` to prevent
+        // Set handler to a noop function instead of `IGN` to prevent
         // leaking signal disposition to a child process.
         .handler = .{ .handler = noopSigHandler },
         .mask = posix.sigemptyset(),
         .flags = 0,
     };
 
-    if (@hasField(posix.SIG, "POLL") and !std.options.keep_sigpoll)
-        posix.sigaction(posix.SIG.POLL, &act, null);
+    if (@hasField(posix.SIG, "IO") and !std.options.keep_sig_io)
+        posix.sigaction(.IO, &act, null);
 
-    if (@hasField(posix.SIG, "IO") and
-        (!@hasField(posix.SIG, "POLL") or posix.SIG.IO != posix.SIG.POLL) and
-        !std.options.keep_sigio)
-    {
-        posix.sigaction(posix.SIG.IO, &act, null);
-    }
+    if (@hasField(posix.SIG, "POLL") and !std.options.keep_sig_poll)
+        posix.sigaction(.POLL, &act, null);
 
-    if (@hasField(posix.SIG, "PIPE") and !std.options.keep_sigpipe)
-        posix.sigaction(posix.SIG.PIPE, &act, null);
+    if (@hasField(posix.SIG, "PIPE") and !std.options.keep_sig_pipe)
+        posix.sigaction(.PIPE, &act, null);
 }
 
-fn noopSigHandler(_: i32) callconv(.c) void {}
+fn noopSigHandler(_: std.posix.SIG) callconv(.c) void {}
lib/std/std.zig
@@ -144,8 +144,8 @@ pub const Options = struct {
 
     crypto_fork_safety: bool = true,
 
-    keep_sigpoll: bool = false,
-    keep_sigio: bool = false,
+    keep_sig_poll: bool = false,
+    keep_sig_io: bool = false,
 
     /// By default Zig disables SIGPIPE by setting a "no-op" handler for it.  Set this option
     /// to `true` to prevent that.
@@ -158,7 +158,7 @@ pub const Options = struct {
     /// cases it's unclear why the process was terminated.  By capturing SIGPIPE instead, functions that
     /// write to broken pipes will return the EPIPE error (error.BrokenPipe) and the program can handle
     /// it like any other error.
-    keep_sigpipe: bool = false,
+    keep_sig_pipe: bool = false,
 
     /// By default, std.http.Client will support HTTPS connections.  Set this option to `true` to
     /// disable TLS support.
test/standalone/posix/sigaction.zig
@@ -17,12 +17,12 @@ fn test_sigaction() !void {
         return; // https://github.com/ziglang/zig/issues/15381
     }
 
-    const test_signo = std.posix.SIG.URG; // URG only because it is ignored by default in debuggers
+    const test_signo: std.posix.SIG = .URG; // URG only because it is ignored by default in debuggers
 
     const S = struct {
         var handler_called_count: u32 = 0;
 
-        fn handler(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.c) void {
+        fn handler(sig: std.posix.SIG, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.c) void {
             _ = ctx_ptr;
             // Check that we received the correct signal.
             const info_sig = switch (native_os) {
@@ -80,20 +80,18 @@ fn test_sigaction() !void {
 }
 
 fn test_sigset_bits() !void {
-    const NO_SIG: i32 = 0;
-
     const S = struct {
-        var expected_sig: i32 = undefined;
-        var seen_sig: i32 = NO_SIG;
+        var expected_sig: std.posix.SIG = undefined;
+        var seen_sig: ?std.posix.SIG = null;
 
-        fn handler(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.c) void {
+        fn handler(sig: std.posix.SIG, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.c) void {
             _ = ctx_ptr;
 
             const info_sig = switch (native_os) {
                 .netbsd => info.info.signo,
                 else => info.signo,
             };
-            if (seen_sig == NO_SIG and sig == expected_sig and sig == info_sig) {
+            if (seen_sig == null and sig == expected_sig and sig == info_sig) {
                 seen_sig = sig;
             }
         }
@@ -107,11 +105,9 @@ fn test_sigset_bits() !void {
     // big-endian), try sending a blocked signal to make sure the mask matches the
     // signal.  (Send URG and CHLD because they're ignored by default in the
     // debugger, vs. USR1 or other named signals)
-    inline for ([_]i32{ std.posix.SIG.URG, std.posix.SIG.CHLD, 62, 94, 126 }) |test_signo| {
-        if (test_signo >= std.posix.NSIG) continue;
-
+    inline for ([_]std.posix.SIG{ .URG, .CHLD }) |test_signo| {
         S.expected_sig = test_signo;
-        S.seen_sig = NO_SIG;
+        S.seen_sig = null;
 
         const sa: std.posix.Sigaction = .{
             .handler = .{ .sigaction = &S.handler },
@@ -135,14 +131,14 @@ fn test_sigset_bits() !void {
         switch (std.posix.errno(rc)) {
             .SUCCESS => {
                 // See that the signal is blocked, then unblocked
-                try std.testing.expectEqual(NO_SIG, S.seen_sig);
+                try std.testing.expectEqual(null, S.seen_sig);
                 std.posix.sigprocmask(std.posix.SIG.UNBLOCK, &block_one, null);
                 try std.testing.expectEqual(test_signo, S.seen_sig);
             },
             .INVAL => {
                 // Signal won't get delviered.  Just clean up.
                 std.posix.sigprocmask(std.posix.SIG.UNBLOCK, &block_one, null);
-                try std.testing.expectEqual(NO_SIG, S.seen_sig);
+                try std.testing.expectEqual(null, S.seen_sig);
             },
             else => |errno| return std.posix.unexpectedErrno(errno),
         }