Skip to content

Commit

Permalink
Add signal_ignore() and signal_default()
Browse files Browse the repository at this point in the history
Provide safe mechanisms to ignore or reset a signal's action to the
default.

Fixes #587.
  • Loading branch information
Chris Pick committed Nov 14, 2023
1 parent 1ea59c7 commit a849a33
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/sys/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,22 @@ pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler>
})
}

/// 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<()> {
Expand Down
16 changes: 16 additions & 0 deletions test/sys/test_signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
}

0 comments on commit a849a33

Please sign in to comment.