use std::{
ops::{Deref, DerefMut},
process::Child,
};
pub fn kill_on_drop(child: Child) -> KillChildOnDrop {
KillChildOnDrop {
child,
gentle: false,
}
}
pub fn kill_gently_on_drop(child: Child) -> KillChildOnDrop {
KillChildOnDrop {
child,
gentle: true,
}
}
#[derive(Debug)]
pub struct KillChildOnDrop {
child: Child,
gentle: bool,
}
impl Drop for KillChildOnDrop {
fn drop(&mut self) {
if self.gentle && cfg!(unix) {
use nix::sys::signal::{self, Signal};
use nix::unistd::Pid;
let pid = Pid::from_raw(self.id().try_into().expect("PID is smaller than i32::MAX"));
let _ = signal::kill(pid, Signal::SIGTERM);
} else {
let _ = self.kill();
}
let _ = self.wait();
}
}
impl Deref for KillChildOnDrop {
type Target = Child;
fn deref(&self) -> &Self::Target {
&self.child
}
}
impl DerefMut for KillChildOnDrop {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.child
}
}