From b5d4a706bad6d8adde102de397bdfa9aa87bea7f Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Fri, 27 Jun 2025 20:50:10 +0300 Subject: [PATCH 1/5] ps: Fix cmd field for kernel threads If process has no command line (kernel threads don't) then show its comm in square brackets. Also use accessor in ucmd() instead of open coding. --- src/uu/ps/src/picker.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/uu/ps/src/picker.rs b/src/uu/ps/src/picker.rs index 279e6919..f3969c8a 100644 --- a/src/uu/ps/src/picker.rs +++ b/src/uu/ps/src/picker.rs @@ -144,11 +144,17 @@ fn format_time(seconds: i64) -> String { } fn cmd(proc_info: RefCell) -> String { - proc_info.borrow().cmdline.clone() + // Use command line if available, otherwise show process name in brackets (for kernel threads) + let cmdline = proc_info.borrow().cmdline.clone(); + if !cmdline.is_empty() { + cmdline + } else { + format!("[{}]", proc_info.borrow_mut().name().unwrap()) + } } fn ucmd(proc_info: RefCell) -> String { - proc_info.borrow_mut().status().get("Name").unwrap().into() + proc_info.borrow_mut().name().unwrap() } #[test] From 4eb5beb8152faa19703acb4343ddde931cb9e39e Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Fri, 27 Jun 2025 20:31:21 +0300 Subject: [PATCH 2/5] ps: Support some field aliases --- src/uu/ps/src/picker.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uu/ps/src/picker.rs b/src/uu/ps/src/picker.rs index f3969c8a..a68308ea 100644 --- a/src/uu/ps/src/picker.rs +++ b/src/uu/ps/src/picker.rs @@ -33,15 +33,15 @@ pub(crate) fn collect_pickers( "user" => pickers.push(helper(user)), "euser" => pickers.push(helper(euser)), "pgid" => pickers.push(helper(pgid)), - "sid" => pickers.push(helper(sid)), + "sid" | "sess" => pickers.push(helper(sid)), "gid" => pickers.push(helper(gid)), "egid" => pickers.push(helper(egid)), "group" => pickers.push(helper(group)), "egroup" => pickers.push(helper(egroup)), "tname" | "tt" | "tty" => pickers.push(helper(tty)), "time" | "cputime" => pickers.push(helper(time)), - "ucmd" => pickers.push(helper(ucmd)), - "cmd" => pickers.push(helper(cmd)), + "ucmd" | "comm" => pickers.push(helper(ucmd)), + "cmd" | "command" | "args" => pickers.push(helper(cmd)), _ => {} } } From 1c55833dd60005ca9a8ea8dc9fd9c71d398d04f8 Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Fri, 27 Jun 2025 19:55:18 +0300 Subject: [PATCH 3/5] ps: Fix effective vs real UID/GID confusion It seems 'uid' (and 'euid') fields specify effective UID (and same for gid, user and group cases). Add ruid, ruser, rgid and rgroup to actually get the real IDs. --- src/uu/ps/src/picker.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/uu/ps/src/picker.rs b/src/uu/ps/src/picker.rs index a68308ea..9c239620 100644 --- a/src/uu/ps/src/picker.rs +++ b/src/uu/ps/src/picker.rs @@ -28,16 +28,16 @@ pub(crate) fn collect_pickers( match code.as_str() { "pid" | "tgid" => pickers.push(helper(pid)), "ppid" => pickers.push(helper(ppid)), - "uid" => pickers.push(helper(uid)), - "euid" => pickers.push(helper(euid)), - "user" => pickers.push(helper(user)), - "euser" => pickers.push(helper(euser)), + "uid" | "euid" => pickers.push(helper(euid)), + "ruid" => pickers.push(helper(ruid)), + "user" | "euser" => pickers.push(helper(euser)), + "ruser" => pickers.push(helper(ruser)), "pgid" => pickers.push(helper(pgid)), "sid" | "sess" => pickers.push(helper(sid)), - "gid" => pickers.push(helper(gid)), - "egid" => pickers.push(helper(egid)), - "group" => pickers.push(helper(group)), - "egroup" => pickers.push(helper(egroup)), + "gid" | "egid" => pickers.push(helper(egid)), + "rgid" => pickers.push(helper(rgid)), + "group" | "egroup" => pickers.push(helper(egroup)), + "rgroup" => pickers.push(helper(rgroup)), "tname" | "tt" | "tty" => pickers.push(helper(tty)), "time" | "cputime" => pickers.push(helper(time)), "ucmd" | "comm" => pickers.push(helper(ucmd)), @@ -64,7 +64,7 @@ fn ppid(proc_info: RefCell) -> String { proc_info.borrow_mut().ppid().unwrap().to_string() } -fn uid(proc_info: RefCell) -> String { +fn ruid(proc_info: RefCell) -> String { proc_info.borrow_mut().uid().unwrap().to_string() } @@ -72,7 +72,7 @@ fn euid(proc_info: RefCell) -> String { proc_info.borrow_mut().euid().unwrap().to_string() } -fn user(proc_info: RefCell) -> String { +fn ruser(proc_info: RefCell) -> String { let uid = proc_info.borrow_mut().uid().unwrap(); uid2usr(uid).ok().unwrap_or_else(|| uid.to_string()) } @@ -82,7 +82,7 @@ fn euser(proc_info: RefCell) -> String { uid2usr(euid).ok().unwrap_or_else(|| euid.to_string()) } -fn gid(proc_info: RefCell) -> String { +fn rgid(proc_info: RefCell) -> String { proc_info.borrow_mut().gid().unwrap().to_string() } @@ -90,7 +90,7 @@ fn egid(proc_info: RefCell) -> String { proc_info.borrow_mut().egid().unwrap().to_string() } -fn group(proc_info: RefCell) -> String { +fn rgroup(proc_info: RefCell) -> String { let gid = proc_info.borrow_mut().gid().unwrap(); gid2grp(gid).ok().unwrap_or_else(|| gid.to_string()) } From 8aaaa233238119b472f8929df5634acccc6feae3 Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Fri, 27 Jun 2025 19:44:04 +0300 Subject: [PATCH 4/5] process: Add suid/sgid --- src/uu/pgrep/src/process.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/uu/pgrep/src/process.rs b/src/uu/pgrep/src/process.rs index e45613ef..c5ea24a8 100644 --- a/src/uu/pgrep/src/process.rs +++ b/src/uu/pgrep/src/process.rs @@ -409,6 +409,14 @@ impl ProcessInformation { self.get_uid_or_gid_field("Gid", 1) } + pub fn suid(&mut self) -> Result { + self.get_uid_or_gid_field("Uid", 2) + } + + pub fn sgid(&mut self) -> Result { + self.get_uid_or_gid_field("Gid", 2) + } + // Root directory of the process (which can be changed by chroot) pub fn root(&mut self) -> Result { read_link(format!("/proc/{}/root", self.pid)) From 638cc848e03ea5248b26fc3314fe3cf7105f834b Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Tue, 24 Jun 2025 10:05:04 +0300 Subject: [PATCH 5/5] ps: Implement suid, suser, sgid, sgroup fields --- src/uu/ps/src/picker.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/uu/ps/src/picker.rs b/src/uu/ps/src/picker.rs index 9c239620..ba643d68 100644 --- a/src/uu/ps/src/picker.rs +++ b/src/uu/ps/src/picker.rs @@ -30,14 +30,18 @@ pub(crate) fn collect_pickers( "ppid" => pickers.push(helper(ppid)), "uid" | "euid" => pickers.push(helper(euid)), "ruid" => pickers.push(helper(ruid)), + "suid" => pickers.push(helper(suid)), "user" | "euser" => pickers.push(helper(euser)), "ruser" => pickers.push(helper(ruser)), + "suser" => pickers.push(helper(suser)), "pgid" => pickers.push(helper(pgid)), "sid" | "sess" => pickers.push(helper(sid)), "gid" | "egid" => pickers.push(helper(egid)), "rgid" => pickers.push(helper(rgid)), + "sgid" => pickers.push(helper(sgid)), "group" | "egroup" => pickers.push(helper(egroup)), "rgroup" => pickers.push(helper(rgroup)), + "sgroup" => pickers.push(helper(sgroup)), "tname" | "tt" | "tty" => pickers.push(helper(tty)), "time" | "cputime" => pickers.push(helper(time)), "ucmd" | "comm" => pickers.push(helper(ucmd)), @@ -72,6 +76,10 @@ fn euid(proc_info: RefCell) -> String { proc_info.borrow_mut().euid().unwrap().to_string() } +fn suid(proc_info: RefCell) -> String { + proc_info.borrow_mut().suid().unwrap_or(0).to_string() +} + fn ruser(proc_info: RefCell) -> String { let uid = proc_info.borrow_mut().uid().unwrap(); uid2usr(uid).ok().unwrap_or_else(|| uid.to_string()) @@ -82,6 +90,11 @@ fn euser(proc_info: RefCell) -> String { uid2usr(euid).ok().unwrap_or_else(|| euid.to_string()) } +fn suser(proc_info: RefCell) -> String { + let suid = proc_info.borrow_mut().suid().unwrap_or(0); + uid2usr(suid).unwrap_or_else(|_| suid.to_string()) +} + fn rgid(proc_info: RefCell) -> String { proc_info.borrow_mut().gid().unwrap().to_string() } @@ -90,6 +103,10 @@ fn egid(proc_info: RefCell) -> String { proc_info.borrow_mut().egid().unwrap().to_string() } +fn sgid(proc_info: RefCell) -> String { + proc_info.borrow_mut().sgid().unwrap_or(0).to_string() +} + fn rgroup(proc_info: RefCell) -> String { let gid = proc_info.borrow_mut().gid().unwrap(); gid2grp(gid).ok().unwrap_or_else(|| gid.to_string()) @@ -100,6 +117,11 @@ fn egroup(proc_info: RefCell) -> String { gid2grp(egid).ok().unwrap_or_else(|| egid.to_string()) } +fn sgroup(proc_info: RefCell) -> String { + let sgid = proc_info.borrow_mut().sgid().unwrap_or(0); + gid2grp(sgid).unwrap_or_else(|_| sgid.to_string()) +} + fn pgid(proc_info: RefCell) -> String { proc_info.borrow_mut().pgid().unwrap().to_string() }