44// file that was distributed with this source code.
55
66// Pid utils
7- use clap:: { arg, crate_version, Command } ;
7+ use clap:: { arg, crate_version, value_parser , Command } ;
88#[ cfg( unix) ]
99use nix:: {
1010 sys:: signal:: { self , Signal } ,
@@ -48,19 +48,21 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
4848 } else {
4949 let sig = ( settings. signal as i32 )
5050 . try_into ( )
51- . map_err ( |e| std :: io :: Error :: from_raw_os_error ( e as i32 ) ) ?;
51+ . map_err ( |e| Error :: from_raw_os_error ( e as i32 ) ) ?;
5252 Some ( sig)
5353 } ;
5454
5555 // Collect pids
5656 let pids = process_matcher:: find_matching_pids ( & settings) ?;
5757
5858 // Send signal
59- // TODO: Implement -q
6059 #[ cfg( unix) ]
61- let echo = matches. get_flag ( "echo" ) ;
62- #[ cfg( unix) ]
63- kill ( & pids, sig, echo) ;
60+ {
61+ let echo = matches. get_flag ( "echo" ) ;
62+ let queue = matches. get_one :: < u32 > ( "queue" ) . cloned ( ) ;
63+
64+ kill ( & pids, sig, queue, echo) ;
65+ }
6466
6567 if matches. get_flag ( "count" ) {
6668 println ! ( "{}" , pids. len( ) ) ;
@@ -71,25 +73,50 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
7173
7274#[ cfg( unix) ]
7375fn handle_obsolete ( args : & mut [ String ] ) {
74- // Sanity check
75- if args. len ( ) > 2 {
76- // Old signal can only be in the first argument position
77- let slice = args[ 1 ] . as_str ( ) ;
78- if let Some ( signal) = slice. strip_prefix ( '-' ) {
76+ for arg in & mut args[ 1 ..] {
77+ if let Some ( signal) = arg. strip_prefix ( '-' ) {
7978 // Check if it is a valid signal
8079 let opt_signal = signal_by_name_or_value ( signal) ;
8180 if opt_signal. is_some ( ) {
8281 // Replace with long option that clap can parse
83- args [ 1 ] = format ! ( "--signal={signal}" ) ;
82+ * arg = format ! ( "--signal={signal}" ) ;
8483 }
8584 }
8685 }
8786}
8887
88+ // Not contains in libc
89+ #[ cfg( target_os = "linux" ) ]
90+ extern "C" {
91+ fn sigqueue (
92+ pid : uucore:: libc:: pid_t ,
93+ sig : uucore:: libc:: c_int ,
94+ val : uucore:: libc:: sigval ,
95+ ) -> uucore:: libc:: c_int ;
96+ }
97+
8998#[ cfg( unix) ]
90- fn kill ( pids : & Vec < ProcessInformation > , sig : Option < Signal > , echo : bool ) {
99+ #[ allow( unused_variables) ]
100+ fn kill ( pids : & Vec < ProcessInformation > , sig : Option < Signal > , queue : Option < u32 > , echo : bool ) {
91101 for pid in pids {
92- if let Err ( e) = signal:: kill ( Pid :: from_raw ( pid. pid as i32 ) , sig) {
102+ #[ cfg( target_os = "linux" ) ]
103+ let result = if let Some ( queue) = queue {
104+ let v = unsafe {
105+ sigqueue (
106+ pid. pid as i32 ,
107+ sig. map_or ( 0 , |s| s as uucore:: libc:: c_int ) ,
108+ uucore:: libc:: sigval {
109+ sival_ptr : queue as usize as * mut uucore:: libc:: c_void ,
110+ } ,
111+ )
112+ } ;
113+ nix:: errno:: Errno :: result ( v) . map ( drop)
114+ } else {
115+ signal:: kill ( Pid :: from_raw ( pid. pid as i32 ) , sig)
116+ } ;
117+ #[ cfg( not( target_os = "linux" ) ) ]
118+ let result = signal:: kill ( Pid :: from_raw ( pid. pid as i32 ) , sig) ;
119+ if let Err ( e) = result {
93120 show ! ( Error :: from_raw_os_error( e as i32 )
94121 . map_err_context( || format!( "killing pid {} failed" , pid. pid) ) ) ;
95122 } else if echo {
@@ -111,7 +138,8 @@ pub fn uu_app() -> Command {
111138 . args_override_self ( true )
112139 . args ( [
113140 // arg!(-<sig> "signal to send (either number or name)"),
114- // arg!(-q --queue <value> "integer value to be sent with the signal"),
141+ arg ! ( -q --queue <value> "integer value to be sent with the signal" )
142+ . value_parser ( value_parser ! ( u32 ) ) ,
115143 arg ! ( -e --echo "display what is killed" ) ,
116144 ] )
117145 . args ( process_matcher:: clap_args (
0 commit comments