From a849a33a0453c75cf0e90d504177e60e8d7da7b7 Mon Sep 17 00:00:00 2001 From: Chris Pick Date: Mon, 13 Nov 2023 20:43:23 -0500 Subject: [PATCH] Add `signal_ignore()` and `signal_default()` Provide safe mechanisms to ignore or reset a signal's action to the default. Fixes #587. --- src/sys/signal.rs | 16 ++++++++++++++++ test/sys/test_signal.rs | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index 408471143f..9167452bbd 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -964,6 +964,22 @@ pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result }) } +/// Reset the specified signal to its default action. +/// +/// `signal` can be any signal except `SIGKILL` or `SIGSTOP`. +pub fn signal_default(signal: Signal) -> Result<()> { + // SAFETY: restoring a default handler is safe if the old handler isn't called + unsafe { self::signal(signal, SigHandler::SigDfl) }.map(drop) +} + +/// Ignore the specified signal. +/// +/// `signal` can be any signal except `SIGKILL` or `SIGSTOP`. +pub fn signal_ignore(signal: Signal) -> Result<()> { + // SAFETY: ignoring a signal is safe if the old handler isn't called + unsafe { self::signal(signal, SigHandler::SigIgn) }.map(drop) +} + fn do_pthread_sigmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<*mut libc::sigset_t>) -> Result<()> { diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index ca25ff9ab0..7aa6cf8492 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -141,3 +141,19 @@ fn test_signal() { // Restore default signal handler unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(); } + +#[test] +fn test_safe_signal() { + let _m = crate::SIGNAL_MTX.lock(); + + signal_ignore(SIGINT).unwrap(); + raise(Signal::SIGINT).unwrap(); + + signal_default(SIGINT).unwrap(); + + // Ensure default was restored + assert_eq!( + unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), + SigHandler::SigDfl + ); +}