2021-10-08 16:18:33 -07:00
|
|
|
use std::{io, process::Child};
|
2019-07-01 14:08:30 -07:00
|
|
|
|
|
|
|
fn kill_process(process: &mut Child) -> Result<(), io::Error> {
|
|
|
|
if let Ok(()) = process.kill() {
|
|
|
|
process.wait()?;
|
|
|
|
} else {
|
|
|
|
println!("Process {} has already exited", process.id());
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(windows)]
|
|
|
|
pub fn stop_process(process: &mut Child) -> Result<(), io::Error> {
|
|
|
|
kill_process(process)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(windows))]
|
|
|
|
pub fn stop_process(process: &mut Child) -> Result<(), io::Error> {
|
2021-10-08 16:18:33 -07:00
|
|
|
use {
|
|
|
|
nix::{
|
|
|
|
errno::Errno::{EINVAL, EPERM, ESRCH},
|
|
|
|
sys::signal::{kill, Signal},
|
|
|
|
unistd::Pid,
|
|
|
|
},
|
|
|
|
std::{
|
|
|
|
io::ErrorKind,
|
|
|
|
thread,
|
|
|
|
time::{Duration, Instant},
|
|
|
|
},
|
|
|
|
};
|
2019-07-01 14:08:30 -07:00
|
|
|
|
|
|
|
let nice_wait = Duration::from_secs(5);
|
|
|
|
let pid = Pid::from_raw(process.id() as i32);
|
|
|
|
match kill(pid, Signal::SIGINT) {
|
|
|
|
Ok(()) => {
|
|
|
|
let expire = Instant::now() + nice_wait;
|
|
|
|
while let Ok(None) = process.try_wait() {
|
|
|
|
if Instant::now() > expire {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
thread::sleep(nice_wait / 10);
|
|
|
|
}
|
|
|
|
if let Ok(None) = process.try_wait() {
|
|
|
|
kill_process(process)?;
|
|
|
|
}
|
|
|
|
}
|
2021-10-08 16:18:33 -07:00
|
|
|
Err(EINVAL) => {
|
2022-12-06 06:30:06 -08:00
|
|
|
println!("Invalid signal. Killing process {pid}");
|
2019-07-01 14:08:30 -07:00
|
|
|
kill_process(process)?;
|
|
|
|
}
|
2021-10-08 16:18:33 -07:00
|
|
|
Err(EPERM) => {
|
2019-07-01 14:08:30 -07:00
|
|
|
return Err(io::Error::new(
|
|
|
|
ErrorKind::InvalidInput,
|
2022-12-06 06:30:06 -08:00
|
|
|
format!("Insufficient permissions to signal process {pid}"),
|
2019-07-01 14:08:30 -07:00
|
|
|
));
|
|
|
|
}
|
2021-10-08 16:18:33 -07:00
|
|
|
Err(ESRCH) => {
|
2019-07-01 14:08:30 -07:00
|
|
|
return Err(io::Error::new(
|
|
|
|
ErrorKind::InvalidInput,
|
2022-12-06 06:30:06 -08:00
|
|
|
format!("Process {pid} does not exist"),
|
2019-07-01 14:08:30 -07:00
|
|
|
));
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
return Err(io::Error::new(
|
|
|
|
ErrorKind::InvalidInput,
|
2022-12-06 06:30:06 -08:00
|
|
|
format!("Unexpected error {e}"),
|
2019-07-01 14:08:30 -07:00
|
|
|
));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Ok(())
|
|
|
|
}
|