use nix::errno::Errno; use nix::sys::signal::*; use nix::unistd::*; use std::hash::{Hash, Hasher}; use std::sync::atomic::{AtomicBool, Ordering}; #[cfg(not(target_os = "redox"))] use std::thread;
#[test] fn test_kill_none() {
kill(getpid(), None).expect("Should be able to send signal to myself.");
}
#[test] #[cfg(not(target_os = "fuchsia"))] fn test_killpg_none() {
killpg(getpgrp(), None)
.expect("Should be able to send signal to my process group.");
}
#[test] fn test_old_sigaction_flags() { let _m = crate::SIGNAL_MTX.lock();
extern"C"fn handler(_: ::libc::c_int) {} let act = SigAction::new(
SigHandler::Handler(handler),
SaFlags::empty(),
SigSet::empty(),
); let oact = unsafe { sigaction(SIGINT, &act) }.unwrap(); let _flags = oact.flags(); let oact = unsafe { sigaction(SIGINT, &act) }.unwrap(); let _flags = oact.flags();
}
#[test] fn test_sigprocmask_noop() {
sigprocmask(SigmaskHow::SIG_BLOCK, None, None)
.expect("this should be an effective noop");
}
#[test] fn test_sigprocmask() { let _m = crate::SIGNAL_MTX.lock();
// This needs to be a signal that rust doesn't use in the test harness. const SIGNAL: Signal = Signal::SIGCHLD;
letmut old_signal_set = SigSet::empty();
sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
.expect("expect to be able to retrieve old signals");
// Make sure the old set doesn't contain the signal, otherwise the following // test don't make sense.
assert!(
!old_signal_set.contains(SIGNAL), "the {SIGNAL:?} signal is already blocked, please change to a \
different one"
);
// Now block the signal. letmut signal_set = SigSet::empty();
signal_set.add(SIGNAL);
sigprocmask(SigmaskHow::SIG_BLOCK, Some(&signal_set), None)
.expect("expect to be able to block signals");
// And test it again, to make sure the change was effective.
old_signal_set.clear();
sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
.expect("expect to be able to retrieve old signals");
assert!(
old_signal_set.contains(SIGNAL), "expected the {SIGNAL:?} to be blocked"
);
// Reset the signal.
sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&signal_set), None)
.expect("expect to be able to block signals");
}
// System V based OSes (e.g. illumos and Solaris) always resets the // disposition to SIG_DFL prior to calling the signal handler #[cfg(solarish)]
assert_eq!( unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
SigHandler::SigDfl
);
let all = SigSet::all();
assert!(all.contains(SIGUSR1));
assert!(all.contains(SIGUSR2));
}
#[test] fn test_clear() { letmut 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] #[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!");
#[cfg(any(
bsd,
linux_android,
solarish,
target_os = "haiku",
target_os = "hurd",
target_os = "aix",
target_os = "fuchsia"
))] #[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 letmut 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. letmut 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(); letmut h0 = DefaultHasher::new();
set0.hash(&mut h0);
let set1 = SigSet::empty(); letmut 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(); letmut h0 = DefaultHasher::new();
set0.hash(&mut h0);
let set1 = SigSet::all(); letmut h1 = DefaultHasher::new();
set1.hash(&mut h1);
assert_eq!(h0.finish(), h1.finish());
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-20)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.