1use std::process;
2use sysinfo::Process;
3use sysinfo::{Pid, System, IS_SUPPORTED_SYSTEM};
4
5pub fn find() -> Option<(String, u32)> {
7 const KNOWN_SHELLS: [&str; 10] = [
8 "bash",
9 "zsh",
10 "fish",
11 "tcsh",
12 "dash",
13 "csh",
14 "ksh",
15 "cmd",
16 "powershell",
17 "pwsh",
18 ];
19
20 if IS_SUPPORTED_SYSTEM {
21 let sys = System::new_all();
22 let mut process: Option<&Process> = sys.process(Pid::from_u32(process::id()));
23 while process.is_some() {
24 process = get_parent(&sys, process.unwrap());
25 if let Some(shell) = process {
26 if let Some(shell_name) = shell.name().to_str() {
27 let mut shell_name = shell_name;
28 if shell_name.ends_with(".exe") {
29 shell_name = &shell_name[..shell_name.len() - 4];
30 }
31 if KNOWN_SHELLS.contains(&shell_name) {
32 return Some((shell_name.to_owned(), shell.pid().as_u32()));
33 }
34 };
35 }
36 }
37 None
38 } else {
39 None
40 }
41}
42
43fn get_parent<'a>(sys: &'a System, process: &Process) -> Option<&'a Process> {
44 if let Some(ppid) = process.parent() {
45 if let Some(parent) = sys.process(ppid) {
46 Some(parent)
47 } else {
48 None
49 }
50 } else {
51 None
52 }
53}