@@ -25,3 +25,32 @@ fn test_signalfd() {
2525 let signo = Signal :: try_from ( res. ssi_signo as i32 ) . unwrap ( ) ;
2626 assert_eq ! ( signo, signal:: SIGUSR1 ) ;
2727}
28+
29+ /// Update the signal mask of an already existing signalfd.
30+ #[ test]
31+ fn test_signalfd_setmask ( ) {
32+ use nix:: sys:: signal:: { self , raise, SigSet , Signal } ;
33+ use nix:: sys:: signalfd:: SignalFd ;
34+
35+ // Grab the mutex for altering signals so we don't interfere with other tests.
36+ let _m = crate :: SIGNAL_MTX . lock ( ) ;
37+
38+ // Block the SIGUSR1 signal from automatic processing for this thread
39+ let mut mask = SigSet :: empty ( ) ;
40+
41+ let mut fd = SignalFd :: new ( & mask) . unwrap ( ) ;
42+
43+ mask. add ( signal:: SIGUSR1 ) ;
44+ mask. thread_block ( ) . unwrap ( ) ;
45+ fd. set_mask ( & mask) . unwrap ( ) ;
46+
47+ // Send a SIGUSR1 signal to the current process. Note that this uses `raise` instead of `kill`
48+ // because `kill` with `getpid` isn't correct during multi-threaded execution like during a
49+ // cargo test session. Instead use `raise` which does the correct thing by default.
50+ raise ( signal:: SIGUSR1 ) . expect ( "Error: raise(SIGUSR1) failed" ) ;
51+
52+ // And now catch that same signal.
53+ let res = fd. read_signal ( ) . unwrap ( ) . unwrap ( ) ;
54+ let signo = Signal :: try_from ( res. ssi_signo as i32 ) . unwrap ( ) ;
55+ assert_eq ! ( signo, signal:: SIGUSR1 ) ;
56+ }
0 commit comments