1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
//! An exfiltrator providing the process that caused the signal. //! //! The [`WithOrigin`] is an [`Exfiltrator`][crate::iterator::exfiltrator::Exfiltrator] that //! provides the information about sending process in addition to the signal number, through the //! [`Origin`] type. //! //! See the [`WithOrigin`] example. use libc::{c_int, siginfo_t}; pub use super::raw::Slot; use super::sealed::Exfiltrator; use super::WithRawSiginfo; pub use crate::low_level::siginfo::{Origin, Process}; /// The [`Exfiltrator`][crate::iterator::exfiltrator::Exfiltrator] that produces [`Origin`] of /// signals. /// /// # Examples /// /// ```rust /// # use signal_hook::consts::SIGUSR1; /// # use signal_hook::iterator::SignalsInfo; /// # use signal_hook::iterator::exfiltrator::WithOrigin; /// # /// # fn main() -> Result<(), std::io::Error> { /// // Subscribe to SIGUSR1, with information about the process. /// let mut signals = SignalsInfo::<WithOrigin>::new(&[SIGUSR1])?; /// /// // Send a signal to ourselves. /// let my_pid = unsafe { libc::getpid() }; /// unsafe { libc::kill(my_pid, SIGUSR1) }; /// /// // Grab the signal and look into the details. /// let received = signals.wait().next().unwrap(); /// /// assert_eq!(SIGUSR1, received.signal); /// assert_eq!(my_pid, received.process.unwrap().pid); /// # Ok(()) } /// ``` #[derive(Copy, Clone, Debug, Default)] pub struct WithOrigin(WithRawSiginfo); // Safety: We need to be async-signal-safe. We delegate to other Exfiltrator, which already is and // call a function that promises to be (Origin::extract) unsafe impl Exfiltrator for WithOrigin { type Storage = Slot; type Output = Origin; fn supports_signal(&self, signal: c_int) -> bool { self.0.supports_signal(signal) } fn store(&self, slot: &Slot, signal: c_int, info: &siginfo_t) { self.0.store(slot, signal, info) } fn load(&self, slot: &Self::Storage, signal: c_int) -> Option<Origin> { self.0 .load(slot, signal) .map(|info| unsafe { Origin::extract(&info) }) } fn init(&self, slot: &Self::Storage, signal: c_int) { self.0.init(slot, signal) } }