spawn_wait/
signal.rs

1use signal_hook::iterator::{exfiltrator::SignalOnly, SignalsInfo};
2
3#[derive(Debug)]
4pub struct SignalHandler {
5  pub(crate) signals: SignalsInfo<SignalOnly>,
6  pub(crate) termination_signals: Vec<i32>,
7}
8
9impl Default for SignalHandler {
10  fn default() -> Self {
11    use signal_hook::consts::*;
12    SignalHandler {
13      signals: SignalsInfo::new(&[SIGTERM, SIGINT, SIGCHLD]).unwrap(),
14      termination_signals: vec![SIGTERM, SIGINT],
15    }
16  }
17}
18
19impl SignalHandler {
20  /// Override the default termination signals list.
21  pub fn with_termination_signals(termination_signals: &[i32]) -> Self {
22    let signals = SignalsInfo::new(termination_signals).unwrap();
23    signals.add_signal(signal_hook::consts::SIGCHLD).unwrap();
24    SignalHandler {
25      signals,
26      termination_signals: termination_signals.to_vec(),
27    }
28  }
29
30  pub fn add_termination_signal(&mut self, signal: i32) {
31    self.termination_signals.push(signal);
32    self.signals.add_signal(signal).unwrap();
33  }
34
35  /// Returns true if there are unprocessed termination signals.
36  ///
37  /// This is useful for checking for termination signals in between different
38  /// stages of processing, so that the application responds fast to signals.
39  pub fn termination_pending(&mut self) -> bool {
40    self
41      .signals
42      .pending()
43      .any(|s| self.termination_signals.contains(&s))
44  }
45}