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