diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
commit | 8dd16259287f58f9273002717ec4d27e97127719 (patch) | |
tree | 3863e62a53829a84037444beab3abd4ed9dfc7d0 /third_party/rust/nix/test/sys/test_signal.rs | |
parent | Releasing progress-linux version 126.0.1-1~progress7.99u1. (diff) | |
download | firefox-8dd16259287f58f9273002717ec4d27e97127719.tar.xz firefox-8dd16259287f58f9273002717ec4d27e97127719.zip |
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/nix/test/sys/test_signal.rs')
-rw-r--r-- | third_party/rust/nix/test/sys/test_signal.rs | 320 |
1 files changed, 316 insertions, 4 deletions
diff --git a/third_party/rust/nix/test/sys/test_signal.rs b/third_party/rust/nix/test/sys/test_signal.rs index ca25ff9ab0..bf607497be 100644 --- a/third_party/rust/nix/test/sys/test_signal.rs +++ b/third_party/rust/nix/test/sys/test_signal.rs @@ -1,9 +1,10 @@ -#[cfg(not(target_os = "redox"))] use nix::errno::Errno; use nix::sys::signal::*; use nix::unistd::*; -use std::convert::TryFrom; +use std::hash::{Hash, Hasher}; use std::sync::atomic::{AtomicBool, Ordering}; +#[cfg(not(target_os = "redox"))] +use std::thread; #[test] fn test_kill_none() { @@ -124,7 +125,7 @@ fn test_signal() { raise(Signal::SIGINT).unwrap(); assert!(SIGNALED.load(Ordering::Relaxed)); - #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] + #[cfg(not(solarish))] assert_eq!( unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), handler @@ -132,7 +133,7 @@ fn test_signal() { // System V based OSes (e.g. illumos and Solaris) always resets the // disposition to SIG_DFL prior to calling the signal handler - #[cfg(any(target_os = "illumos", target_os = "solaris"))] + #[cfg(solarish)] assert_eq!( unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), SigHandler::SigDfl @@ -141,3 +142,314 @@ fn test_signal() { // Restore default signal handler unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(); } + +#[test] +fn test_contains() { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + + assert!(mask.contains(SIGUSR1)); + assert!(!mask.contains(SIGUSR2)); + + let all = SigSet::all(); + assert!(all.contains(SIGUSR1)); + assert!(all.contains(SIGUSR2)); +} + +#[test] +fn test_clear() { + let mut set = SigSet::all(); + set.clear(); + for signal in Signal::iterator() { + assert!(!set.contains(signal)); + } +} + +#[test] +fn test_from_str_round_trips() { + for signal in Signal::iterator() { + assert_eq!(signal.as_ref().parse::<Signal>().unwrap(), signal); + assert_eq!(signal.to_string().parse::<Signal>().unwrap(), signal); + } +} + +#[test] +fn test_from_str_invalid_value() { + let errval = Err(Errno::EINVAL); + assert_eq!("NOSIGNAL".parse::<Signal>(), errval); + assert_eq!("kill".parse::<Signal>(), errval); + assert_eq!("9".parse::<Signal>(), errval); +} + +#[test] +fn test_extend() { + let mut one_signal = SigSet::empty(); + one_signal.add(SIGUSR1); + + let mut two_signals = SigSet::empty(); + two_signals.add(SIGUSR2); + two_signals.extend(&one_signal); + + assert!(two_signals.contains(SIGUSR1)); + assert!(two_signals.contains(SIGUSR2)); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_thread_signal_set_mask() { + thread::spawn(|| { + let prev_mask = SigSet::thread_get_mask() + .expect("Failed to get existing signal mask!"); + + let mut test_mask = prev_mask; + test_mask.add(SIGUSR1); + + test_mask.thread_set_mask().expect("assertion failed"); + let new_mask = + SigSet::thread_get_mask().expect("Failed to get new mask!"); + + assert!(new_mask.contains(SIGUSR1)); + assert!(!new_mask.contains(SIGUSR2)); + + prev_mask + .thread_set_mask() + .expect("Failed to revert signal mask!"); + }) + .join() + .unwrap(); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_thread_signal_block() { + thread::spawn(|| { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + + mask.thread_block().expect("assertion failed"); + + assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1)); + }) + .join() + .unwrap(); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_thread_signal_unblock() { + thread::spawn(|| { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + + mask.thread_unblock().expect("assertion failed"); + + assert!(!SigSet::thread_get_mask().unwrap().contains(SIGUSR1)); + }) + .join() + .unwrap(); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_thread_signal_swap() { + thread::spawn(|| { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + mask.thread_block().unwrap(); + + assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1)); + + let mut mask2 = SigSet::empty(); + mask2.add(SIGUSR2); + + let oldmask = mask2.thread_swap_mask(SigmaskHow::SIG_SETMASK).unwrap(); + + assert!(oldmask.contains(SIGUSR1)); + assert!(!oldmask.contains(SIGUSR2)); + + assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR2)); + }) + .join() + .unwrap(); +} + +#[test] +fn test_from_and_into_iterator() { + let sigset = SigSet::from_iter(vec![Signal::SIGUSR1, Signal::SIGUSR2]); + let signals = sigset.into_iter().collect::<Vec<Signal>>(); + assert_eq!(signals, [Signal::SIGUSR1, Signal::SIGUSR2]); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_sigaction() { + thread::spawn(|| { + extern "C" fn test_sigaction_handler(_: libc::c_int) {} + extern "C" fn test_sigaction_action( + _: libc::c_int, + _: *mut libc::siginfo_t, + _: *mut libc::c_void, + ) { + } + + let handler_sig = SigHandler::Handler(test_sigaction_handler); + + let flags = + SaFlags::SA_ONSTACK | SaFlags::SA_RESTART | SaFlags::SA_SIGINFO; + + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + + let action_sig = SigAction::new(handler_sig, flags, mask); + + assert_eq!( + action_sig.flags(), + SaFlags::SA_ONSTACK | SaFlags::SA_RESTART + ); + assert_eq!(action_sig.handler(), handler_sig); + + mask = action_sig.mask(); + assert!(mask.contains(SIGUSR1)); + assert!(!mask.contains(SIGUSR2)); + + let handler_act = SigHandler::SigAction(test_sigaction_action); + let action_act = SigAction::new(handler_act, flags, mask); + assert_eq!(action_act.handler(), handler_act); + + let action_dfl = SigAction::new(SigHandler::SigDfl, flags, mask); + assert_eq!(action_dfl.handler(), SigHandler::SigDfl); + + let action_ign = SigAction::new(SigHandler::SigIgn, flags, mask); + assert_eq!(action_ign.handler(), SigHandler::SigIgn); + }) + .join() + .unwrap(); +} + +#[test] +#[cfg(not(target_os = "redox"))] +fn test_sigwait() { + thread::spawn(|| { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + mask.add(SIGUSR2); + mask.thread_block().unwrap(); + + raise(SIGUSR1).unwrap(); + assert_eq!(mask.wait().unwrap(), SIGUSR1); + }) + .join() + .unwrap(); +} + +#[cfg(any( + bsd, + linux_android, + solarish, + target_os = "haiku", + target_os = "hurd", + target_os = "aix", + target_os = "fushsia" +))] +#[test] +fn test_sigsuspend() { + // This test change signal handler + let _m = crate::SIGNAL_MTX.lock(); + static SIGNAL_RECIEVED: AtomicBool = AtomicBool::new(false); + extern "C" fn test_sigsuspend_handler(_: libc::c_int) { + assert!(!SIGNAL_RECIEVED.swap(true, Ordering::SeqCst)); + } + thread::spawn(|| { + const SIGNAL: Signal = Signal::SIGUSR1; + + // Add signal mask to this thread + let mut signal_set = SigSet::empty(); + signal_set.add(SIGNAL); + signal_set.thread_block().unwrap(); + + // Set signal handler and save old one. + let act = SigAction::new( + SigHandler::Handler(test_sigsuspend_handler), + SaFlags::empty(), + SigSet::empty(), + ); + let old_act = unsafe { sigaction(SIGNAL, &act) } + .expect("expect to be able to set new action and get old action"); + + raise(SIGNAL).expect("expect be able to send signal"); + // Now `SIGNAL` was sended but it is blocked. + let mut not_wait_set = SigSet::all(); + not_wait_set.remove(SIGNAL); + // signal handler must run in SigSet::suspend() + assert!(!SIGNAL_RECIEVED.load(Ordering::SeqCst)); + not_wait_set.suspend().unwrap(); + assert!(SIGNAL_RECIEVED.load(Ordering::SeqCst)); + + // Restore the signal handler. + unsafe { sigaction(SIGNAL, &old_act) } + .expect("expect to be able to restore old action "); + }) + .join() + .unwrap(); +} + +#[test] +fn test_from_sigset_t_unchecked() { + let src_set = SigSet::empty(); + let set = unsafe { SigSet::from_sigset_t_unchecked(*src_set.as_ref()) }; + + for signal in Signal::iterator() { + assert!(!set.contains(signal)); + } + + let src_set = SigSet::all(); + let set = unsafe { SigSet::from_sigset_t_unchecked(*src_set.as_ref()) }; + + for signal in Signal::iterator() { + assert!(set.contains(signal)); + } +} + +#[test] +fn test_eq_empty() { + let set0 = SigSet::empty(); + let set1 = SigSet::empty(); + assert_eq!(set0, set1); +} + +#[test] +fn test_eq_all() { + let set0 = SigSet::all(); + let set1 = SigSet::all(); + assert_eq!(set0, set1); +} + +#[test] +fn test_hash_empty() { + use std::collections::hash_map::DefaultHasher; + + let set0 = SigSet::empty(); + let mut h0 = DefaultHasher::new(); + set0.hash(&mut h0); + + let set1 = SigSet::empty(); + let mut h1 = DefaultHasher::new(); + set1.hash(&mut h1); + + assert_eq!(h0.finish(), h1.finish()); +} + +#[test] +fn test_hash_all() { + use std::collections::hash_map::DefaultHasher; + + let set0 = SigSet::all(); + let mut h0 = DefaultHasher::new(); + set0.hash(&mut h0); + + let set1 = SigSet::all(); + let mut h1 = DefaultHasher::new(); + set1.hash(&mut h1); + + assert_eq!(h0.finish(), h1.finish()); +} |