Skip to content

Commit cc812d1

Browse files
committed
ps: Implement -x flag
1 parent 26150ac commit cc812d1

File tree

4 files changed

+27
-8
lines changed

4 files changed

+27
-8
lines changed

src/uu/ps/src/mapping.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ pub(crate) fn vm_format_codes() -> Vec<String> {
104104
.to_vec()
105105
}
106106

107+
/// Returns the format codes used when BSD flags (e.g. -x) are used.
108+
pub(crate) fn bsd_format_codes() -> Vec<String> {
109+
["pid", "tname", "stat", "time", "command"]
110+
.map(Into::into)
111+
.to_vec()
112+
}
113+
107114
/// Returns the register format codes (for -X flag).
108115
pub(crate) fn register_format_codes() -> Vec<String> {
109116
[

src/uu/ps/src/process_selection.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ pub struct ProcessSelectionSettings {
4343
/// - `-d` Select all processes except session leaders.
4444
pub select_non_session_leaders: bool,
4545

46+
/// - '-x' Lift "must have a tty" restriction.
47+
pub dont_require_tty: bool,
48+
4649
/// - `--deselect` Negates the selection.
4750
pub negate_selection: bool,
4851
}
@@ -53,6 +56,7 @@ impl ProcessSelectionSettings {
5356
select_all: matches.get_flag("A"),
5457
select_non_session_leaders_with_tty: matches.get_flag("a"),
5558
select_non_session_leaders: matches.get_flag("d"),
59+
dont_require_tty: matches.get_flag("x"),
5660
negate_selection: matches.get_flag("deselect"),
5761
}
5862
}
@@ -75,8 +79,9 @@ impl ProcessSelectionSettings {
7579
return Ok(!is_session_leader(process));
7680
}
7781

78-
// Default behavior: select processes with same terminal and same effective user ID
79-
Ok(process.tty() == current_tty && process.euid().unwrap() == current_euid)
82+
// Default behavior: select processes with same effective user ID and same tty (except -x removes tty restriction)
83+
Ok(process.euid().unwrap() == current_euid
84+
&& (self.dont_require_tty || process.tty() == current_tty))
8085
};
8186

8287
let mut selected = vec![];

src/uu/ps/src/ps.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ mod sorting;
1212
use clap::crate_version;
1313
use clap::{Arg, ArgAction, ArgMatches, Command};
1414
use mapping::{
15-
collect_code_mapping, default_codes, default_mapping, default_with_psr_codes,
15+
bsd_format_codes, collect_code_mapping, default_codes, default_mapping, default_with_psr_codes,
1616
extra_full_format_codes, full_format_codes, job_format_codes, long_format_codes,
1717
long_y_format_codes, register_format_codes, signal_format_codes, user_format_codes,
1818
vm_format_codes,
@@ -65,6 +65,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
6565
user_format_codes()
6666
} else if matches.get_flag("v") {
6767
vm_format_codes()
68+
} else if matches.get_flag("x") {
69+
bsd_format_codes()
6870
} else if matches.get_flag("X") {
6971
register_format_codes()
7072
} else if arg_formats.is_empty() {
@@ -179,11 +181,10 @@ pub fn uu_app() -> Command {
179181
// .action(ArgAction::SetTrue)
180182
// .help("all processes on this terminal")
181183
// .allow_hyphen_values(true),
182-
// Arg::new("x")
183-
// .short('x')
184-
// .action(ArgAction::SetTrue)
185-
// .help("processes without controlling ttys")
186-
// .allow_hyphen_values(true),
184+
Arg::new("x")
185+
.short('x')
186+
.action(ArgAction::SetTrue)
187+
.help("processes without controlling ttys"),
187188
])
188189
.arg(
189190
Arg::new("f")

tests/by-util/test_ps.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,12 @@ fn test_register_format() {
131131
);
132132
}
133133

134+
#[test]
135+
#[cfg(target_os = "linux")]
136+
fn test_x_format() {
137+
check_header("-x", &["PID", "TTY", "STAT", "TIME", "COMMAND"]);
138+
}
139+
134140
#[test]
135141
#[cfg(target_os = "linux")]
136142
fn test_code_mapping() {

0 commit comments

Comments
 (0)