1#[cfg(not(target_os = "redox"))]
2use nix::errno::Errno;
3use nix::sys::signal::*;
4use nix::unistd::*;
5use std::convert::TryFrom;
6use std::sync::atomic::{AtomicBool, Ordering};
7
8#[test]
9fn test_kill_none() {
10 kill(getpid(), None).expect("Should be able to send signal to myself.");
11}
12
13#[test]
14#[cfg(not(target_os = "fuchsia"))]
15fn test_killpg_none() {
16 killpg(getpgrp(), None)
17 .expect("Should be able to send signal to my process group.");
18}
19
20#[test]
21fn test_old_sigaction_flags() {
22 let _m = crate::SIGNAL_MTX.lock();
23
24 extern "C" fn handler(_: ::libc::c_int) {}
25 let act = SigAction::new(
26 SigHandler::Handler(handler),
27 SaFlags::empty(),
28 SigSet::empty(),
29 );
30 let oact = unsafe { sigaction(SIGINT, &act) }.unwrap();
31 let _flags = oact.flags();
32 let oact = unsafe { sigaction(SIGINT, &act) }.unwrap();
33 let _flags = oact.flags();
34}
35
36#[test]
37fn test_sigprocmask_noop() {
38 sigprocmask(SigmaskHow::SIG_BLOCK, None, None)
39 .expect("this should be an effective noop");
40}
41
42#[test]
43fn test_sigprocmask() {
44 let _m = crate::SIGNAL_MTX.lock();
45
46 // This needs to be a signal that rust doesn't use in the test harness.
47 const SIGNAL: Signal = Signal::SIGCHLD;
48
49 let mut old_signal_set = SigSet::empty();
50 sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
51 .expect("expect to be able to retrieve old signals");
52
53 // Make sure the old set doesn't contain the signal, otherwise the following
54 // test don't make sense.
55 assert!(
56 !old_signal_set.contains(SIGNAL),
57 "the {SIGNAL:?} signal is already blocked, please change to a \
58 different one"
59 );
60
61 // Now block the signal.
62 let mut signal_set = SigSet::empty();
63 signal_set.add(SIGNAL);
64 sigprocmask(SigmaskHow::SIG_BLOCK, Some(&signal_set), None)
65 .expect("expect to be able to block signals");
66
67 // And test it again, to make sure the change was effective.
68 old_signal_set.clear();
69 sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
70 .expect("expect to be able to retrieve old signals");
71 assert!(
72 old_signal_set.contains(SIGNAL),
73 "expected the {SIGNAL:?} to be blocked"
74 );
75
76 // Reset the signal.
77 sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&signal_set), None)
78 .expect("expect to be able to block signals");
79}
80
81static SIGNALED: AtomicBool = AtomicBool::new(false);
82
83extern "C" fn test_sigaction_handler(signal: libc::c_int) {
84 let signal = Signal::try_from(signal).unwrap();
85 SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
86}
87
88#[cfg(not(target_os = "redox"))]
89extern "C" fn test_sigaction_action(
90 _: libc::c_int,
91 _: *mut libc::siginfo_t,
92 _: *mut libc::c_void,
93) {
94}
95
96#[test]
97#[cfg(not(target_os = "redox"))]
98fn test_signal_sigaction() {
99 let _m = crate::SIGNAL_MTX.lock();
100
101 let action_handler = SigHandler::SigAction(test_sigaction_action);
102 assert_eq!(
103 unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(),
104 Errno::ENOTSUP
105 );
106}
107
108#[test]
109fn test_signal() {
110 let _m = crate::SIGNAL_MTX.lock();
111
112 unsafe { signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap();
113 raise(Signal::SIGINT).unwrap();
114 assert_eq!(
115 unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
116 SigHandler::SigIgn
117 );
118
119 let handler = SigHandler::Handler(test_sigaction_handler);
120 assert_eq!(
121 unsafe { signal(Signal::SIGINT, handler) }.unwrap(),
122 SigHandler::SigDfl
123 );
124 raise(Signal::SIGINT).unwrap();
125 assert!(SIGNALED.load(Ordering::Relaxed));
126
127 #[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
128 assert_eq!(
129 unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
130 handler
131 );
132
133 // System V based OSes (e.g. illumos and Solaris) always resets the
134 // disposition to SIG_DFL prior to calling the signal handler
135 #[cfg(any(target_os = "illumos", target_os = "solaris"))]
136 assert_eq!(
137 unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
138 SigHandler::SigDfl
139 );
140
141 // Restore default signal handler
142 unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap();
143}
144