aha_misc/common/proc.rs
1//! Process tools
2
3use std::{thread, time::Duration};
4
5use libc;
6use sysinfo::{ProcessRefreshKind, ProcessesToUpdate, System};
7
8/// Find the process ID (PID) of a program by its name.
9///
10/// # Arguments
11/// * `name` - The name of the process to find.
12///
13/// # Returns
14/// `Some(u32)` containing the PID if the process is found, or `None` if the process
15/// is not found after the maximum wait time.
16///
17/// # Description
18/// This function attempts to find a process with the specified name by checking
19/// the system's process list. It will retry for up to 10 seconds (1 second intervals)
20/// before giving up. This is useful when waiting for a process to start.
21pub fn pidof(name: &str) -> Option<u32> {
22 let mut wait_time = 0;
23 let max_wait_time = 10;
24 log::debug!("Get pid of {}...", name);
25 let mut sys = System::new_all();
26 while wait_time < max_wait_time {
27 sys.refresh_processes_specifics(
28 ProcessesToUpdate::All,
29 true,
30 ProcessRefreshKind::everything().without_tasks(),
31 );
32 for (pid, process) in sys.processes() {
33 log::debug!("Process {}: {:?}", pid.as_u32(), process.name());
34 if *name == *process.name() {
35 return Some(pid.as_u32());
36 }
37 }
38 thread::sleep(Duration::from_secs(1));
39 wait_time += 1;
40 }
41 None
42}
43
44/// Check if a process with the given PID is alive.
45///
46/// # Arguments
47/// * `pid` - The process ID to check.
48///
49/// # Returns
50/// `true` if the process is alive, `false` otherwise.
51///
52/// # Description
53/// This function uses the POSIX `kill` system call with signal 0 to check
54/// if a process exists and the calling process has permission to send signals to it.
55/// It does not actually send a signal to the process.
56pub fn is_proc_alive(pid: u32) -> bool {
57 let status = unsafe { libc::kill(pid as i32, 0) };
58 if status == -1 { false } else { true }
59}