Commit 629cc6cf28

LemonBoy <thatlemon@gmail.com>
2020-12-12 16:44:10
std: Further siginfo refinements
* Define siginfo and sigaction for Darwin * Define sigaction/handler union for maximum libc compatibility * Minor correction to some type definitions
1 parent 1d9b284
lib/std/os/bits/darwin.zig
@@ -124,13 +124,35 @@ pub const timespec = extern struct {
 };
 
 pub const sigset_t = u32;
-pub const empty_sigset = sigset_t(0);
+pub const empty_sigset: sigset_t = 0;
+
+pub const siginfo_t = extern struct {
+    signo: c_int,
+    errno: c_int,
+    code: c_int,
+    pid: pid_t,
+    uid: uid_t,
+    status: c_int,
+    addr: *c_void,
+    value: extern union {
+        int: c_int,
+        ptr: *c_void,
+    },
+    si_band: c_long,
+    _pad: [7]c_ulong,
+};
 
 /// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
 pub const Sigaction = extern struct {
-    handler: fn (c_int) callconv(.C) void,
-    sa_mask: sigset_t,
-    sa_flags: c_int,
+    pub const handler_fn = fn (c_int) callconv(.C) void;
+    pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
+
+    handler: extern union {
+        handler: ?handler_fn,
+        sigaction: ?sigaction_fn,
+    },
+    mask: sigset_t,
+    flags: c_uint,
 };
 
 pub const dirent = extern struct {
lib/std/os/bits/dragonfly.zig
@@ -530,12 +530,16 @@ pub const sigset_t = extern struct {
 };
 pub const sig_atomic_t = c_int;
 pub const Sigaction = extern struct {
-    __sigaction_u: extern union {
-        __sa_handler: ?fn (c_int) callconv(.C) void,
-        __sa_sigaction: ?fn (c_int, [*c]siginfo_t, ?*c_void) callconv(.C) void,
+    pub const handler_fn = fn (c_int) callconv(.C) void;
+    pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
+
+    /// signal handler
+    handler: extern union {
+        handler: ?handler_fn,
+        sigaction: ?sigaction_fn,
     },
-    sa_flags: c_int,
-    sa_mask: sigset_t,
+    flags: c_uint,
+    mask: sigset_t,
 };
 pub const sig_t = [*c]fn (c_int) callconv(.C) void;
 
lib/std/os/bits/freebsd.zig
@@ -742,14 +742,17 @@ pub const SIG_IGN = @intToPtr(fn (i32) callconv(.C) void, 1);
 
 /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
 pub const Sigaction = extern struct {
+    pub const handler_fn = fn (c_int) callconv(.C) void;
+    pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
+
     /// signal handler
-    __sigaction_u: extern union {
-        __sa_handler: fn (i32) callconv(.C) void,
-        __sa_sigaction: fn (i32, *__siginfo, usize) callconv(.C) void,
+    handler: extern union {
+        handler: ?handler_fn,
+        sigaction: ?sigaction_fn,
     },
 
     /// see signal options
-    sa_flags: u32,
+    sa_flags: c_uint,
 
     /// signal mask to apply
     sa_mask: sigset_t,
lib/std/os/bits/linux.zig
@@ -864,27 +864,38 @@ pub const sigset_t = [1024 / 32]u32;
 pub const all_mask: sigset_t = [_]u32{0xffffffff} ** sigset_t.len;
 pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffffffff} ** 30;
 
-pub const k_sigaction = if (is_mips)
-    extern struct {
-        flags: usize,
-        sigaction: ?fn (i32, *const siginfo_t, ?*const c_void) callconv(.C) void,
-        mask: [4]u32,
+pub const k_sigaction = switch (builtin.arch) {
+    .mips, .mipsel => extern struct {
+        flags: c_uint,
+        handler: ?fn (c_int) callconv(.C) void,
+        mask: [4]c_ulong,
         restorer: fn () callconv(.C) void,
-    }
-else
-    extern struct {
-        sigaction: ?fn (i32, *const siginfo_t, ?*const c_void) callconv(.C) void,
-        flags: usize,
+    },
+    .mips64, .mips64el => extern struct {
+        flags: c_uint,
+        handler: ?fn (c_int) callconv(.C) void,
+        mask: [2]c_ulong,
         restorer: fn () callconv(.C) void,
-        mask: [2]u32,
-    };
+    },
+    else => extern struct {
+        handler: ?fn (c_int) callconv(.C) void,
+        flags: c_ulong,
+        restorer: fn () callconv(.C) void,
+        mask: [2]c_uint,
+    },
+};
 
 /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
 pub const Sigaction = extern struct {
-    pub const sigaction_fn = fn (i32, *const siginfo_t, ?*const c_void) callconv(.C) void;
-    sigaction: ?sigaction_fn,
+    pub const handler_fn = fn (c_int) callconv(.C) void;
+    pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
+
+    handler: extern union {
+        handler: ?handler_fn,
+        sigaction: ?sigaction_fn,
+    },
     mask: sigset_t,
-    flags: u32,
+    flags: c_uint,
     restorer: ?fn () callconv(.C) void = null,
 };
 
lib/std/os/bits/netbsd.zig
@@ -716,13 +716,18 @@ pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
 
 /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
 pub const Sigaction = extern struct {
-    pub const sigaction_fn = fn (i32, *siginfo_t, ?*c_void) callconv(.C) void;
+    pub const handler_fn = fn (c_int) callconv(.C) void;
+    pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
+
     /// signal handler
-    sigaction: ?sigaction_fn,
+    handler: extern union {
+        handler: ?handler_fn,
+        sigaction: ?sigaction_fn,
+    },
     /// signal mask to apply
     mask: sigset_t,
     /// signal options
-    flags: u32,
+    flags: c_uint,
 };
 
 pub const sigval_t = extern union {
lib/std/os/bits/openbsd.zig
@@ -753,13 +753,18 @@ pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
 
 /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
 pub const Sigaction = extern struct {
-    pub const sigaction_fn = fn (c_int, *siginfo_t, ?*c_void) callconv(.C) void;
+    pub const handler_fn = fn (c_int) callconv(.C) void;
+    pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void;
+
     /// signal handler
-    sigaction: ?sigaction_fn,
+    handler: extern union {
+        handler: ?handler_fn,
+        sigaction: ?sigaction_fn,
+    },
     /// signal mask to apply
     mask: sigset_t,
     /// signal options
-    flags: c_int,
+    flags: c_uint,
 };
 
 pub const sigval = extern union {
lib/std/os/linux.zig
@@ -869,7 +869,7 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
     if (act) |new| {
         const restorer_fn = if ((new.flags & SA_SIGINFO) != 0) restore_rt else restore;
         ksa = k_sigaction{
-            .sigaction = new.sigaction,
+            .handler = new.handler.handler,
             .flags = new.flags | SA_RESTORER,
             .mask = undefined,
             .restorer = @ptrCast(fn () callconv(.C) void, restorer_fn),
@@ -888,8 +888,8 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
     if (getErrno(result) != 0) return result;
 
     if (oact) |old| {
-        old.sigaction = oldksa.sigaction;
-        old.flags = @truncate(u32, oldksa.flags);
+        old.handler.handler = oldksa.handler;
+        old.flags = @truncate(c_uint, oldksa.flags);
         @memcpy(@ptrCast([*]u8, &old.mask), @ptrCast([*]const u8, &oldksa.mask), mask_size);
     }
 
lib/std/os/test.zig
@@ -662,7 +662,7 @@ test "sigaction" {
     };
 
     var sa = os.Sigaction{
-        .sigaction = S.handler,
+        .handler = .{ .sigaction = S.handler },
         .mask = os.empty_sigset,
         .flags = os.SA_SIGINFO | os.SA_RESETHAND,
     };
@@ -671,7 +671,7 @@ test "sigaction" {
     os.sigaction(os.SIGUSR1, &sa, null);
     // Check that we can read it back correctly.
     os.sigaction(os.SIGUSR1, null, &old_sa);
-    testing.expectEqual(S.handler, old_sa.sigaction.?);
+    testing.expectEqual(S.handler, old_sa.handler.sigaction.?);
     testing.expect((old_sa.flags & os.SA_RESETHAND) != 0);
     // Invoke the handler.
     try os.raise(os.SIGUSR1);
lib/std/debug.zig
@@ -1721,7 +1721,7 @@ pub fn attachSegfaultHandler() void {
         return;
     }
     var act = os.Sigaction{
-        .sigaction = handleSegfaultLinux,
+        .handler = .{ .sigaction = handleSegfaultLinux },
         .mask = os.empty_sigset,
         .flags = (os.SA_SIGINFO | os.SA_RESTART | os.SA_RESETHAND),
     };
@@ -1740,7 +1740,7 @@ fn resetSegfaultHandler() void {
         return;
     }
     var act = os.Sigaction{
-        .sigaction = os.SIG_DFL,
+        .handler = .{ .sigaction = os.SIG_DFL },
         .mask = os.empty_sigset,
         .flags = 0,
     };