use std::io;
use crate::log::dev_warn;
use super::{SignalNumber, SignalsState, consts::*, set::SignalAction, signal_name};
pub(crate) struct SignalHandler {
signal: SignalNumber,
original_action: SignalAction,
}
impl SignalHandler {
const FORBIDDEN: &'static [SignalNumber] = &[SIGKILL, SIGSTOP];
pub(crate) fn register(
signal: SignalNumber,
behavior: SignalHandlerBehavior,
state: &mut SignalsState,
) -> io::Result<Self> {
if Self::FORBIDDEN.contains(&signal) {
panic!(
"the {} signal action cannot be overridden",
signal_name(signal)
);
}
let action = SignalAction::new(behavior)?;
let original_action = action.register(signal)?;
state.updated(signal)?;
Ok(Self {
signal,
original_action,
})
}
pub(crate) fn forget(self) {
std::mem::forget(self)
}
}
impl Drop for SignalHandler {
#[track_caller]
fn drop(&mut self) {
let signal = self.signal;
if let Err(err) = self.original_action.register(signal) {
dev_warn!(
"cannot restore original action for {}: {err}",
signal_name(signal),
)
}
}
}
pub(crate) enum SignalHandlerBehavior {
Default,
Ignore,
Stream,
StorePending,
}