//! OS registration adapter for the shared safe-boundary signal controller. use signal_hook::consts::signal::{SIGINT, SIGTERM}; use signal_hook::SigId; use crate::app::AppError; pub(crate) use hexwork_game::signals::SignalController; pub(crate) struct InstalledSignals { controller: SignalController, registrations: Vec, } impl InstalledSignals { pub(crate) fn install() -> Result { let controller = SignalController::default(); let mut registrations = Vec::with_capacity(2); for signal in [SIGINT, SIGTERM] { match signal_hook::flag::register(signal, controller.pending_flag()) { Ok(id) => registrations.push(id), Err(error) => { for id in registrations { signal_hook::low_level::unregister(id); } return Err(AppError::io("signal-install", format!("failed to register signal {signal}: {error}"))); } } } Ok(Self { controller, registrations }) } pub(crate) fn controller(&self) -> SignalController { self.controller.clone() } } impl Drop for InstalledSignals { fn drop(&mut self) { for id in self.registrations.drain(..) { signal_hook::low_level::unregister(id); } } }