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..
This commit is contained in:
Piotr Kufel 2024-08-13 04:29:40 -07:00 committed by GitHub
parent d5946a9667
commit 48e401834d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -142,31 +142,29 @@ impl ProcessInfo {
/// Name of command
pub fn name(&self) -> String {
self.command()
.split(' ')
.collect::<Vec<_>>()
.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()
}
}