From f577fd5ebe9904d669480c371ff150001735bf22 Mon Sep 17 00:00:00 2001 From: Gaurav Jain <64748057+errorxyz@users.noreply.github.com> Date: Wed, 11 Dec 2024 02:31:21 +0530 Subject: [PATCH] Bump sysinfo on macos (#201) --- Cargo.lock | 18 +----------- Cargo.toml | 2 +- src/processes/macos_icons.rs | 39 +++++++++++++++----------- src/processes/macos_list.rs | 54 ++++++++++++++++++++++-------------- 4 files changed, 58 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56329ce7..06525dcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1800,8 +1800,7 @@ dependencies = [ "security-framework", "smoltcp", "socket2", - "sysinfo 0.29.11", - "sysinfo 0.33.0", + "sysinfo", "tokio", "tokio-util", "tun", @@ -2640,21 +2639,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" -[[package]] -name = "sysinfo" -version = "0.29.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666" -dependencies = [ - "cfg-if", - "core-foundation-sys", - "libc", - "ntapi", - "once_cell", - "rayon", - "winapi", -] - [[package]] name = "sysinfo" version = "0.33.0" diff --git a/Cargo.toml b/Cargo.toml index 233f9061..b6a0e3b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,7 +80,7 @@ core-graphics = "0.24" core-foundation = "0.10" cocoa = "0.26" objc = "0.2" -sysinfo = "0.29.10" +sysinfo = "0.33.0" [target.'cfg(target_os = "linux")'.dependencies] tun = { version = "0.7.5", features = ["async"] } diff --git a/src/processes/macos_icons.rs b/src/processes/macos_icons.rs index 52336ffa..a16c8cef 100644 --- a/src/processes/macos_icons.rs +++ b/src/processes/macos_icons.rs @@ -8,7 +8,7 @@ use std::hash::{Hash, Hasher}; use std::io::Cursor; use std::path::Path; use std::path::PathBuf; -use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; +use sysinfo::{ProcessRefreshKind, ProcessesToUpdate, System, UpdateKind}; #[derive(Default)] pub struct IconCache { @@ -54,22 +54,29 @@ pub fn tiff_to_png(tiff: &[u8]) -> Vec { pub fn tiff_data_for_executable(executable: &Path) -> Result> { let mut sys = System::new(); - sys.refresh_processes_specifics(ProcessRefreshKind::new()); + sys.refresh_processes_specifics( + ProcessesToUpdate::All, + true, + ProcessRefreshKind::nothing().with_exe(UpdateKind::OnlyIfNotSet), + ); for (pid, process) in sys.processes() { - let pid = pid.as_u32(); - if executable == process.exe().to_path_buf() { - unsafe { - let app: id = msg_send![ - class!(NSRunningApplication), - runningApplicationWithProcessIdentifier: pid - ]; - if !app.is_null() { - let img: id = msg_send![app, icon]; - let tiff: id = msg_send![img, TIFFRepresentation]; - let length: usize = msg_send![tiff, length]; - let bytes: *const u8 = msg_send![tiff, bytes]; - let data = std::slice::from_raw_parts(bytes, length).to_vec(); - return Ok(data); + // process.exe() will return empty path if there was an error while trying to read /proc//exe. + if let Some(path) = process.exe() { + if executable == path.to_path_buf() { + let pid = pid.as_u32(); + unsafe { + let app: id = msg_send![ + class!(NSRunningApplication), + runningApplicationWithProcessIdentifier: pid + ]; + if !app.is_null() { + let img: id = msg_send![app, icon]; + let tiff: id = msg_send![img, TIFFRepresentation]; + let length: usize = msg_send![tiff, length]; + let bytes: *const u8 = msg_send![tiff, bytes]; + let data = std::slice::from_raw_parts(bytes, length).to_vec(); + return Ok(data); + } } } } diff --git a/src/processes/macos_list.rs b/src/processes/macos_list.rs index 181af85e..eac64c17 100644 --- a/src/processes/macos_list.rs +++ b/src/processes/macos_list.rs @@ -15,34 +15,46 @@ use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::ffi::c_void; use std::path::PathBuf; -use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; +use sysinfo::{ProcessRefreshKind, ProcessesToUpdate, System, UpdateKind}; pub fn active_executables() -> Result { let mut executables: HashMap = HashMap::new(); let visible = visible_windows()?; let mut sys = System::new(); - sys.refresh_processes_specifics(ProcessRefreshKind::new()); + sys.refresh_processes_specifics( + ProcessesToUpdate::All, + true, + ProcessRefreshKind::nothing().with_exe(UpdateKind::OnlyIfNotSet), + ); for (pid, process) in sys.processes() { - let pid = pid.as_u32(); - let display_name = process.name().to_string(); - let executable = process.exe().to_path_buf(); - let is_system = executable.starts_with("/System/"); - match executables.entry(executable) { - Entry::Occupied(mut e) => { - let process_info = e.get(); - if !process_info.is_visible && visible.contains(&pid) { - e.get_mut().is_visible = true; + // process.exe() will return empty path if there was an error while trying to read /proc//exe. + if let Some(path) = process.exe() { + let pid = pid.as_u32(); + let executable = path.to_path_buf(); + match executables.entry(executable) { + Entry::Occupied(mut e) => { + let process_info = e.get(); + if !process_info.is_visible && visible.contains(&pid) { + e.get_mut().is_visible = true; + } + } + 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(), + }; + let is_visible = visible.contains(&pid); + let is_system = executable.starts_with("/System/"); + e.insert(ProcessInfo { + executable, + display_name, + is_visible, + is_system, + }); } - } - Entry::Vacant(e) => { - let executable = e.key().clone(); - let is_visible = visible.contains(&pid); - e.insert(ProcessInfo { - executable, - display_name, - is_visible, - is_system, - }); } } }