@@ -1745,8 +1745,9 @@ pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?*
1745
1745
return syscall4 (.rt_sigprocmask , flags , @intFromPtr (set ), @intFromPtr (oldset ), NSIG / 8 );
1746
1746
}
1747
1747
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 );
1750
1751
assert (sig != SIG .KILL );
1751
1752
assert (sig != SIG .STOP );
1752
1753
@@ -1755,14 +1756,15 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
1755
1756
const mask_size = @sizeOf (@TypeOf (ksa .mask ));
1756
1757
1757
1758
if (act ) | new | {
1759
+ // Zig needs to install our arch restorer function with any signal handler, so
1760
+ // must copy the Sigaction struct
1758
1761
const restorer_fn = if ((new .flags & SA .SIGINFO ) != 0 ) & restore_rt else & restore ;
1759
1762
ksa = k_sigaction {
1760
1763
.handler = new .handler .handler ,
1761
1764
.flags = new .flags | SA .RESTORER ,
1762
- .mask = undefined ,
1765
+ .mask = new . mask ,
1763
1766
.restorer = @ptrCast (restorer_fn ),
1764
1767
};
1765
- @memcpy (@as ([* ]u8 , @ptrCast (& ksa .mask ))[0.. mask_size ], @as ([* ]const u8 , @ptrCast (& new .mask )));
1766
1768
}
1767
1769
1768
1770
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
1777
1779
1778
1780
if (oact ) | old | {
1779
1781
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 ;
1782
1784
}
1783
1785
1784
1786
return 0 ;
1785
1787
}
1786
1788
1787
1789
const usize_bits = @typeInfo (usize ).int .bits ;
1788
1790
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 ;
1790
1793
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 ;
1792
1798
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 ;
1795
1800
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 ;
1797
1805
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 ;
1799
1808
1800
- fn sigset_bit_index (sig : usize ) struct { word : usize , mask : u32 } {
1809
+ fn sigset_bit_index (sig : usize ) struct { word : usize , mask : SigsetElement } {
1801
1810
assert (sig > 0 );
1802
1811
assert (sig < NSIG );
1803
1812
const bit = sig - 1 ;
1804
- const shift = @as (u5 , @truncate (bit % 32 ));
1805
1813
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 )) ,
1808
1816
};
1809
1817
}
1810
1818
@@ -5479,38 +5487,33 @@ pub const TFD = switch (native_arch) {
5479
5487
},
5480
5488
};
5481
5489
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
-
5486
5490
const k_sigaction_funcs = struct {
5487
5491
const handler = ? * align (1 ) const fn (i32 ) callconv (.c ) void ;
5488
5492
const restorer = * const fn () callconv (.c ) void ;
5489
5493
};
5490
5494
5495
+ /// Kernel sigaction struct, as expected by the `rt_sigaction` syscall. Includes restorer.
5491
5496
pub const k_sigaction = switch (native_arch ) {
5492
- .mips , .mipsel = > extern struct {
5497
+ .mips , .mipsel , .mips64 , .mips64el = > extern struct {
5493
5498
flags : c_uint ,
5494
5499
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 ,
5502
5501
restorer : k_sigaction_funcs.restorer ,
5503
5502
},
5504
5503
else = > extern struct {
5505
5504
handler : k_sigaction_funcs.handler ,
5506
5505
flags : c_ulong ,
5507
5506
restorer : k_sigaction_funcs.restorer ,
5508
- mask : [ 2 ] c_uint ,
5507
+ mask : sigset_t ,
5509
5508
},
5510
5509
};
5511
5510
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
+ ///
5512
5515
/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
5513
- pub const Sigaction = extern struct {
5516
+ pub const Sigaction = struct {
5514
5517
pub const handler_fn = * align (1 ) const fn (i32 ) callconv (.c ) void ;
5515
5518
pub const sigaction_fn = * const fn (i32 , * const siginfo_t , ? * anyopaque ) callconv (.c ) void ;
5516
5519
@@ -5519,8 +5522,10 @@ pub const Sigaction = extern struct {
5519
5522
sigaction : ? sigaction_fn ,
5520
5523
},
5521
5524
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
+ },
5524
5529
};
5525
5530
5526
5531
pub const SFD = struct {
@@ -5900,6 +5905,8 @@ else
5900
5905
size : usize ,
5901
5906
};
5902
5907
5908
+ // Not clear the i32 padding is always correct with 64-bit pointers.
5909
+ // See https://github.com/ziglang/zig/issues/19754
5903
5910
pub const sigval = extern union {
5904
5911
int : i32 ,
5905
5912
ptr : * anyopaque ,
0 commit comments