@@ -1745,8 +1745,9 @@ pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?*
17451745 return syscall4 (.rt_sigprocmask , flags , @intFromPtr (set ), @intFromPtr (oldset ), NSIG / 8 );
17461746}
17471747
1748- pub fn sigaction (sig : u6 , noalias act : ? * const Sigaction , noalias oact : ? * Sigaction ) usize {
1749- assert (sig >= 1 );
1748+ pub fn sigaction (sig : u8 , noalias act : ? * const Sigaction , noalias oact : ? * Sigaction ) usize {
1749+ assert (sig > 0 );
1750+ assert (sig < NSIG );
17501751 assert (sig != SIG .KILL );
17511752 assert (sig != SIG .STOP );
17521753
@@ -1755,14 +1756,15 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
17551756 const mask_size = @sizeOf (@TypeOf (ksa .mask ));
17561757
17571758 if (act ) | new | {
1759+ // Zig needs to install our arch restorer function with any signal handler, so
1760+ // must copy the Sigaction struct
17581761 const restorer_fn = if ((new .flags & SA .SIGINFO ) != 0 ) & restore_rt else & restore ;
17591762 ksa = k_sigaction {
17601763 .handler = new .handler .handler ,
17611764 .flags = new .flags | SA .RESTORER ,
1762- .mask = undefined ,
1765+ .mask = new . mask ,
17631766 .restorer = @ptrCast (restorer_fn ),
17641767 };
1765- @memcpy (@as ([* ]u8 , @ptrCast (& ksa .mask ))[0.. mask_size ], @as ([* ]const u8 , @ptrCast (& new .mask )));
17661768 }
17671769
17681770 const ksa_arg = if (act != null ) @intFromPtr (& ksa ) else 0 ;
@@ -1777,34 +1779,40 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
17771779
17781780 if (oact ) | old | {
17791781 old .handler .handler = oldksa .handler ;
1780- old .flags = @as ( c_uint , @truncate ( oldksa .flags )) ;
1781- @memcpy ( @as ([ * ] u8 , @ptrCast ( & old .mask ))[0 .. mask_size ], @as ([ * ] const u8 , @ptrCast ( & oldksa .mask ))) ;
1782+ old .flags = oldksa .flags ;
1783+ old .mask = oldksa .mask ;
17821784 }
17831785
17841786 return 0 ;
17851787}
17861788
17871789const usize_bits = @typeInfo (usize ).int .bits ;
17881790
1789- pub const sigset_t = [1024 / 32 ]u32 ;
1791+ /// Defined as one greater than the largest defined signal number.
1792+ pub const NSIG = if (is_mips ) 128 else 65 ;
17901793
1791- const sigset_len = @typeInfo (sigset_t ).array .len ;
1794+ /// Linux kernel's sigset_t. This is logically 64-bit on most
1795+ /// architectures, but 128-bit on MIPS. Contrast with the 1024-bit
1796+ /// sigset_t exported by the glibc and musl library ABIs.
1797+ pub const sigset_t = [(NSIG - 1 + 7 ) / @bitSizeOf (SigsetElement )]SigsetElement ;
17921798
1793- /// Empty set to initialize sigset_t instances from.
1794- pub const empty_sigset : sigset_t = [_ ]u32 {0 } ** sigset_len ;
1799+ const SigsetElement = c_ulong ;
17951800
1796- pub const filled_sigset : sigset_t = [_ ]u32 {0x7fff_ffff } ++ [_ ]u32 {0 } ** (sigset_len - 1 );
1801+ const sigset_len = @typeInfo (sigset_t ).array .len ;
1802+
1803+ /// Empty set to initialize sigset_t instances from. No need for `sigemptyset`.
1804+ pub const empty_sigset : sigset_t = [_ ]SigsetElement {0 } ** sigset_len ;
17971805
1798- pub const all_mask : sigset_t = [_ ]u32 {0xffff_ffff } ** sigset_len ;
1806+ /// Filled set to initialize sigset_t instances from. No need for `sigfillset`.
1807+ pub const filled_sigset : sigset_t = [_ ]SigsetElement {~ @as (SigsetElement , 0 )} ** sigset_len ;
17991808
1800- fn sigset_bit_index (sig : usize ) struct { word : usize , mask : u32 } {
1809+ fn sigset_bit_index (sig : usize ) struct { word : usize , mask : SigsetElement } {
18011810 assert (sig > 0 );
18021811 assert (sig < NSIG );
18031812 const bit = sig - 1 ;
1804- const shift = @as (u5 , @truncate (bit % 32 ));
18051813 return .{
1806- .word = bit / 32 ,
1807- .mask = @as (u32 , 1 ) << shift ,
1814+ .word = bit / @bitSizeOf ( SigsetElement ) ,
1815+ .mask = @as (SigsetElement , 1 ) << @truncate ( bit % @bitSizeOf ( SigsetElement )) ,
18081816 };
18091817}
18101818
@@ -5479,38 +5487,33 @@ pub const TFD = switch (native_arch) {
54795487 },
54805488};
54815489
5482- /// NSIG is the total number of signals defined.
5483- /// As signal numbers are sequential, NSIG is one greater than the largest defined signal number.
5484- pub const NSIG = if (is_mips ) 128 else 65 ;
5485-
54865490const k_sigaction_funcs = struct {
54875491 const handler = ? * align (1 ) const fn (i32 ) callconv (.c ) void ;
54885492 const restorer = * const fn () callconv (.c ) void ;
54895493};
54905494
5495+ /// Kernel sigaction struct, as expected by the `rt_sigaction` syscall. Includes restorer.
54915496pub const k_sigaction = switch (native_arch ) {
5492- .mips , .mipsel = > extern struct {
5497+ .mips , .mipsel , .mips64 , .mips64el = > extern struct {
54935498 flags : c_uint ,
54945499 handler : k_sigaction_funcs.handler ,
5495- mask : [4 ]c_ulong ,
5496- restorer : k_sigaction_funcs.restorer ,
5497- },
5498- .mips64 , .mips64el = > extern struct {
5499- flags : c_uint ,
5500- handler : k_sigaction_funcs.handler ,
5501- mask : [2 ]c_ulong ,
5500+ mask : sigset_t ,
55025501 restorer : k_sigaction_funcs.restorer ,
55035502 },
55045503 else = > extern struct {
55055504 handler : k_sigaction_funcs.handler ,
55065505 flags : c_ulong ,
55075506 restorer : k_sigaction_funcs.restorer ,
5508- mask : [ 2 ] c_uint ,
5507+ mask : sigset_t ,
55095508 },
55105509};
55115510
5511+ /// Kernel Sigaction wrapper for the actual ABI `k_sigaction`. The Zig
5512+ /// linux.zig wrapper library still does some pre-processing on
5513+ /// sigaction() calls (to add the `restorer` field).
5514+ ///
55125515/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
5513- pub const Sigaction = extern struct {
5516+ pub const Sigaction = struct {
55145517 pub const handler_fn = * align (1 ) const fn (i32 ) callconv (.c ) void ;
55155518 pub const sigaction_fn = * const fn (i32 , * const siginfo_t , ? * anyopaque ) callconv (.c ) void ;
55165519
@@ -5519,8 +5522,10 @@ pub const Sigaction = extern struct {
55195522 sigaction : ? sigaction_fn ,
55205523 },
55215524 mask : sigset_t ,
5522- flags : c_uint ,
5523- restorer : ? * const fn () callconv (.c ) void = null ,
5525+ flags : switch (native_arch ) {
5526+ .mips , .mipsel , .mips64 , .mips64el = > c_uint ,
5527+ else = > c_ulong ,
5528+ },
55245529};
55255530
55265531pub const SFD = struct {
0 commit comments