diff --git a/Cargo.lock b/Cargo.lock index 9f58b4a2..56329ce7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1610,9 +1610,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libloading" @@ -1800,7 +1800,8 @@ dependencies = [ "security-framework", "smoltcp", "socket2", - "sysinfo", + "sysinfo 0.29.11", + "sysinfo 0.33.0", "tokio", "tokio-util", "tun", @@ -2654,6 +2655,20 @@ dependencies = [ "winapi", ] +[[package]] +name = "sysinfo" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "948512566b1895f93b1592c7574baeb2de842f224f2aab158799ecadb8ebbb46" +dependencies = [ + "core-foundation-sys", + "libc", + "memchr", + "ntapi", + "rayon", + "windows 0.57.0", +] + [[package]] name = "tar" version = "0.4.43" diff --git a/Cargo.toml b/Cargo.toml index 5efc94db..233f9061 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,6 +84,7 @@ sysinfo = "0.29.10" [target.'cfg(target_os = "linux")'.dependencies] tun = { version = "0.7.5", features = ["async"] } +sysinfo = "0.33.0" [dev-dependencies] env_logger = "0.11" diff --git a/mitmproxy-rs/src/process_info.rs b/mitmproxy-rs/src/process_info.rs index ef87f7ce..f824256d 100644 --- a/mitmproxy-rs/src/process_info.rs +++ b/mitmproxy-rs/src/process_info.rs @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf}; use anyhow::Result; use pyo3::prelude::*; -#[cfg(any(windows, target_os = "macos"))] +#[cfg(any(windows, target_os = "macos", target_os = "linux"))] use mitmproxy::processes; #[pyclass(module = "mitmproxy_rs.process_info", frozen)] @@ -47,18 +47,18 @@ impl Process { /// Return a list of all running executables. /// Note that this groups multiple processes by executable name. /// -/// *Availability: Windows, macOS* +/// *Availability: Windows, macOS, Linux* #[pyfunction] pub fn active_executables() -> PyResult> { - #[cfg(any(windows, target_os = "macos"))] + #[cfg(any(windows, target_os = "macos", target_os = "linux"))] { processes::active_executables() .map(|p| p.into_iter().map(Process).collect()) .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{}", e))) } - #[cfg(not(any(windows, target_os = "macos")))] + #[cfg(not(any(windows, target_os = "macos", target_os = "linux")))] Err(pyo3::exceptions::PyNotImplementedError::new_err( - "active_executables is only available on Windows", + "active_executables not supported on the current OS", )) } diff --git a/src/processes/linux_list.rs b/src/processes/linux_list.rs new file mode 100644 index 00000000..170ab80a --- /dev/null +++ b/src/processes/linux_list.rs @@ -0,0 +1,55 @@ +use crate::processes::{ProcessInfo, ProcessList}; +use anyhow::Result; +use std::collections::hash_map::Entry; +use std::collections::HashMap; +use std::path::PathBuf; +use sysinfo::{ProcessRefreshKind, ProcessesToUpdate, System, UpdateKind}; + +pub fn active_executables() -> Result { + let mut executables: HashMap = HashMap::new(); + let mut sys = System::new(); + + sys.refresh_processes_specifics( + ProcessesToUpdate::All, + true, + ProcessRefreshKind::nothing().with_exe(UpdateKind::OnlyIfNotSet), + ); + + for process in sys.processes().values() { + // process.exe() will return an empty path if there was an error while trying to read /proc//exe. + if let Some(path) = process.exe() { + let executable = path.to_path_buf(); + + match executables.entry(executable) { + Entry::Occupied(_) => {} + Entry::Vacant(e) => { + let executable = e.key().clone(); + // .file_name() returns `None` if the path terminates in `..` + // We use the absolute path in such a case. + let display_name = match path.file_name() { + Some(s) => s.to_string_lossy().to_string(), + None => path.to_string_lossy().to_string(), + }; + e.insert(ProcessInfo { + executable, + display_name, + is_visible: false, + is_system: false, + }); + } + } + } + } + Ok(executables.into_values().collect()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn process_list() { + let lst = active_executables().unwrap(); + assert!(!lst.is_empty()); + } +} diff --git a/src/processes/mod.rs b/src/processes/mod.rs index 33e38fbe..ec8505b3 100644 --- a/src/processes/mod.rs +++ b/src/processes/mod.rs @@ -13,6 +13,11 @@ pub use self::windows_list::active_executables; #[cfg(windows)] pub use self::windows_list::get_process_name; +#[cfg(target_os = "linux")] +mod linux_list; +#[cfg(target_os = "linux")] +pub use self::linux_list::active_executables; + #[cfg(target_os = "macos")] mod macos_icons; #[cfg(target_os = "macos")]