From fb69db09e1180a8f7172e3a958b8d6354d0d4659 Mon Sep 17 00:00:00 2001 From: yushuoqi Date: Mon, 16 Feb 2026 10:32:03 +0800 Subject: [PATCH] pgrep: optimize length detection When calculating the length, the ^$ character needs to be removed if the -x parameter is present. Closes: #635 --- src/uu/pgrep/src/process_matcher.rs | 14 +++++++++++++- tests/by-util/test_pgrep.rs | 29 ++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/uu/pgrep/src/process_matcher.rs b/src/uu/pgrep/src/process_matcher.rs index 160af5e7..c991092d 100644 --- a/src/uu/pgrep/src/process_matcher.rs +++ b/src/uu/pgrep/src/process_matcher.rs @@ -151,8 +151,20 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult { pub fn find_matching_pids(settings: &Settings) -> UResult> { let mut pids = collect_matched_pids(settings)?; + let is_long_match = if settings.exact { + settings + .regex + .as_str() + .trim_matches('^') + .trim_matches('$') + .len() + > 15 + } else { + settings.regex.as_str().len() > 15 + }; + if pids.is_empty() { - if !settings.full && settings.regex.as_str().len() > 15 { + if !settings.full && is_long_match { 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)); diff --git a/tests/by-util/test_pgrep.rs b/tests/by-util/test_pgrep.rs index 85b16ad8..9d7ea391 100644 --- a/tests/by-util/test_pgrep.rs +++ b/tests/by-util/test_pgrep.rs @@ -654,7 +654,6 @@ fn test_pidfile_fcntl_locked() { // spawn a flock process that locks the file let mut flock_process = Command::new("flock") - .arg("--fcntl") .arg(temp_file.path()) .arg("sleep") .arg("2") @@ -718,3 +717,31 @@ fn test_env_multiple_filters() { // Multiple filters use OR logic new_ucmd!().arg("--env=PATH,NONEXISTENT").succeeds(); } + +#[test] +#[cfg(target_os = "linux")] +fn test_exact_long_pattern_no_match() { + new_ucmd!() + .arg("-x") + .arg("12345678901234") + .fails() + .code_is(1); +} + +#[test] +fn test_pattern_longer_than_15_characters() { + new_ucmd!() + .arg("1234567890123456") + .fails() + .code_is(1) + .stderr_contains("longer than 15 characters"); +} + +#[test] +#[cfg(target_os = "linux")] +fn test_pool_workqueue_release() { + new_ucmd!() + .arg("pool_workqueue_release") + .succeeds() + .stdout_matches(&Regex::new(MULTIPLE_PIDS).unwrap()); +}