blob: ab7690ccbb8fcd72fa1731c56ea3d824b1880be0 [file] [log] [blame] [edit]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Utilities for working with signal handlers
use libc::c_int;
use nix::sys::signal::pthread_sigmask;
use nix::sys::signal::sigaction;
use nix::sys::signal::SaFlags;
use nix::sys::signal::SigAction;
use nix::sys::signal::SigHandler;
use nix::sys::signal::SigSet;
use nix::sys::signal::SigmaskHow;
use nix::sys::signal::Signal;
/// Registers `handler` as the signal handler of signum `num`.
///
/// # Safety
///
/// This is considered unsafe because the given handler will be called asynchronously, interrupting
/// whatever the thread was doing and therefore must only do async-signal-safe operations.
pub unsafe fn register_signal_handler(
num: Signal,
handler: extern "C" fn(c_int),
) -> nix::Result<()> {
sigaction(
num,
&SigAction::new(
SigHandler::Handler(handler),
SaFlags::SA_RESTART,
SigSet::empty(),
),
)
.map(|_| ())
}
/// Resets the signal handler of signum `num` back to the default.
pub fn clear_signal_handler(num: Signal) -> nix::Result<()> {
// SAFETY: Reverting to SigDfl is safe, we are not setting a handler.
unsafe {
sigaction(
num,
&SigAction::new(SigHandler::SigDfl, SaFlags::SA_RESTART, SigSet::empty()),
)
.map(|_| ())
}
}
/// Masks given signal.
pub fn block_signal(num: Signal) -> nix::Result<()> {
let mut sigset = SigSet::empty();
sigset.add(num);
pthread_sigmask(SigmaskHow::SIG_BLOCK, Some(&sigset), None)
}
/// Unmasks given signal.
pub fn unblock_signal(num: Signal) -> nix::Result<()> {
let mut sigset = SigSet::empty();
sigset.add(num);
pthread_sigmask(SigmaskHow::SIG_UNBLOCK, Some(&sigset), None)
}