Skip to content

Commit 5f7480a

Browse files
add processes_info::active_executables for linux (mitmproxy#200)
* add processes_info::active_executables for linux * update docstring * Only refresh process specific information * add process display name * fix * create system only with process specifics * Update process exe names only * [autofix.ci] apply automated fixes * nits * use file name of executable as display name --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 49e78d6 commit 5f7480a

File tree

5 files changed

+84
-8
lines changed

5 files changed

+84
-8
lines changed

Cargo.lock

Lines changed: 18 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ sysinfo = "0.29.10"
8484

8585
[target.'cfg(target_os = "linux")'.dependencies]
8686
tun = { version = "0.7.5", features = ["async"] }
87+
sysinfo = "0.33.0"
8788

8889
[dev-dependencies]
8990
env_logger = "0.11"

mitmproxy-rs/src/process_info.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
33
use anyhow::Result;
44
use pyo3::prelude::*;
55

6-
#[cfg(any(windows, target_os = "macos"))]
6+
#[cfg(any(windows, target_os = "macos", target_os = "linux"))]
77
use mitmproxy::processes;
88

99
#[pyclass(module = "mitmproxy_rs.process_info", frozen)]
@@ -47,18 +47,18 @@ impl Process {
4747
/// Return a list of all running executables.
4848
/// Note that this groups multiple processes by executable name.
4949
///
50-
/// *Availability: Windows, macOS*
50+
/// *Availability: Windows, macOS, Linux*
5151
#[pyfunction]
5252
pub fn active_executables() -> PyResult<Vec<Process>> {
53-
#[cfg(any(windows, target_os = "macos"))]
53+
#[cfg(any(windows, target_os = "macos", target_os = "linux"))]
5454
{
5555
processes::active_executables()
5656
.map(|p| p.into_iter().map(Process).collect())
5757
.map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{}", e)))
5858
}
59-
#[cfg(not(any(windows, target_os = "macos")))]
59+
#[cfg(not(any(windows, target_os = "macos", target_os = "linux")))]
6060
Err(pyo3::exceptions::PyNotImplementedError::new_err(
61-
"active_executables is only available on Windows",
61+
"active_executables not supported on the current OS",
6262
))
6363
}
6464

src/processes/linux_list.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use crate::processes::{ProcessInfo, ProcessList};
2+
use anyhow::Result;
3+
use std::collections::hash_map::Entry;
4+
use std::collections::HashMap;
5+
use std::path::PathBuf;
6+
use sysinfo::{ProcessRefreshKind, ProcessesToUpdate, System, UpdateKind};
7+
8+
pub fn active_executables() -> Result<ProcessList> {
9+
let mut executables: HashMap<PathBuf, ProcessInfo> = HashMap::new();
10+
let mut sys = System::new();
11+
12+
sys.refresh_processes_specifics(
13+
ProcessesToUpdate::All,
14+
true,
15+
ProcessRefreshKind::nothing().with_exe(UpdateKind::OnlyIfNotSet),
16+
);
17+
18+
for process in sys.processes().values() {
19+
// process.exe() will return an empty path if there was an error while trying to read /proc/<pid>/exe.
20+
if let Some(path) = process.exe() {
21+
let executable = path.to_path_buf();
22+
23+
match executables.entry(executable) {
24+
Entry::Occupied(_) => {}
25+
Entry::Vacant(e) => {
26+
let executable = e.key().clone();
27+
// .file_name() returns `None` if the path terminates in `..`
28+
// We use the absolute path in such a case.
29+
let display_name = match path.file_name() {
30+
Some(s) => s.to_string_lossy().to_string(),
31+
None => path.to_string_lossy().to_string(),
32+
};
33+
e.insert(ProcessInfo {
34+
executable,
35+
display_name,
36+
is_visible: false,
37+
is_system: false,
38+
});
39+
}
40+
}
41+
}
42+
}
43+
Ok(executables.into_values().collect())
44+
}
45+
46+
#[cfg(test)]
47+
mod tests {
48+
use super::*;
49+
50+
#[test]
51+
fn process_list() {
52+
let lst = active_executables().unwrap();
53+
assert!(!lst.is_empty());
54+
}
55+
}

src/processes/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ pub use self::windows_list::active_executables;
1313
#[cfg(windows)]
1414
pub use self::windows_list::get_process_name;
1515

16+
#[cfg(target_os = "linux")]
17+
mod linux_list;
18+
#[cfg(target_os = "linux")]
19+
pub use self::linux_list::active_executables;
20+
1621
#[cfg(target_os = "macos")]
1722
mod macos_icons;
1823
#[cfg(target_os = "macos")]

0 commit comments

Comments
 (0)