solana_install/
stop_process.rs

1use std::{io, process::Child};
2
3fn kill_process(process: &mut Child) -> Result<(), io::Error> {
4    if let Ok(()) = process.kill() {
5        process.wait()?;
6    } else {
7        println!("Process {} has already exited", process.id());
8    }
9    Ok(())
10}
11
12#[cfg(windows)]
13pub fn stop_process(process: &mut Child) -> Result<(), io::Error> {
14    kill_process(process)
15}
16
17#[cfg(not(windows))]
18pub fn stop_process(process: &mut Child) -> Result<(), io::Error> {
19    use {
20        nix::{
21            errno::Errno::{EINVAL, EPERM, ESRCH},
22            sys::signal::{kill, Signal},
23            unistd::Pid,
24        },
25        std::{
26            io::ErrorKind,
27            thread,
28            time::{Duration, Instant},
29        },
30    };
31
32    let nice_wait = Duration::from_secs(5);
33    let pid = Pid::from_raw(process.id() as i32);
34    match kill(pid, Signal::SIGINT) {
35        Ok(()) => {
36            let expire = Instant::now() + nice_wait;
37            while let Ok(None) = process.try_wait() {
38                if Instant::now() > expire {
39                    break;
40                }
41                thread::sleep(nice_wait / 10);
42            }
43            if let Ok(None) = process.try_wait() {
44                kill_process(process)?;
45            }
46        }
47        Err(EINVAL) => {
48            println!("Invalid signal. Killing process {pid}");
49            kill_process(process)?;
50        }
51        Err(EPERM) => {
52            return Err(io::Error::new(
53                ErrorKind::InvalidInput,
54                format!("Insufficient permissions to signal process {pid}"),
55            ));
56        }
57        Err(ESRCH) => {
58            return Err(io::Error::new(
59                ErrorKind::InvalidInput,
60                format!("Process {pid} does not exist"),
61            ));
62        }
63        Err(e) => {
64            return Err(io::Error::new(
65                ErrorKind::InvalidInput,
66                format!("Unexpected error {e}"),
67            ));
68        }
69    };
70    Ok(())
71}