1 // These tests cannot run as a regular test because cargo would spawn a thread to run it,
2 // failing the signal masking. So we make our own, non-threaded harnessing
3
4 #[cfg(unix)]
main()5 fn main() {
6 for test in self::test::TESTS {
7 test();
8 // reset the signal mask between tests
9 self::test::reset_mask();
10 }
11 }
12
13 #[cfg(not(unix))]
main()14 fn main() {}
15
16 #[cfg(unix)]
17 mod test {
18 extern crate calloop;
19 extern crate nix;
20
21 use std::io;
22 use std::time::Duration;
23
24 use self::calloop::signals::{Signal, Signals};
25 use self::calloop::EventLoop;
26
27 use self::nix::sys::signal::{kill, SigSet};
28 use self::nix::unistd::Pid;
29
30 pub const TESTS: &'static [fn()] = &[single_usr1, usr2_added_afterwards, usr2_signal_removed];
31
reset_mask()32 pub fn reset_mask() {
33 SigSet::empty().thread_set_mask().unwrap();
34 }
35
single_usr1()36 fn single_usr1() {
37 let mut event_loop = EventLoop::new().unwrap();
38
39 let mut signal_received = false;
40
41 let _signal_source = event_loop
42 .handle()
43 .insert_source(
44 Signals::new(&[Signal::SIGUSR1]).unwrap(),
45 move |evt, rcv| {
46 assert!(evt.signal() == Signal::SIGUSR1);
47 *rcv = true;
48 },
49 )
50 .map_err(Into::<io::Error>::into)
51 .unwrap();
52
53 // send ourselves a SIGUSR1
54 kill(Pid::this(), Signal::SIGUSR1).unwrap();
55
56 event_loop
57 .dispatch(Some(Duration::from_millis(10)), &mut signal_received)
58 .unwrap();
59
60 assert!(signal_received);
61 }
62
usr2_added_afterwards()63 fn usr2_added_afterwards() {
64 let mut event_loop = EventLoop::new().unwrap();
65
66 let mut signal_received = None;
67
68 let mut signal_source = event_loop
69 .handle()
70 .insert_source(
71 Signals::new(&[Signal::SIGUSR1]).unwrap(),
72 move |evt, rcv| {
73 *rcv = Some(evt.signal());
74 },
75 )
76 .map_err(Into::<io::Error>::into)
77 .unwrap();
78
79 signal_source.add_signals(&[Signal::SIGUSR2]).unwrap();
80
81 // send ourselves a SIGUSR2
82 kill(Pid::this(), Signal::SIGUSR2).unwrap();
83
84 event_loop
85 .dispatch(Some(Duration::from_millis(10)), &mut signal_received)
86 .unwrap();
87
88 assert_eq!(signal_received, Some(Signal::SIGUSR2));
89 }
90
usr2_signal_removed()91 fn usr2_signal_removed() {
92 let mut event_loop = EventLoop::new().unwrap();
93
94 let mut signal_received = None;
95
96 let mut signal_source = event_loop
97 .handle()
98 .insert_source(
99 Signals::new(&[Signal::SIGUSR1, Signal::SIGUSR2]).unwrap(),
100 move |evt, rcv| {
101 *rcv = Some(evt.signal());
102 },
103 )
104 .map_err(Into::<io::Error>::into)
105 .unwrap();
106
107 signal_source.remove_signals(&[Signal::SIGUSR2]).unwrap();
108
109 // block sigusr2 anyway, to not be killed by it
110 let mut set = SigSet::empty();
111 set.add(Signal::SIGUSR2);
112 set.thread_block().unwrap();
113
114 // send ourselves a SIGUSR2
115 kill(Pid::this(), Signal::SIGUSR2).unwrap();
116
117 event_loop
118 .dispatch(Some(Duration::from_millis(10)), &mut signal_received)
119 .unwrap();
120
121 // we should not have received anything, as we don't listen to SIGUSR2 any more
122 assert!(signal_received.is_none());
123
124 // swap the signals from [SIGUSR1] to [SIGUSR2]
125 signal_source.set_signals(&[Signal::SIGUSR2]).unwrap();
126
127 event_loop
128 .dispatch(Some(Duration::from_millis(10)), &mut signal_received)
129 .unwrap();
130
131 // we should get back the pending SIGUSR2 now
132 assert_eq!(signal_received, Some(Signal::SIGUSR2));
133 }
134 }
135