• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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