fix(runtime): reset signal handlers in children

Ignored signals do not get reset on exec.
This allows children to properly suspend when needed.
This commit is contained in:
buffet 2022-09-25 12:17:55 +00:00
parent 78593f1667
commit fe3d05d36b

View file

@ -13,7 +13,8 @@ use nix::{
fcntl::OFlag, fcntl::OFlag,
libc, libc,
sys::{ sys::{
signal, signal::{self, SaFlags, SigAction, SigHandler},
signalfd::SigSet,
wait::{self, WaitPidFlag, WaitStatus}, wait::{self, WaitPidFlag, WaitStatus},
}, },
unistd::{self, Pid}, unistd::{self, Pid},
@ -47,10 +48,20 @@ impl<'a> PreparedCommand<'a> {
cmd.stderr(self.stderr.map_or(Stdio::inherit(), Stdio::from)); cmd.stderr(self.stderr.map_or(Stdio::inherit(), Stdio::from));
cmd.process_group(pgid.as_raw()); cmd.process_group(pgid.as_raw());
if *pgid == Pid::from_raw(0) { {
let pgid = *pgid;
unsafe { unsafe {
cmd.pre_exec(move || { cmd.pre_exec(move || {
let _ = unistd::tcsetpgrp(libc::STDIN_FILENO, unistd::getpid()); if pgid == Pid::from_raw(0) {
let _ = unistd::tcsetpgrp(libc::STDIN_FILENO, unistd::getpid());
}
let default =
SigAction::new(SigHandler::SigDfl, SaFlags::empty(), SigSet::empty());
let _ = signal::sigaction(signal::Signal::SIGTSTP, &default);
let _ = signal::sigaction(signal::Signal::SIGTTOU, &default);
Ok(()) Ok(())
}); });
} }