nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: uutils/procps
Pull request #329 (2025-02-19 08:32:17)

pgrep: don't show msg if pattern is 15 chars long
The original `pgrep` shows a message if the pattern is longer than 15 chars:
```
$ pgrep 123456789012345
$ pgrep 1234567890123456
pgrep: pattern that searches for process name longer than 15 characters will result in zero matches
Try `pgrep -f' option to match against the complete command line.
```
We showed this message if the pattern was 15 chars or longer. This PR fixes the issue.


Patch:
diff --git a/src/uu/pgrep/src/process_matcher.rs b/src/uu/pgrep/src/process_matcher.rs
index ffb2474..b9ff54b 100644
--- a/src/uu/pgrep/src/process_matcher.rs
+++ b/src/uu/pgrep/src/process_matcher.rs
@@ -78,7 +78,7 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> {
         ));
     }
 
-    if !settings.full && pattern.len() >= 15 {
+    if !settings.full && pattern.len() > 15 {
         let msg = format!("pattern that searches for process name longer than 15 characters will result in zero matches\n\
                            Try `{} -f' option to match against the complete command line.", uucore::util_name());
         return Err(USimpleError::new(1, msg));


Test patch:
diff --git a/tests/by-util/test_pgrep.rs b/tests/by-util/test_pgrep.rs
index f4f9314..50a2a58 100644
--- a/tests/by-util/test_pgrep.rs
+++ b/tests/by-util/test_pgrep.rs
@@ -380,7 +380,13 @@ fn test_does_not_match_pid() {
 #[cfg(target_os = "linux")]
 fn test_too_long_pattern() {
     new_ucmd!()
-        .arg("THIS_IS_OVER_16_CHARS")
+        .arg("A".repeat(15))
+        .fails()
+        .code_is(1)
+        .no_output();
+
+    new_ucmd!()
+        .arg("A".repeat(16))
         .fails()
         .code_is(1)
         .stderr_contains("pattern that searches for process name longer than 15 characters will result in zero matches");
Repository: uutils/procps
Pull request #339 (2025-02-26 15:29:27)

process_matcher: Don't match own procps process
For example, pgrep should never report itself as a match (but it can match other pgrep processes).


Patch:
diff --git a/src/uu/pgrep/src/process_matcher.rs b/src/uu/pgrep/src/process_matcher.rs
index c24c13a..460e947 100644
--- a/src/uu/pgrep/src/process_matcher.rs
+++ b/src/uu/pgrep/src/process_matcher.rs
@@ -168,7 +168,12 @@ fn collect_matched_pids(settings: &Settings) -> Vec<ProcessInformation> {
     let filtered: Vec<ProcessInformation> = {
         let mut tmp_vec = Vec::new();
 
+        let our_pid = std::process::id() as usize;
         for mut pid in walk_process().collect::<Vec<_>>() {
+            if pid.pid == our_pid {
+                continue;
+            }
+
             let run_state_matched = match (&settings.runstates, pid.run_state()) {
                 (Some(arg_run_states), Ok(pid_state)) => {
                     arg_run_states.contains(&pid_state.to_string())


Test patch:
diff --git a/tests/by-util/test_pgrep.rs b/tests/by-util/test_pgrep.rs
index 55cb127..303ce8d 100644
--- a/tests/by-util/test_pgrep.rs
+++ b/tests/by-util/test_pgrep.rs
@@ -420,3 +420,15 @@ fn test_current_user() {
         .arg(uucore::process::getuid().to_string())
         .succeeds();
 }
+
+#[test]
+#[cfg(target_os = "linux")]
+fn test_does_not_match_current_process() {
+    let our_pid = std::process::id();
+    dbg!(&our_pid);
+    new_ucmd!()
+        .arg("-f")
+        .arg("UNIQUE_STRING_THAT_DOES_NOT_MATCH_ANY_OTHER_PROCESS")
+        .fails()
+        .no_output();
+}
Repository: uutils/procps
Pull request #359 (2025-03-21 10:07:26)

pidof: don't require program name
Currently, we require at least one program name and if none is provided, a clap error message is shown. This makes the following code snippet in `uumain` unreachable:
```rust
    if arg_program_name.is_none() {
        uucore::error::set_exit_code(1);
        return Ok(());
    };
```
This PR no longer requires a program name and thus makes the snippet above reachable. It also corresponds with the behavior of the original `pidof`, which doesn't show an error message if called without any args.

The PR also removes the `#[cfg(target_os = "linux")]` of the test as it is not necessary.


Patch:
diff --git a/src/uu/pidof/src/pidof.rs b/src/uu/pidof/src/pidof.rs
index 12dc8f7..c9ecade 100644
--- a/src/uu/pidof/src/pidof.rs
+++ b/src/uu/pidof/src/pidof.rs
@@ -117,7 +117,6 @@ pub fn uu_app() -> Command {
         .arg(
             Arg::new("program-name")
                 .help("Program name.")
-                .required(true)
                 .index(1)
                 .action(ArgAction::Append),
         )


Test patch:
diff --git a/tests/by-util/test_pidof.rs b/tests/by-util/test_pidof.rs
index 76e4cda..2234fd5 100644
--- a/tests/by-util/test_pidof.rs
+++ b/tests/by-util/test_pidof.rs
@@ -5,6 +5,11 @@
 
 use crate::common::util::TestScenario;
 
+#[test]
+fn test_no_args() {
+    new_ucmd!().fails().code_is(1).no_output();
+}
+
 #[test]
 fn test_invalid_arg() {
     new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
@@ -23,12 +28,6 @@ fn test_find_kthreadd() {
     new_ucmd!().arg("kthreadd").succeeds();
 }
 
-#[test]
-#[cfg(target_os = "linux")]
-fn test_no_program() {
-    new_ucmd!().fails().code_is(1);
-}
-
 #[test]
 #[cfg(target_os = "linux")]
 fn test_no_pid_found() {
Repository: uutils/procps
Pull request #65 (2024-04-18 12:57:50)

w: add `--help`
This PR adds `--help`. It also ensures that `-h` is the short form of `--no-header`.


Patch:
diff --git a/src/uu/w/src/w.rs b/src/uu/w/src/w.rs
index 83cd515..d13364a 100644
--- a/src/uu/w/src/w.rs
+++ b/src/uu/w/src/w.rs
@@ -184,6 +184,12 @@ pub fn uu_app() -> Command {
         .override_usage(format_usage(USAGE))
         .infer_long_args(true)
         .disable_help_flag(true)
+        .arg(
+            Arg::new("help")
+                .long("help")
+                .help("Print help information")
+                .action(ArgAction::Help),
+        )
         .arg(
             Arg::new("no-header")
                 .short('h')


Test patch:
diff --git a/tests/by-util/test_w.rs b/tests/by-util/test_w.rs
index 42341e6..904cd1e 100644
--- a/tests/by-util/test_w.rs
+++ b/tests/by-util/test_w.rs
@@ -11,13 +11,24 @@ fn test_invalid_arg() {
     new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
 }
 
+#[test]
+fn test_help() {
+    new_ucmd!()
+        .arg("--help")
+        .succeeds()
+        .stdout_contains("Usage")
+        .stdout_contains("Options");
+}
+
 #[test]
 fn test_no_header() {
-    let cmd = new_ucmd!().arg("--no-header").succeeds();
+    for arg in ["-h", "--no-header"] {
+        let cmd = new_ucmd!().arg(arg).succeeds();
 
-    let result = cmd.stdout_str();
+        let result = cmd.stdout_str();
 
-    assert!(!result.contains("USER\tTTY\tLOGIN@\tIDLE\tJCPU\tPCPU\tWHAT"));
+        assert!(!result.contains("USER\tTTY\tLOGIN@\tIDLE\tJCPU\tPCPU\tWHAT"));
+    }
 }
 
 #[test]
Repository: uutils/procps
Pull request #132 (2024-07-19 12:11:21)

pgrep: allow `--older` without pattern
This PR allows the `--older` option without a pattern: `pgrep --older=1`. This corresponds to the behavior of `pgrep` from procps-ng.


Patch:
diff --git a/src/uu/pgrep/src/pgrep.rs b/src/uu/pgrep/src/pgrep.rs
index fde9c2a..7c1c05c 100644
--- a/src/uu/pgrep/src/pgrep.rs
+++ b/src/uu/pgrep/src/pgrep.rs
@@ -6,7 +6,9 @@
 // Pid utils
 pub mod process;
 
-use clap::{arg, crate_version, Arg, ArgAction, ArgGroup, ArgMatches, Command};
+use clap::{
+    arg, crate_version, parser::ValueSource, Arg, ArgAction, ArgGroup, ArgMatches, Command,
+};
 use process::{walk_process, ProcessInformation, TerminalType};
 use regex::Regex;
 use std::{collections::HashSet, sync::OnceLock};
@@ -44,8 +46,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
     // Pattern check
     let flag_newest = matches.get_flag("newest");
     let flag_oldest = matches.get_flag("oldest");
+    let flag_older = matches.value_source("older") == Some(ValueSource::CommandLine);
 
-    if (!flag_newest && !flag_oldest) && pattern.is_empty() {
+    if (!flag_newest && !flag_oldest && !flag_older) && pattern.is_empty() {
         return Err(USimpleError::new(
             2,
             "no matching criteria specified\nTry `pgrep --help' for more information.",


Test patch:
diff --git a/tests/by-util/test_pgrep.rs b/tests/by-util/test_pgrep.rs
index 84adab6..f38f4b9 100644
--- a/tests/by-util/test_pgrep.rs
+++ b/tests/by-util/test_pgrep.rs
@@ -93,6 +93,39 @@ fn test_newest_non_matching_pattern() {
         .no_output();
 }
 
+#[test]
+#[cfg(target_os = "linux")]
+fn test_older() {
+    for arg in ["-O", "--older"] {
+        new_ucmd!()
+            .arg(arg)
+            .arg("0")
+            .succeeds()
+            .stdout_matches(&Regex::new("(?m)^[1-9][0-9]*$").unwrap());
+    }
+}
+
+#[test]
+#[cfg(target_os = "linux")]
+fn test_older_matching_pattern() {
+    new_ucmd!()
+        .arg("--older=0")
+        .arg("sh")
+        .succeeds()
+        .stdout_matches(&Regex::new("(?m)^[1-9][0-9]*$").unwrap());
+}
+
+#[test]
+#[cfg(target_os = "linux")]
+fn test_older_non_matching_pattern() {
+    new_ucmd!()
+        .arg("--older=0")
+        .arg("non_matching")
+        .fails()
+        .code_is(1)
+        .no_stdout();
+}
+
 #[test]
 #[cfg(target_os = "linux")]
 fn test_full() {
Repository: uutils/procps
Pull request #140 (2024-07-23 08:58:29)

pgrep: allow comma-separated list of terminals
This PR allows a comma-separated list of terminals for `--terminal`.


Patch:
diff --git a/src/uu/pgrep/src/pgrep.rs b/src/uu/pgrep/src/pgrep.rs
index 340e4d9..baeef1e 100644
--- a/src/uu/pgrep/src/pgrep.rs
+++ b/src/uu/pgrep/src/pgrep.rs
@@ -286,7 +286,7 @@ pub fn uu_app() -> Command {
             // arg!(-P     --parent <PPID>         "match only child processes of the given parent"),
             // arg!(-s     --session <SID>         "match session IDs"),
             arg!(-t     --terminal <tty>        "match by controlling terminal")
-                .action(ArgAction::Append),
+                .value_delimiter(','),
             // arg!(-u     --euid <ID>         ... "match by effective IDs"),
             // arg!(-U     --uid <ID>          ... "match by real IDs"),
             arg!(-x     --exact                 "match exactly with the command name"),


Test patch:
diff --git a/tests/by-util/test_pgrep.rs b/tests/by-util/test_pgrep.rs
index 7144da6..7595c06 100644
--- a/tests/by-util/test_pgrep.rs
+++ b/tests/by-util/test_pgrep.rs
@@ -253,8 +253,18 @@ fn test_terminal() {
     }
 }
 
+#[test]
 #[cfg(target_os = "linux")]
+fn test_terminal_multiple_terminals() {
+    new_ucmd!()
+        .arg("--terminal=tty1,?")
+        .arg("kthreadd")
+        .succeeds()
+        .stdout_matches(&Regex::new(SINGLE_PID).unwrap());
+}
+
 #[test]
+#[cfg(target_os = "linux")]
 fn test_unknown_terminal() {
     new_ucmd!().arg("--terminal=?").succeeds();
     new_ucmd!().arg("--terminal=?").arg("kthreadd").succeeds();
Repository: uutils/procps
Pull request #143 (2024-07-24 07:47:03)

pgrep: allow `--runstates` without pattern
This PR allows the use of `--runstates` without a pattern. It also turns a regex pattern into a `const` in the tests.


Patch:
diff --git a/src/uu/pgrep/src/pgrep.rs b/src/uu/pgrep/src/pgrep.rs
index baeef1e..b89b4e8 100644
--- a/src/uu/pgrep/src/pgrep.rs
+++ b/src/uu/pgrep/src/pgrep.rs
@@ -71,6 +71,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
 
     if (!settings.newest
         && !settings.oldest
+        && settings.runstates.is_none()
         && settings.older.is_none()
         && settings.terminal.is_none())
         && pattern.is_empty()
@@ -168,6 +169,7 @@ fn collect_matched_pids(settings: &Settings) -> Vec<ProcessInformation> {
                 (Some(arg_run_states), Ok(pid_state)) => {
                     arg_run_states.contains(&pid_state.to_string())
                 }
+                (_, Err(_)) => false,
                 _ => true,
             };
 


Test patch:
diff --git a/tests/by-util/test_pgrep.rs b/tests/by-util/test_pgrep.rs
index 7595c06..1aba87d 100644
--- a/tests/by-util/test_pgrep.rs
+++ b/tests/by-util/test_pgrep.rs
@@ -9,6 +9,9 @@ use regex::Regex;
 
 #[cfg(target_os = "linux")]
 const SINGLE_PID: &str = "^[1-9][0-9]*";
+#[cfg(target_os = "linux")]
+// (?m) enables multi-line mode
+const MULTIPLE_PIDS: &str = "(?m)^[1-9][0-9]*$";
 
 #[test]
 fn test_no_args() {
@@ -101,7 +104,7 @@ fn test_older() {
             .arg(arg)
             .arg("0")
             .succeeds()
-            .stdout_matches(&Regex::new("(?m)^[1-9][0-9]*$").unwrap());
+            .stdout_matches(&Regex::new(MULTIPLE_PIDS).unwrap());
     }
 }
 
@@ -112,7 +115,7 @@ fn test_older_matching_pattern() {
         .arg("--older=0")
         .arg("sh")
         .succeeds()
-        .stdout_matches(&Regex::new("(?m)^[1-9][0-9]*$").unwrap());
+        .stdout_matches(&Regex::new(MULTIPLE_PIDS).unwrap());
 }
 
 #[test]
@@ -249,7 +252,7 @@ fn test_terminal() {
             .arg("tty1")
             .arg("--inverse") // XXX hack to make test pass in CI
             .succeeds()
-            .stdout_matches(&Regex::new("(?m)^[1-9][0-9]*$").unwrap());
+            .stdout_matches(&Regex::new(MULTIPLE_PIDS).unwrap());
     }
 }
 
@@ -279,3 +282,25 @@ fn test_terminal_invalid_terminal() {
         .code_is(1)
         .no_output();
 }
+
+#[test]
+#[cfg(target_os = "linux")]
+fn test_runstates() {
+    for arg in ["-r", "--runstates"] {
+        new_ucmd!()
+            .arg(arg)
+            .arg("S")
+            .succeeds()
+            .stdout_matches(&Regex::new(MULTIPLE_PIDS).unwrap());
+    }
+}
+
+#[test]
+#[cfg(target_os = "linux")]
+fn test_runstates_invalid_runstate() {
+    new_ucmd!()
+        .arg("--runstates=invalid")
+        .fails()
+        .code_is(1)
+        .no_output();
+}
Repository: uutils/procps
Pull request #161 (2024-08-06 08:41:38)

Remove unnecessary `spell-checker:ignore` lines


Patch:
diff --git a/src/uu/slabtop/src/parse.rs b/src/uu/slabtop/src/parse.rs
index 0e038d3..6b1926b 100644
--- a/src/uu/slabtop/src/parse.rs
+++ b/src/uu/slabtop/src/parse.rs
@@ -2,7 +2,6 @@
 //
 // For the full copyright and license information, please view the LICENSE
 // file that was distributed with this source code.
-// spell-checker:ignore (words) symdir somefakedir
 
 use std::{
     cmp::Ordering,


Test patch:
diff --git a/tests/by-util/test_pmap.rs b/tests/by-util/test_pmap.rs
index c3afeaf..85ca6f4 100644
--- a/tests/by-util/test_pmap.rs
+++ b/tests/by-util/test_pmap.rs
@@ -2,7 +2,6 @@
 //
 // For the full copyright and license information, please view the LICENSE
 // file that was distributed with this source code.
-// spell-checker:ignore (words) symdir somefakedir
 
 use crate::common::util::TestScenario;
 
diff --git a/tests/by-util/test_pwdx.rs b/tests/by-util/test_pwdx.rs
index c3afeaf..85ca6f4 100644
--- a/tests/by-util/test_pwdx.rs
+++ b/tests/by-util/test_pwdx.rs
@@ -2,7 +2,6 @@
 //
 // For the full copyright and license information, please view the LICENSE
 // file that was distributed with this source code.
-// spell-checker:ignore (words) symdir somefakedir
 
 use crate::common::util::TestScenario;
 
diff --git a/tests/by-util/test_w.rs b/tests/by-util/test_w.rs
index 034f08c..d860a7e 100644
--- a/tests/by-util/test_w.rs
+++ b/tests/by-util/test_w.rs
@@ -2,7 +2,6 @@
 //
 // For the full copyright and license information, please view the LICENSE
 // file that was distributed with this source code.
-// spell-checker:ignore (words) symdir somefakedir
 
 use crate::common::util::TestScenario;
 
diff --git a/tests/by-util/test_watch.rs b/tests/by-util/test_watch.rs
index 72bb3be..f167162 100644
--- a/tests/by-util/test_watch.rs
+++ b/tests/by-util/test_watch.rs
@@ -2,7 +2,6 @@
 //
 // For the full copyright and license information, please view the LICENSE
 // file that was distributed with this source code.
-// spell-checker:ignore (words) symdir somefakedir
 
 use crate::common::util::TestScenario;
Repository: uutils/procps
Pull request #163 (2024-08-06 15:08:05)

pwdx: handle `0` as invalid PID
This PR changes the error message that's shown when `pwdx 0` is called. Now it matches the error message shown by the original `pwdx`
```
// before
$ cargo run pwdx 0
pwdx: failed to read link for PID 0: No such file or directory (os error 2)

// after
$ cargo run pwdx 0
pwdx: invalid process id: 0
```


Patch:
diff --git a/src/uu/pwdx/src/pwdx.rs b/src/uu/pwdx/src/pwdx.rs
index a7d603c..77a18e8 100644
--- a/src/uu/pwdx/src/pwdx.rs
+++ b/src/uu/pwdx/src/pwdx.rs
@@ -3,14 +3,13 @@
 // For the full copyright and license information, please view the LICENSE
 // file that was distributed with this source code.
 
-use clap::Arg;
-use clap::{crate_version, Command};
+use clap::{crate_version, Arg, Command};
 use std::env;
 use std::fs;
 use std::path::Path;
 use std::process;
-
-use uucore::{error::UResult, format_usage, help_about, help_usage};
+use uucore::error::{UResult, USimpleError};
+use uucore::{format_usage, help_about, help_usage};
 
 const ABOUT: &str = help_about!("pwdx.md");
 const USAGE: &str = help_usage!("pwdx.md");
@@ -20,10 +19,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
     let matches = uu_app().try_get_matches_from(args)?;
 
     let pid_str = matches.get_one::<String>("pid").unwrap();
-    let pid = pid_str.parse::<i32>().unwrap_or_else(|_| {
-        eprintln!("Invalid PID");
-        process::exit(1);
-    });
+    let pid = match pid_str.parse::<i32>() {
+        // PIDs start at 1, hence 0 is invalid
+        Ok(0) | Err(_) => {
+            return Err(USimpleError::new(
+                1,
+                format!("invalid process id: {pid_str}"),
+            ))
+        }
+        Ok(pid) => pid,
+    };
 
     let cwd_link = format!("/proc/{}/cwd", pid);
 


Test patch:
diff --git a/tests/by-util/test_pwdx.rs b/tests/by-util/test_pwdx.rs
index 85ca6f4..e89ae20 100644
--- a/tests/by-util/test_pwdx.rs
+++ b/tests/by-util/test_pwdx.rs
@@ -5,6 +5,18 @@
 
 use crate::common::util::TestScenario;
 
+#[test]
+fn test_invalid_pid() {
+    for invalid_pid in ["0", "invalid"] {
+        new_ucmd!()
+            .arg(invalid_pid)
+            .fails()
+            .code_is(1)
+            .no_stdout()
+            .stderr_contains(format!("invalid process id: {invalid_pid}"));
+    }
+}
+
 #[test]
 fn test_invalid_arg() {
     new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
Repository: uutils/procps
Pull request #168 (2024-08-08 14:39:00)

ps: fix alias for `-A` (use `-e` instead of `--e`)


Patch:
diff --git a/src/uu/ps/src/ps.rs b/src/uu/ps/src/ps.rs
index 6484917..6e2fb45 100644
--- a/src/uu/ps/src/ps.rs
+++ b/src/uu/ps/src/ps.rs
@@ -128,7 +128,7 @@ pub fn uu_app() -> Command {
             Arg::new("A")
                 .short('A')
                 .help("all processes")
-                .visible_alias("e")
+                .visible_short_alias('e')
                 .action(ArgAction::SetTrue),
             Arg::new("a")
                 .short('a')


Test patch:
diff --git a/tests/by-util/test_ps.rs b/tests/by-util/test_ps.rs
index ffc1f01..ab82612 100644
--- a/tests/by-util/test_ps.rs
+++ b/tests/by-util/test_ps.rs
@@ -5,6 +5,15 @@
 
 use crate::common::util::TestScenario;
 
+#[test]
+#[cfg(target_os = "linux")]
+fn test_select_all_processes() {
+    for arg in ["-A", "-e"] {
+        // TODO ensure the output format is correct
+        new_ucmd!().arg(arg).succeeds();
+    }
+}
+
 #[test]
 fn test_invalid_arg() {
     new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
Repository: uutils/procps
Pull request #197 (2024-08-21 09:39:28)

pmap: fix perms column & remove unnecessary columns
This PR fixes the "perms" column and removes unnecessary columns from the output when running `cargo run pmap <some PID>`.

Before the changes:
```
0000735e54227000      8K rw-p 00036000 08:08 10773308                   /usr/lib/ld-linux-x86-64.so.2
```
After the changes:
```
0000735e54227000      8K rw--- /usr/lib/ld-linux-x86-64.so.2
```
In comparison, the output of the original `pmap`:
```
0000735e54227000      8K rw--- ld-linux-x86-64.so.2
```


Patch:
diff --git a/src/uu/pmap/src/pmap.rs b/src/uu/pmap/src/pmap.rs
index b720e3a..b996a2f 100644
--- a/src/uu/pmap/src/pmap.rs
+++ b/src/uu/pmap/src/pmap.rs
@@ -59,7 +59,12 @@ fn parse_maps(pid: &str) -> Result<(), Error> {
         let (memory_range, rest) = line.split_once(' ').expect("line should contain ' '");
         let (start_address, size_in_kb) = parse_memory_range(memory_range);
 
-        println!("{start_address} {size_in_kb:>6}K {rest}");
+        let (perms, rest) = rest.split_once(' ').expect("line should contain 2nd ' '");
+        let perms = parse_perms(perms);
+
+        let cmd: String = rest.split_whitespace().skip(3).collect();
+
+        println!("{start_address} {size_in_kb:>6}K {perms} {cmd}");
     }
 
     Ok(())
@@ -82,6 +87,15 @@ fn parse_memory_range(memory_range: &str) -> (String, u64) {
     (format!("{start:0>16}"), size_in_kb)
 }
 
+// Turns a 4-char perms string from /proc/<PID>/maps into a 5-char perms string. The first three
+// chars are left untouched.
+fn parse_perms(perms: &str) -> String {
+    let perms = perms.replace("p", "-");
+
+    // the fifth char seems to be always '-' in the original pmap
+    format!("{perms}-")
+}
+
 pub fn uu_app() -> Command {
     Command::new(env!("CARGO_PKG_NAME"))
         .version(crate_version!())
@@ -178,4 +192,11 @@ mod test {
         assert_eq!(start, "00007ffc4f0c2000");
         assert_eq!(size, 132);
     }
+
+    #[test]
+    fn test_parse_perms() {
+        assert_eq!("-----", parse_perms("---p"));
+        assert_eq!("---s-", parse_perms("---s"));
+        assert_eq!("rwx--", parse_perms("rwxp"));
+    }
 }


Test patch:
diff --git a/tests/by-util/test_pmap.rs b/tests/by-util/test_pmap.rs
index 451957c..dfff913 100644
--- a/tests/by-util/test_pmap.rs
+++ b/tests/by-util/test_pmap.rs
@@ -30,7 +30,7 @@ fn test_existing_pid() {
 
     let rest = rest.trim_end();
     let (memory_map, last_line) = rest.rsplit_once('\n').unwrap();
-    let re = Regex::new("(?m)^[0-9a-f]{16} +[1-9][0-9]*K ").unwrap();
+    let re = Regex::new("(?m)^[0-9a-f]{16} +[1-9][0-9]*K (-|r)(-|w)(-|x)(-|s)- ").unwrap();
     assert!(re.is_match(memory_map));
     // TODO ensure that "total" is followed by a total amount
     assert!(last_line.starts_with(" total"));
Repository: uutils/procps
Pull request #202 (2024-08-26 13:26:17)

pmap: trim cmdline
This PR trims the return value of the `parse_cmdline` function.

Before the change, there is a space at the end of the output:
```
$ cargo run -q pmap 1 | tr " " "."
1:.../sbin/init.\vmlinuz-linux.
```
After the change:
```
$ cargo run -q pmap 1 | tr " " "."
1:.../sbin/init.\vmlinuz-linux
```


Patch:
diff --git a/src/uu/pmap/src/pmap.rs b/src/uu/pmap/src/pmap.rs
index 6e882aa..abb1224 100644
--- a/src/uu/pmap/src/pmap.rs
+++ b/src/uu/pmap/src/pmap.rs
@@ -48,7 +48,8 @@ fn parse_cmdline(pid: &str) -> Result<String, Error> {
         .filter_map(|c| std::str::from_utf8(c).ok())
         .collect::<Vec<&str>>()
         .join(" ");
-    Ok(cmdline)
+    let cmdline = cmdline.trim_end();
+    Ok(cmdline.into())
 }
 
 fn parse_maps(pid: &str) -> Result<(), Error> {


Test patch:
diff --git a/tests/by-util/test_pmap.rs b/tests/by-util/test_pmap.rs
index 776cf89..f526e04 100644
--- a/tests/by-util/test_pmap.rs
+++ b/tests/by-util/test_pmap.rs
@@ -25,7 +25,7 @@ fn test_existing_pid() {
         .stdout_move_str();
 
     let (first_line, rest) = result.split_once('\n').unwrap();
-    let re = Regex::new(&format!("^{pid}:   .+$")).unwrap();
+    let re = Regex::new(&format!("^{pid}:   .+[^ ]$")).unwrap();
     assert!(re.is_match(first_line));
 
     let rest = rest.trim_end();