use std::process::Stdio;
use crate::{Error, Result};
#[cfg(target_os = "macos")]
pub const MACOS_COMMAND_WRAPPER: &str = r#"
exec 3<&0
(
trap '' HUP INT TERM
while IFS= read -r _ <&3; do :; done
kill -KILL -- -1 2>/dev/null
) &
test -n "$!" || exit 125
exec 3<&-
exec "$@" </dev/null
"#;
pub struct ProcessGroupGuard {
id: u32,
armed: bool,
}
impl ProcessGroupGuard {
pub fn new(child: &tokio::process::Child) -> Result<Self> {
let id = child
.id()
.ok_or_else(|| Error::Sandbox("command process ID unavailable".into()))?;
Ok(Self { id, armed: true })
}
pub fn kill(&mut self) {
if self.armed {
let _ = std::process::Command::new("/bin/kill")
.args(["-KILL", "--", &format!("-{}", self.id)])
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();
self.armed = false;
}
}
}
impl Drop for ProcessGroupGuard {
fn drop(&mut self) {
self.kill();
}
}