1use anyhow::{anyhow, bail, Result};
2use nix::{
3 sys::signal::{kill, Signal},
4 unistd::{getsid, Pid},
5};
6
7use crate::processes::Processes;
8
9pub fn send_signal_to_pid(pid: Pid, signal: Option<Signal>) -> anyhow::Result<bool> {
10 match kill(pid, signal) {
11 Ok(()) => Ok(true),
12 Err(e) => match e {
13 nix::errno::Errno::EPERM => {
14 bail!("don't have permission to send signal to pid {pid}")
22 }
23 nix::errno::Errno::ESRCH => {
24 Ok(false)
26 }
27 _ => unreachable!(),
28 },
29 }
30}
31
32pub fn send_signal_to_process_group(pid: Pid, signal: Option<Signal>) -> Result<bool> {
33 let process_group_id: i32 = pid
34 .as_raw()
35 .checked_neg()
36 .ok_or_else(|| anyhow!("pid {pid} can't be negated"))?;
37 send_signal_to_pid(Pid::from_raw(process_group_id), signal)
38}
39
40pub fn send_signal_to_all_processes_of_session(
41 session_pid: Pid,
42 signal: Option<Signal>,
43) -> anyhow::Result<bool> {
44 let mut reached_a_process = send_signal_to_process_group(session_pid, signal)?;
47
48 let pids = Processes::default().get_list()?;
50 for pid in pids {
51 if let Ok(sid) = getsid(Some(pid)) {
52 if sid == session_pid {
53 if send_signal_to_pid(pid, signal)? {
54 reached_a_process = true;
55 }
56 }
57 }
58 }
59 Ok(reached_a_process)
60}