process_matcher: Fix accidentally matching against pid

Currently pgrep/pkill without -x/-f flags is matching based on the first
15 characters of /proc/<pid>/stat, which actually contains something like
"1116878 (cat) R" thus matching the process id when it should just match
on the name.

This has probably come from misunderstanding the comment from manpage:

> The process name used for matching is limited to the 15 characters
> present in the output of /proc/pid/stat.

... which doesn't mean pgrep/pkill is literally matching on 15
characters of /proc/<pid>/stat but that the process name in that file is
truncated to 15 characters.

Fixes #307
This commit is contained in:
Tuomas Tynkkynen
2025-02-19 01:48:00 +02:00
parent a2d49d6d03
commit 43f7412e74
2 changed files with 10 additions and 9 deletions
+3 -9
View File
@@ -160,18 +160,12 @@ fn collect_matched_pids(settings: &Settings) -> Vec<ProcessInformation> {
name.into()
};
let pattern_matched = {
let want = if settings.exact {
// Equals `Name` in /proc/<pid>/status
// The `unwrap` operation must succeed
// because the REGEX has been verified as correct in `uumain`.
&name
} else if settings.full {
let want = if settings.full {
// Equals `cmdline` in /proc/<pid>/cmdline
&pid.cmdline
} else {
// From manpage:
// The process name used for matching is limited to the 15 characters present in the output of /proc/pid/stat.
&pid.proc_stat()[..15]
// Equals `Name` in /proc/<pid>/status
&name
};
settings.regex.is_match(want)
+7
View File
@@ -369,6 +369,13 @@ fn test_invalid_signal() {
.stderr_contains("Unknown signal 'foo'");
}
#[test]
#[cfg(target_os = "linux")]
fn test_does_not_match_pid() {
let our_pid = std::process::id();
new_ucmd!().arg(our_pid.to_string()).fails();
}
#[test]
#[cfg(target_os = "linux")]
fn test_too_long_pattern() {