• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #[cfg(not(target_os = "redox"))]
2 use nix::errno::Errno;
3 use nix::sys::signal::*;
4 use nix::unistd::*;
5 use std::convert::TryFrom;
6 use std::sync::atomic::{AtomicBool, Ordering};
7 
8 #[test]
test_kill_none()9 fn 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"))]
test_killpg_none()15 fn test_killpg_none() {
16     killpg(getpgrp(), None)
17         .expect("Should be able to send signal to my process group.");
18 }
19 
20 #[test]
test_old_sigaction_flags()21 fn 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]
test_sigprocmask_noop()37 fn test_sigprocmask_noop() {
38     sigprocmask(SigmaskHow::SIG_BLOCK, None, None)
39         .expect("this should be an effective noop");
40 }
41 
42 #[test]
test_sigprocmask()43 fn 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 is already blocked, please change to a \
58              different one",
59         SIGNAL
60     );
61 
62     // Now block the signal.
63     let mut signal_set = SigSet::empty();
64     signal_set.add(SIGNAL);
65     sigprocmask(SigmaskHow::SIG_BLOCK, Some(&signal_set), None)
66         .expect("expect to be able to block signals");
67 
68     // And test it again, to make sure the change was effective.
69     old_signal_set.clear();
70     sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
71         .expect("expect to be able to retrieve old signals");
72     assert!(
73         old_signal_set.contains(SIGNAL),
74         "expected the {:?} to be blocked",
75         SIGNAL
76     );
77 
78     // Reset the signal.
79     sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&signal_set), None)
80         .expect("expect to be able to block signals");
81 }
82 
83 lazy_static! {
84     static ref SIGNALED: AtomicBool = AtomicBool::new(false);
85 }
86 
test_sigaction_handler(signal: libc::c_int)87 extern "C" fn test_sigaction_handler(signal: libc::c_int) {
88     let signal = Signal::try_from(signal).unwrap();
89     SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
90 }
91 
92 #[cfg(not(target_os = "redox"))]
test_sigaction_action( _: libc::c_int, _: *mut libc::siginfo_t, _: *mut libc::c_void, )93 extern "C" fn test_sigaction_action(
94     _: libc::c_int,
95     _: *mut libc::siginfo_t,
96     _: *mut libc::c_void,
97 ) {
98 }
99 
100 #[test]
101 #[cfg(not(target_os = "redox"))]
test_signal_sigaction()102 fn test_signal_sigaction() {
103     let _m = crate::SIGNAL_MTX.lock();
104 
105     let action_handler = SigHandler::SigAction(test_sigaction_action);
106     assert_eq!(
107         unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(),
108         Errno::ENOTSUP
109     );
110 }
111 
112 #[test]
test_signal()113 fn test_signal() {
114     let _m = crate::SIGNAL_MTX.lock();
115 
116     unsafe { signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap();
117     raise(Signal::SIGINT).unwrap();
118     assert_eq!(
119         unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
120         SigHandler::SigIgn
121     );
122 
123     let handler = SigHandler::Handler(test_sigaction_handler);
124     assert_eq!(
125         unsafe { signal(Signal::SIGINT, handler) }.unwrap(),
126         SigHandler::SigDfl
127     );
128     raise(Signal::SIGINT).unwrap();
129     assert!(SIGNALED.load(Ordering::Relaxed));
130 
131     #[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
132     assert_eq!(
133         unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
134         handler
135     );
136 
137     // System V based OSes (e.g. illumos and Solaris) always resets the
138     // disposition to SIG_DFL prior to calling the signal handler
139     #[cfg(any(target_os = "illumos", target_os = "solaris"))]
140     assert_eq!(
141         unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
142         SigHandler::SigDfl
143     );
144 
145     // Restore default signal handler
146     unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap();
147 }
148