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 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 83lazy_static! { 84 static ref SIGNALED: AtomicBool = AtomicBool::new(false); 85} 86 87extern "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"))] 93extern "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"))] 102fn 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] 113fn 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