From eb0871abc751888f2227736bd0306d8dabff4735 Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Sun, 23 Mar 2025 21:21:33 +0200 Subject: [PATCH] process_matcher: Allow lone --require-handler option Make it possible to run `pgrep --require-handler` without any other matcher arguments. --- src/uu/pgrep/src/process_matcher.rs | 37 ++++++++++++++++------------- tests/by-util/test_pgrep.rs | 9 +++++++ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/uu/pgrep/src/process_matcher.rs b/src/uu/pgrep/src/process_matcher.rs index 1b5ad2d..6f1b85a 100644 --- a/src/uu/pgrep/src/process_matcher.rs +++ b/src/uu/pgrep/src/process_matcher.rs @@ -115,6 +115,7 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult { && settings.gid.is_none() && settings.pgroup.is_none() && settings.session.is_none() + && !settings.require_handler && pattern.is_empty() { return Err(USimpleError::new( @@ -138,21 +139,6 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult { pub fn find_matching_pids(settings: &Settings) -> Vec { let mut pids = collect_matched_pids(settings); - #[cfg(unix)] - if settings.require_handler { - // Bits in SigCgt are off by one (ie. bit 0 represents signal 1, etc.) - let mask_to_test = if settings.signal == 0 { - // In original pgrep, testing for signal 0 seems to return results for signal 64 instead. - 1 << (64 - 1) - } else { - 1 << (settings.signal - 1) - }; - pids.retain(|pid| { - let mask = - u64::from_str_radix(pid.clone().status().get("SigCgt").unwrap(), 16).unwrap(); - mask & mask_to_test != 0 - }); - } if pids.is_empty() { uucore::error::set_exit_code(1); pids @@ -254,6 +240,24 @@ fn collect_matched_pids(settings: &Settings) -> Vec { && any_matches(&settings.euid, pid.euid().unwrap()) && any_matches(&settings.gid, pid.gid().unwrap()); + #[cfg(unix)] + let handler_matched = if settings.require_handler { + // Bits in SigCgt are off by one (ie. bit 0 represents signal 1, etc.) + let mask_to_test = if settings.signal == 0 { + // In original pgrep, testing for signal 0 seems to return results for signal 64 instead. + 1 << (64 - 1) + } else { + 1 << (settings.signal - 1) + }; + let mask = + u64::from_str_radix(pid.clone().status().get("SigCgt").unwrap(), 16).unwrap(); + mask & mask_to_test != 0 + } else { + true + }; + #[cfg(not(unix))] + let handler_matched = true; + if (run_state_matched && pattern_matched && tty_matched @@ -261,7 +265,8 @@ fn collect_matched_pids(settings: &Settings) -> Vec { && parent_matched && pgroup_matched && session_matched - && ids_matched) + && ids_matched + && handler_matched) ^ settings.inverse { tmp_vec.push(pid); diff --git a/tests/by-util/test_pgrep.rs b/tests/by-util/test_pgrep.rs index 6317044..376eed7 100644 --- a/tests/by-util/test_pgrep.rs +++ b/tests/by-util/test_pgrep.rs @@ -380,6 +380,15 @@ fn test_signal_that_never_matches() { .no_output(); } +#[test] +#[cfg(target_os = "linux")] +fn test_lone_require_handler_is_allowed() { + new_ucmd!() + .arg("--require-handler") + .run() + .stderr_does_not_contain("no matching criteria specified"); +} + #[test] #[cfg(target_os = "linux")] fn test_does_not_match_pid() {