use std::io;
use tokio::process::{Child, Command};
#[derive(Debug)]
pub struct EmulatorProcessGroup {
pgid: u32,
}
impl EmulatorProcessGroup {
pub fn spawn(mut cmd: Command) -> io::Result<(Self, Child)> {
unsafe {
cmd.pre_exec(|| {
if libc::setpgid(0, 0) != 0 {
return Err(io::Error::last_os_error());
}
Ok(())
});
}
let child = cmd.spawn()?;
let pgid = child
.id()
.ok_or_else(|| io::Error::other("Child process has no ID"))?;
Ok((Self { pgid }, child))
}
pub fn kill(&self) -> io::Result<()> {
unsafe {
if libc::kill(-(self.pgid as libc::pid_t), libc::SIGTERM) != 0 {
return Err(io::Error::last_os_error());
}
}
Ok(())
}
#[allow(dead_code)]
pub fn pgid(&self) -> u32 {
self.pgid
}
}