1#[cfg(target_os = "linux")]
2pub fn pids_with_file_open(path: &std::path::Path) -> std::io::Result<Vec<nix::unistd::Pid>> {
3 use nix::libc::pid_t;
4 use nix::unistd::Pid;
5 use procfs::process::all_processes;
6
7 let mut pids = vec![];
8
9 let target = path.canonicalize()?;
10
11 for process in all_processes().unwrap() {
12 let Ok(process) = process else {
13 continue;
14 };
15
16 let Ok(fds) = process.fd() else {
17 continue;
18 };
19
20 for fd in fds {
21 let Ok(fd) = fd else {
22 continue;
23 };
24
25 if matches!(fd.target, procfs::process::FDTarget::Path(path) if path == target) {
26 pids.push(Pid::from_raw(process.pid as pid_t));
27 }
28 }
29 }
30
31 Ok(pids)
32}
33
34#[cfg(any(target_os = "macos", target_os = "freebsd"))]
35pub fn pids_with_file_open(path: &std::path::Path) -> std::io::Result<Vec<nix::unistd::Pid>> {
36 use nix::libc::pid_t;
37 use nix::unistd::Pid;
38 use std::process::Command;
39
40 let output = Command::new("lsof")
42 .arg("-t")
43 .arg(path.to_string_lossy().as_ref())
44 .output()?;
45 if !output.status.success() {
46 return Ok(Vec::new());
47 }
48
49 let stdout = String::from_utf8_lossy(&output.stdout);
50 let mut pids = Vec::new();
51 for line in stdout.lines() {
52 if let Ok(pid) = line.trim().parse::<pid_t>() {
53 pids.push(Pid::from_raw(pid));
54 }
55 }
56
57 Ok(pids)
58}
59
60#[cfg(target_os = "linux")]
61pub fn cmdline(pid: nix::unistd::Pid) -> std::io::Result<String> {
62 use std::fs;
63
64 let cmdline = fs::read_to_string(format!("/proc/{pid}/cmdline"))?;
65 Ok(cmdline.replace('\0', " ").trim().to_string())
66}
67
68#[cfg(any(target_os = "macos", target_os = "freebsd"))]
69pub fn cmdline(pid: nix::unistd::Pid) -> std::io::Result<String> {
70 use std::process::Command;
71
72 let output = Command::new("ps")
73 .arg("-p")
74 .arg(pid.as_raw().to_string())
75 .arg("-o")
76 .arg("command=")
77 .output()?;
78 if !output.status.success() {
79 return Err(std::io::Error::other("Failed to get process command line"));
80 }
81
82 let cmdline = String::from_utf8_lossy(&output.stdout);
83 Ok(cmdline.trim().to_string())
84}