From 48e401834d604563106a6ef3738a996d38c790ca Mon Sep 17 00:00:00 2001 From: Piotr Kufel Date: Tue, 13 Aug 2024 04:29:40 -0700 Subject: [PATCH] Fix handling of spaces in executable names (#13596) # Description The original code assumed a full single-string command line could be split by space to get the original argv. # User-Facing Changes Fixes an issue where `ps` would display incomplete process name if it contained space(s). # Tests + Formatting Fixes existing code, no new coverage. Existing code doesn't seem to be covered, we could be it would be somewhat involved and the fix was simple, so didn't bother.. --- crates/nu-system/src/linux.rs | 38 ++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/crates/nu-system/src/linux.rs b/crates/nu-system/src/linux.rs index 238c386959..1523584537 100644 --- a/crates/nu-system/src/linux.rs +++ b/crates/nu-system/src/linux.rs @@ -142,31 +142,29 @@ impl ProcessInfo { /// Name of command pub fn name(&self) -> String { - self.command() - .split(' ') - .collect::>() - .first() - .map(|x| x.to_string()) - .unwrap_or_default() + if let Ok(mut cmd) = self.curr_proc.cmdline() { + if let Some(name) = cmd.first_mut() { + // Take over the first element and return it without extra allocations + // (String::default() is allocation-free). + return std::mem::take(name); + } + } + self.comm() } /// Full name of command, with arguments + /// + /// WARNING: As this does no escaping, this function is lossy. It's OK-ish for display purposes + /// but nothing else. + // TODO: Maybe rename this to display_command and add escaping compatible with nushell? pub fn command(&self) -> String { - if let Ok(cmd) = &self.curr_proc.cmdline() { + if let Ok(cmd) = self.curr_proc.cmdline() { + // TODO: When can it successfully return empty? if !cmd.is_empty() { - cmd.join(" ").replace(['\n', '\t'], " ") - } else { - match self.curr_proc.stat() { - Ok(p) => p.comm, - Err(_) => "".to_string(), - } - } - } else { - match self.curr_proc.stat() { - Ok(p) => p.comm, - Err(_) => "".to_string(), + return cmd.join(" ").replace(['\n', '\t'], " "); } } + self.comm() } pub fn cwd(&self) -> String { @@ -228,4 +226,8 @@ impl ProcessInfo { pub fn virtual_size(&self) -> u64 { self.curr_proc.stat().map(|p| p.vsize).unwrap_or_default() } + + fn comm(&self) -> String { + self.curr_proc.stat().map(|st| st.comm).unwrap_or_default() + } }