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
use std::io::Result;

use nix::sys::signal::{sigprocmask, SigSet, SigmaskHow};
use tokio::process::Command;
#[cfg(feature = "tracing")]
use tracing::trace;

use super::{TokioCommandWrap, TokioCommandWrapper};

/// Wrapper which resets the process signal mask.
///
/// By default a Command on Unix inherits its parent's [signal mask]. However, in some cases this
/// is not what you want. This wrapper resets the command's sigmask by unblocking all signals.
#[derive(Clone, Copy, Debug)]
pub struct ResetSigmask;

impl TokioCommandWrapper for ResetSigmask {
	fn pre_spawn(&mut self, command: &mut Command, _core: &TokioCommandWrap) -> Result<()> {
		unsafe {
			command.pre_exec(|| {
				let mut oldset = SigSet::empty();
				let newset = SigSet::all();

				#[cfg(feature = "tracing")]
				trace!(unblocking=?newset, "resetting process sigmask");

				sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&newset), Some(&mut oldset))?;

				#[cfg(feature = "tracing")]
				trace!(?oldset, "sigmask reset");
				Ok(())
			});
		}
		Ok(())
	}
}