1 use std::convert::TryFrom;
2 
3 #[test]
create_signalfd()4 fn create_signalfd() {
5     use nix::sys::{signal::SigSet, signalfd::SignalFd};
6 
7     let mask = SigSet::empty();
8     SignalFd::new(&mask).unwrap();
9 }
10 
11 #[test]
create_signalfd_with_opts()12 fn create_signalfd_with_opts() {
13     use nix::sys::{
14         signal::SigSet,
15         signalfd::{SfdFlags, SignalFd},
16     };
17 
18     let mask = SigSet::empty();
19     SignalFd::with_flags(&mask, SfdFlags::SFD_CLOEXEC | SfdFlags::SFD_NONBLOCK)
20         .unwrap();
21 }
22 
23 #[test]
read_empty_signalfd()24 fn read_empty_signalfd() {
25     use nix::sys::{
26         signal::SigSet,
27         signalfd::{SfdFlags, SignalFd},
28     };
29 
30     let mask = SigSet::empty();
31     let mut fd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
32 
33     let res = fd.read_signal();
34     assert!(res.unwrap().is_none());
35 }
36 
37 #[test]
test_signalfd()38 fn test_signalfd() {
39     use nix::sys::signal::{self, raise, SigSet, Signal};
40     use nix::sys::signalfd::SignalFd;
41 
42     // Grab the mutex for altering signals so we don't interfere with other tests.
43     let _m = crate::SIGNAL_MTX.lock();
44 
45     // Block the SIGUSR1 signal from automatic processing for this thread
46     let mut mask = SigSet::empty();
47     mask.add(signal::SIGUSR1);
48     mask.thread_block().unwrap();
49 
50     let mut fd = SignalFd::new(&mask).unwrap();
51 
52     // Send a SIGUSR1 signal to the current process. Note that this uses `raise` instead of `kill`
53     // because `kill` with `getpid` isn't correct during multi-threaded execution like during a
54     // cargo test session. Instead use `raise` which does the correct thing by default.
55     raise(signal::SIGUSR1).expect("Error: raise(SIGUSR1) failed");
56 
57     // And now catch that same signal.
58     let res = fd.read_signal().unwrap().unwrap();
59     let signo = Signal::try_from(res.ssi_signo as i32).unwrap();
60     assert_eq!(signo, signal::SIGUSR1);
61 }
62 
63 /// Update the signal mask of an already existing signalfd.
64 #[test]
test_signalfd_setmask()65 fn test_signalfd_setmask() {
66     use nix::sys::signal::{self, raise, SigSet, Signal};
67     use nix::sys::signalfd::SignalFd;
68 
69     // Grab the mutex for altering signals so we don't interfere with other tests.
70     let _m = crate::SIGNAL_MTX.lock();
71 
72     // Block the SIGUSR1 signal from automatic processing for this thread
73     let mut mask = SigSet::empty();
74 
75     let mut fd = SignalFd::new(&mask).unwrap();
76 
77     mask.add(signal::SIGUSR1);
78     mask.thread_block().unwrap();
79     fd.set_mask(&mask).unwrap();
80 
81     // Send a SIGUSR1 signal to the current process. Note that this uses `raise` instead of `kill`
82     // because `kill` with `getpid` isn't correct during multi-threaded execution like during a
83     // cargo test session. Instead use `raise` which does the correct thing by default.
84     raise(signal::SIGUSR1).expect("Error: raise(SIGUSR1) failed");
85 
86     // And now catch that same signal.
87     let res = fd.read_signal().unwrap().unwrap();
88     let signo = Signal::try_from(res.ssi_signo as i32).unwrap();
89     assert_eq!(signo, signal::SIGUSR1);
90 }
91