diff --git a/Cargo.lock b/Cargo.lock index 6b41665e..faaa955b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1203,6 +1203,7 @@ dependencies = [ "syscalls", "sysconf", "unescape", + "uzers", ] [[package]] @@ -1301,7 +1302,6 @@ dependencies = [ "strum_macros", "sysconf", "unescape", - "uzers", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 3c19bac3..894015a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,6 @@ sysconf = "0.3.4" nvml-wrapper = "0.10.0" unescape = "0.1.0" nix = { version = "0.28", features = ["signal"] } -uzers = "0.11.3" plotters = { version = "0.3.5", default_features = false, features = [ "area_series", ] } diff --git a/lib/process_data/Cargo.lock b/lib/process_data/Cargo.lock index 81c7d931..26ea4cc4 100644 --- a/lib/process_data/Cargo.lock +++ b/lib/process_data/Cargo.lock @@ -106,12 +106,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - [[package]] name = "ident_case" version = "1.0.1" @@ -145,20 +139,16 @@ dependencies = [ ] [[package]] -name = "memchr" -version = "2.6.4" +name = "log" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] -name = "num_cpus" -version = "1.16.0" +name = "memchr" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "nvml-wrapper" @@ -200,12 +190,11 @@ dependencies = [ [[package]] name = "process-data" -version = "1.2.1" +version = "1.3.0" dependencies = [ "anyhow", "glob", "libc", - "num_cpus", "nvml-wrapper", "once_cell", "regex", @@ -213,6 +202,7 @@ dependencies = [ "syscalls", "sysconf", "unescape", + "uzers", ] [[package]] @@ -372,6 +362,16 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "uzers" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d283dc7e8c901e79e32d077866eaf599156cbf427fffa8289aecc52c5c3f63" +dependencies = [ + "libc", + "log", +] + [[package]] name = "winapi" version = "0.2.8" diff --git a/lib/process_data/Cargo.toml b/lib/process_data/Cargo.toml index 20a4f6b4..cd184c6d 100644 --- a/lib/process_data/Cargo.toml +++ b/lib/process_data/Cargo.toml @@ -23,3 +23,4 @@ serde = { version = "1.0.180", features = ["serde_derive"] } nvml-wrapper = "0.9.0" syscalls = { version = "0.6.15", features = ["all"] } libc = "0.2.150" +uzers = "0.11.3" diff --git a/lib/process_data/src/lib.rs b/lib/process_data/src/lib.rs index f87113d8..1fb587af 100644 --- a/lib/process_data/src/lib.rs +++ b/lib/process_data/src/lib.rs @@ -14,10 +14,17 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use std::fs::File; use std::io::{Read, Write}; use std::os::linux::fs::MetadataExt; +use std::path::Path; use std::str::FromStr; use std::sync::RwLock; use std::{path::PathBuf, time::SystemTime}; +static USERS_CACHE: Lazy> = Lazy::new(|| unsafe { + uzers::all_users() + .map(|user| (user.uid(), user.name().to_string_lossy().to_string())) + .collect() +}); + static PAGESIZE: Lazy = Lazy::new(sysconf::pagesize); static RE_UID: Lazy = Lazy::new(|| Regex::new(r"Uid:\s*(\d+)").unwrap()); @@ -122,7 +129,7 @@ pub struct GpuUsageStats { #[derive(Debug, Default, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)] pub struct ProcessData { pub pid: i32, - pub uid: u32, + pub user: String, proc_path: PathBuf, pub comm: String, pub commandline: String, @@ -174,7 +181,7 @@ impl ProcessData { } } - fn get_uid(proc_path: &PathBuf) -> Result { + fn get_uid(proc_path: &Path) -> Result { let status = std::fs::read_to_string(proc_path.join("status"))?; if let Some(captures) = RE_UID.captures(&status) { let first_num_str = captures.get(1).context("no uid found")?; @@ -216,12 +223,12 @@ impl ProcessData { } pub fn try_from_path(proc_path: PathBuf) -> Result { - let stat = std::fs::read_to_string(&proc_path.join("stat"))?; - let statm = std::fs::read_to_string(&proc_path.join("statm"))?; - let comm = std::fs::read_to_string(&proc_path.join("comm"))?; - let commandline = std::fs::read_to_string(&proc_path.join("cmdline"))?; - let cgroup = std::fs::read_to_string(&proc_path.join("cgroup"))?; - let io = std::fs::read_to_string(&proc_path.join("io")).ok(); + let stat = std::fs::read_to_string(proc_path.join("stat"))?; + let statm = std::fs::read_to_string(proc_path.join("statm"))?; + let comm = std::fs::read_to_string(proc_path.join("comm"))?; + let commandline = std::fs::read_to_string(proc_path.join("cmdline"))?; + let cgroup = std::fs::read_to_string(proc_path.join("cgroup"))?; + let io = std::fs::read_to_string(proc_path.join("io")).ok(); let pid = proc_path .file_name() @@ -230,7 +237,10 @@ impl ProcessData { .context("can't turn OsStr to str")? .parse()?; - let uid = Self::get_uid(&proc_path)?; + let user = USERS_CACHE + .get(&Self::get_uid(&proc_path)?) + .cloned() + .unwrap_or(String::from("root")); let stat = stat .split(')') // since we don't care about the pid or the executable name, split after the executable name to make our life easier @@ -284,7 +294,7 @@ impl ProcessData { Ok(Self { pid, - uid, + user, comm, commandline, user_cpu_time, @@ -305,12 +315,12 @@ impl ProcessData { fn gpu_usage_stats(proc_path: &PathBuf, pid: i32) -> BTreeMap { let nvidia_stats = Self::nvidia_gpu_stats_all(pid).unwrap_or_default(); let mut other_stats = Self::other_gpu_usage_stats(proc_path, pid).unwrap_or_default(); - other_stats.extend(nvidia_stats.into_iter()); + other_stats.extend(nvidia_stats); other_stats } fn other_gpu_usage_stats( - proc_path: &PathBuf, + proc_path: &Path, pid: i32, ) -> Result> { let fdinfo_dir = proc_path.join("fdinfo"); diff --git a/src/ui/pages/processes/mod.rs b/src/ui/pages/processes/mod.rs index c2978d42..35753501 100644 --- a/src/ui/pages/processes/mod.rs +++ b/src/ui/pages/processes/mod.rs @@ -26,7 +26,6 @@ use self::process_name_cell::ResProcessNameCell; mod imp { use std::{ cell::{Cell, RefCell}, - collections::HashMap, sync::OnceLock, }; @@ -66,8 +65,6 @@ mod imp { pub column_view: RefCell, pub open_dialog: RefCell>, - pub username_cache: RefCell>, - pub sender: OnceLock>, pub popped_over_process: RefCell>, @@ -151,7 +148,6 @@ mod imp { sort_model: Default::default(), column_view: Default::default(), open_dialog: Default::default(), - username_cache: Default::default(), sender: Default::default(), uses_progress_bar: Cell::new(false), icon: RefCell::new(ThemedIcon::new("generic-process-symbolic").into()), @@ -471,7 +467,7 @@ impl ResProcesses { pub fn open_information_dialog(&self, process: &ProcessItem) { let imp = self.imp(); let process_dialog = ResProcessDialog::new(); - process_dialog.init(process, self.get_user_name_by_uid(process.uid)); + process_dialog.init(process, &process.user); process_dialog.present(&MainWindow::default()); *imp.open_dialog.borrow_mut() = Some((process.pid, process_dialog)); } @@ -534,10 +530,7 @@ impl ResProcesses { // add the newly started process to the store let items: Vec = new_items .drain() - .map(|(_, new_item)| { - let user_name = self.get_user_name_by_uid(new_item.uid); - ProcessEntry::new(new_item, &user_name) - }) + .map(|(_, new_item)| ProcessEntry::new(new_item)) .collect(); store.extend_from_slice(&items); @@ -596,27 +589,6 @@ impl ResProcesses { dialog.present(&MainWindow::default()); } - fn get_user_name_by_uid(&self, uid: u32) -> String { - let imp = self.imp(); - - // we do this to avoid mut-borrows when possible - let cached = { - let borrow = imp.username_cache.borrow(); - borrow.get(&uid).cloned() - }; - - if let Some(cached) = cached { - cached - } else { - let name = uzers::get_user_by_uid(uid).map_or_else( - || i18n("root"), - |user| user.name().to_string_lossy().to_string(), - ); - imp.username_cache.borrow_mut().insert(uid, name.clone()); - name - } - } - fn add_name_column(&self, column_view: &ColumnView) -> ColumnViewColumn { let name_col_factory = gtk::SignalListItemFactory::new(); diff --git a/src/ui/pages/processes/process_entry.rs b/src/ui/pages/processes/process_entry.rs index 50cc69c7..e90895ab 100644 --- a/src/ui/pages/processes/process_entry.rs +++ b/src/ui/pages/processes/process_entry.rs @@ -179,11 +179,11 @@ glib::wrapper! { } impl ProcessEntry { - pub fn new(process_item: ProcessItem, user: &str) -> Self { + pub fn new(process_item: ProcessItem) -> Self { let this: Self = glib::Object::builder() .property("name", &process_item.display_name) .property("commandline", &process_item.commandline) - .property("user", user) + .property("user", &process_item.user) .property("icon", &process_item.icon) .property("pid", process_item.pid) .build(); diff --git a/src/utils/app.rs b/src/utils/app.rs index 5a292115..ec30a03e 100644 --- a/src/utils/app.rs +++ b/src/utils/app.rs @@ -613,6 +613,7 @@ impl AppsContext { }; ProcessItem { pid: process.data.pid, + user: process.data.user.clone(), display_name: full_comm.clone(), icon: process.icon.clone(), memory_usage: process.data.memory_usage, @@ -624,7 +625,6 @@ impl AppsContext { containerization: process.data.containerization, starttime: process.starttime(), cgroup: process.data.cgroup.clone(), - uid: process.data.uid, read_speed: process.read_speed(), read_total: process.data.read_bytes, write_speed: process.write_speed(), diff --git a/src/utils/process.rs b/src/utils/process.rs index 472a0232..c7dbe257 100644 --- a/src/utils/process.rs +++ b/src/utils/process.rs @@ -76,7 +76,7 @@ pub enum ProcessAction { #[derive(Debug, Clone)] pub struct ProcessItem { pub pid: i32, - pub uid: u32, + pub user: String, pub display_name: String, pub icon: Icon, pub memory_usage: usize,