@@ -11,6 +11,8 @@ use std::{collections::HashSet, io};
1111use clap:: { arg, Arg , ArgAction , ArgMatches } ;
1212use regex:: Regex ;
1313#[ cfg( unix) ]
14+ use uucore:: libc:: { getpgrp, getsid} ;
15+ #[ cfg( unix) ]
1416use uucore:: {
1517 display:: Quotable ,
1618 entries:: { grp2gid, usr2uid} ,
@@ -40,6 +42,8 @@ pub struct Settings {
4042 pub uid : Option < HashSet < u32 > > ,
4143 pub euid : Option < HashSet < u32 > > ,
4244 pub gid : Option < HashSet < u32 > > ,
45+ pub pgroup : Option < HashSet < u64 > > ,
46+ pub session : Option < HashSet < u64 > > ,
4347}
4448
4549pub fn get_match_settings ( matches : & ArgMatches ) -> UResult < Settings > {
@@ -76,6 +80,26 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> {
7680 gid : matches
7781 . get_many :: < u32 > ( "group" )
7882 . map ( |ids| ids. cloned ( ) . collect ( ) ) ,
83+ pgroup : matches. get_many :: < u64 > ( "pgroup" ) . map ( |xs| {
84+ xs. map ( |pg| {
85+ if * pg == 0 {
86+ unsafe { getpgrp ( ) as u64 }
87+ } else {
88+ * pg
89+ }
90+ } )
91+ . collect ( )
92+ } ) ,
93+ session : matches. get_many :: < u64 > ( "session" ) . map ( |xs| {
94+ xs. map ( |sid| {
95+ if * sid == 0 {
96+ unsafe { getsid ( 0 ) as u64 }
97+ } else {
98+ * sid
99+ }
100+ } )
101+ . collect ( )
102+ } ) ,
79103 } ;
80104
81105 if !settings. newest
@@ -87,6 +111,8 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> {
87111 && settings. uid . is_none ( )
88112 && settings. euid . is_none ( )
89113 && settings. gid . is_none ( )
114+ && settings. pgroup . is_none ( )
115+ && settings. session . is_none ( )
90116 && pattern. is_empty ( )
91117 {
92118 return Err ( USimpleError :: new (
@@ -207,6 +233,8 @@ fn collect_matched_pids(settings: &Settings) -> Vec<ProcessInformation> {
207233 let older_matched = pid. start_time ( ) . unwrap ( ) >= arg_older;
208234
209235 let parent_matched = any_matches ( & settings. parent , pid. ppid ( ) . unwrap ( ) ) ;
236+ let pgroup_matched = any_matches ( & settings. pgroup , pid. pgid ( ) . unwrap ( ) ) ;
237+ let session_matched = any_matches ( & settings. session , pid. sid ( ) . unwrap ( ) ) ;
210238
211239 let ids_matched = any_matches ( & settings. uid , pid. uid ( ) . unwrap ( ) )
212240 && any_matches ( & settings. euid , pid. euid ( ) . unwrap ( ) )
@@ -217,6 +245,8 @@ fn collect_matched_pids(settings: &Settings) -> Vec<ProcessInformation> {
217245 && tty_matched
218246 && older_matched
219247 && parent_matched
248+ && pgroup_matched
249+ && session_matched
220250 && ids_matched)
221251 ^ settings. inverse
222252 {
@@ -290,6 +320,22 @@ pub fn grp2gid(_name: &str) -> io::Result<u32> {
290320 ) )
291321}
292322
323+ /// # Safety
324+ ///
325+ /// Dummy implementation for unsupported platforms.
326+ #[ cfg( not( unix) ) ]
327+ pub unsafe fn getpgrp ( ) -> u32 {
328+ panic ! ( "unsupported on this platform" ) ;
329+ }
330+
331+ /// # Safety
332+ ///
333+ /// Dummy implementation for unsupported platforms.
334+ #[ cfg( not( unix) ) ]
335+ pub unsafe fn getsid ( _pid : u32 ) -> u32 {
336+ panic ! ( "unsupported on this platform" ) ;
337+ }
338+
293339fn parse_uid_or_username ( uid_or_username : & str ) -> io:: Result < u32 > {
294340 uid_or_username
295341 . parse :: < u32 > ( )
@@ -315,9 +361,9 @@ pub fn clap_args(pattern_help: &'static str, enable_v_flag: bool) -> Vec<Arg> {
315361 arg!( -H --"require-handler" "match only if signal handler is present" ) ,
316362 arg!( -c --count "count of matching processes" ) ,
317363 arg!( -f --full "use full process name to match" ) ,
318- // arg!(-g --pgroup <PGID> "match listed process group IDs")
319- // .value_delimiter(',')
320- // .value_parser(clap::value_parser!(u64)),
364+ arg!( -g --pgroup <PGID > "match listed process group IDs" )
365+ . value_delimiter( ',' )
366+ . value_parser( clap:: value_parser!( u64 ) ) ,
321367 arg!( -G --group <GID > "match real group IDs" )
322368 . value_delimiter( ',' )
323369 . value_parser( parse_gid_or_group_name) ,
@@ -331,9 +377,9 @@ pub fn clap_args(pattern_help: &'static str, enable_v_flag: bool) -> Vec<Arg> {
331377 arg!( -P --parent <PPID > "match only child processes of the given parent" )
332378 . value_delimiter( ',' )
333379 . value_parser( clap:: value_parser!( u64 ) ) ,
334- // arg!(-s --session <SID> "match session IDs")
335- // .value_delimiter(',')
336- // .value_parser(clap::value_parser!(u64)),
380+ arg!( -s --session <SID > "match session IDs" )
381+ . value_delimiter( ',' )
382+ . value_parser( clap:: value_parser!( u64 ) ) ,
337383 arg!( --signal <sig> "signal to send (either number or name)" )
338384 . default_value( "SIGTERM" ) ,
339385 arg!( -t --terminal <tty> "match by controlling terminal" ) . value_delimiter( ',' ) ,
0 commit comments