@@ -10,6 +10,8 @@ use clap::{arg, crate_version, Arg, ArgAction, ArgGroup, ArgMatches, Command};
1010use process:: { walk_process, ProcessInformation , Teletype } ;
1111use regex:: Regex ;
1212use std:: { collections:: HashSet , sync:: OnceLock } ;
13+ #[ cfg( unix) ]
14+ use uucore:: { display:: Quotable , signals:: signal_by_name_or_value} ;
1315use uucore:: {
1416 error:: { UResult , USimpleError } ,
1517 format_usage, help_about, help_usage,
@@ -87,9 +89,21 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
8789 ) ) ;
8890 }
8991
92+ // Parse signal
93+ #[ cfg( unix) ]
94+ let sig_num = parse_signal_value ( matches. get_one :: < String > ( "signal" ) . unwrap ( ) ) ?;
95+
9096 // Collect pids
9197 let pids = {
9298 let mut pids = collect_matched_pids ( & settings) ;
99+ #[ cfg( unix) ]
100+ if matches. get_flag ( "require-handler" ) {
101+ pids. retain ( |pid| {
102+ let mask =
103+ u64:: from_str_radix ( pid. clone ( ) . status ( ) . get ( "SigCgt" ) . unwrap ( ) , 16 ) . unwrap ( ) ;
104+ mask & ( 1 << sig_num) != 0
105+ } ) ;
106+ }
93107 if pids. is_empty ( ) {
94108 uucore:: error:: set_exit_code ( 1 ) ;
95109 pids
@@ -275,6 +289,12 @@ fn process_flag_o_n(
275289 }
276290}
277291
292+ #[ cfg( unix) ]
293+ fn parse_signal_value ( signal_name : & str ) -> UResult < usize > {
294+ signal_by_name_or_value ( signal_name)
295+ . ok_or_else ( || USimpleError :: new ( 1 , format ! ( "Unknown signal {}" , signal_name. quote( ) ) ) )
296+ }
297+
278298#[ allow( clippy:: cognitive_complexity) ]
279299pub fn uu_app ( ) -> Command {
280300 Command :: new ( uucore:: util_name ( ) )
@@ -289,6 +309,7 @@ pub fn uu_app() -> Command {
289309 . hide_default_value ( true ) ,
290310 arg ! ( -l --"list-name" "list PID and process name" ) ,
291311 arg ! ( -a --"list-full" "list PID and full command line" ) ,
312+ arg ! ( -H --"require-handler" "match only if signal handler is present" ) ,
292313 arg ! ( -v --inverse "negates the matching" ) ,
293314 // arg!(-w --lightweight "list all TID"),
294315 arg ! ( -c --count "count of matching processes" ) ,
@@ -310,7 +331,8 @@ pub fn uu_app() -> Command {
310331 // arg!(-s --session <SID> "match session IDs")
311332 // .value_delimiter(',')
312333 // .value_parser(clap::value_parser!(u64)),
313- // arg!(--signal <sig> "signal to send (either number or name)"),
334+ arg ! ( --signal <sig> "signal to send (either number or name)" )
335+ . default_value ( "SIGTERM" ) ,
314336 arg ! ( -t --terminal <tty> "match by controlling terminal" )
315337 . value_delimiter ( ',' ) ,
316338 // arg!(-u --euid <ID> ... "match by effective IDs")
0 commit comments