#![cfg(unix)]
use super::worktree::kill_process_group;
#[test]
fn process_group_kill_takes_grandchildren() {
use std::io::BufRead;
use std::os::unix::process::CommandExt;
use std::process::{Command, Stdio};
let mut child = Command::new("sh")
.arg("-c")
.arg("sleep 60 2>/dev/null & echo $!; wait")
.process_group(0)
.stdout(Stdio::piped())
.spawn()
.expect("spawn sh");
let mut line = String::new();
std::io::BufReader::new(child.stdout.take().expect("sh stdout"))
.read_line(&mut line)
.expect("read grandchild pid");
let grandchild: i32 = line.trim().parse().expect("grandchild pid");
assert_eq!(
unsafe { libc::kill(grandchild, 0) },
0,
"grandchild should be alive before the kill"
);
kill_process_group(&mut child);
let _ = child.wait();
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(5);
loop {
let rc = unsafe { libc::kill(grandchild, 0) };
if rc == -1 && std::io::Error::last_os_error().raw_os_error() == Some(libc::ESRCH) {
break;
}
assert!(
std::time::Instant::now() < deadline,
"grandchild still alive or unreaped 5s after the process-group kill"
);
std::thread::sleep(std::time::Duration::from_millis(50));
}
}