@@ -21,6 +21,8 @@ use parser::{parser, OptionalKeyValue};
2121use prettytable:: { format:: consts:: FORMAT_CLEAN , Row , Table } ;
2222use process_selection:: ProcessSelectionSettings ;
2323use std:: cell:: RefCell ;
24+ #[ cfg( unix) ]
25+ use uucore:: entries:: { grp2gid, usr2uid} ;
2426use uucore:: {
2527 error:: { UError , UResult , USimpleError } ,
2628 format_usage, help_about, help_usage,
@@ -29,6 +31,22 @@ use uucore::{
2931const ABOUT : & str = help_about ! ( "ps.md" ) ;
3032const USAGE : & str = help_usage ! ( "ps.md" ) ;
3133
34+ #[ cfg( not( unix) ) ]
35+ pub fn usr2uid ( _name : & str ) -> std:: io:: Result < u32 > {
36+ Err ( std:: io:: Error :: new (
37+ std:: io:: ErrorKind :: InvalidInput ,
38+ "unsupported on this platform" ,
39+ ) )
40+ }
41+
42+ #[ cfg( not( unix) ) ]
43+ pub fn grp2gid ( _name : & str ) -> std:: io:: Result < u32 > {
44+ Err ( std:: io:: Error :: new (
45+ std:: io:: ErrorKind :: InvalidInput ,
46+ "unsupported on this platform" ,
47+ ) )
48+ }
49+
3250#[ uucore:: main]
3351pub fn uumain ( args : impl uucore:: Args ) -> UResult < ( ) > {
3452 let matches = uu_app ( ) . try_get_matches_from ( args) ?;
@@ -138,15 +156,45 @@ fn collect_format(
138156 Ok ( collect)
139157}
140158
141- fn parse_numeric_list ( s : & str ) -> Result < Vec < usize > , String > {
159+ fn split_arg_list ( s : & str ) -> impl Iterator < Item = & str > {
142160 s. split ( |c : char | c. is_whitespace ( ) || c == ',' )
161+ }
162+
163+ fn parse_numeric_list ( s : & str ) -> Result < Vec < usize > , String > {
164+ split_arg_list ( s)
143165 . map ( |word| {
144166 word. parse :: < usize > ( )
145167 . map_err ( |_| format ! ( "invalid number: '{}'" , word) )
146168 } )
147169 . collect ( )
148170}
149171
172+ fn parse_uid_list ( s : & str ) -> Result < Vec < u32 > , String > {
173+ split_arg_list ( s)
174+ . map ( |uid_or_username| {
175+ uid_or_username
176+ . parse :: < u32 > ( )
177+ . or_else ( |_| usr2uid ( uid_or_username) )
178+ . map_err ( |_| format ! ( "invalid user name '{}'" , uid_or_username) )
179+ } )
180+ . collect ( )
181+ }
182+
183+ fn parse_gid_list ( s : & str ) -> Result < Vec < u32 > , String > {
184+ split_arg_list ( s)
185+ . map ( |gid_or_group_name| {
186+ gid_or_group_name
187+ . parse :: < u32 > ( )
188+ . or_else ( |_| grp2gid ( gid_or_group_name) )
189+ . map_err ( |_| format ! ( "invalid group name '{}'" , gid_or_group_name) )
190+ } )
191+ . collect ( )
192+ }
193+
194+ fn parse_command_list ( s : & str ) -> Result < Vec < String > , String > {
195+ Ok ( split_arg_list ( s) . map ( |part| part. to_string ( ) ) . collect ( ) )
196+ }
197+
150198#[ allow( clippy:: cognitive_complexity) ]
151199pub fn uu_app ( ) -> Command {
152200 Command :: new ( uucore:: util_name ( ) )
@@ -271,6 +319,13 @@ pub fn uu_app() -> Command {
271319 . action ( ArgAction :: SetTrue )
272320 . help ( "do not print header at all" ) ,
273321 )
322+ . arg (
323+ Arg :: new ( "command" )
324+ . short ( 'C' )
325+ . action ( ArgAction :: Append )
326+ . value_parser ( parse_command_list)
327+ . help ( "select by command name" ) ,
328+ )
274329 . arg (
275330 Arg :: new ( "pid" )
276331 . short ( 'p' )
@@ -279,33 +334,57 @@ pub fn uu_app() -> Command {
279334 . value_parser ( parse_numeric_list)
280335 . help ( "select by process ID" ) ,
281336 )
337+ . arg (
338+ Arg :: new ( "ppid" )
339+ . long ( "ppid" )
340+ . action ( ArgAction :: Append )
341+ . value_parser ( parse_numeric_list)
342+ . help ( "select by parent process ID" ) ,
343+ )
344+ . arg (
345+ Arg :: new ( "sid" )
346+ . long ( "sid" )
347+ . action ( ArgAction :: Append )
348+ . value_parser ( parse_numeric_list)
349+ . help ( "select by session ID" ) ,
350+ )
351+ . arg (
352+ Arg :: new ( "real-group" )
353+ . short ( 'G' )
354+ . long ( "Group" )
355+ . action ( ArgAction :: Append )
356+ . value_parser ( parse_gid_list)
357+ . help ( "select by real group ID (RGID) or name" ) ,
358+ )
359+ . arg (
360+ Arg :: new ( "effective-group" )
361+ . short ( 'g' )
362+ . long ( "group" )
363+ . action ( ArgAction :: Append )
364+ . value_parser ( parse_gid_list)
365+ . help ( "select by effective group ID (EGID) or name" ) ,
366+ )
367+ . arg (
368+ Arg :: new ( "real-user" )
369+ . short ( 'U' )
370+ . long ( "User" )
371+ . action ( ArgAction :: Append )
372+ . value_parser ( parse_uid_list)
373+ . help ( "select by real user ID (RUID) or name" ) ,
374+ )
375+ . arg (
376+ Arg :: new ( "effective-user" )
377+ . long ( "user" )
378+ . action ( ArgAction :: Append )
379+ . value_parser ( parse_uid_list)
380+ . help ( "select by effective user ID (EUID) or name" ) ,
381+ )
282382 // .args([
283- // Arg::new("command").short('c').help("command name"),
284- // Arg::new("GID")
285- // .short('G')
286- // .long("Group")
287- // .help("real group id or name"),
288- // Arg::new("group")
289- // .short('g')
290- // .long("group")
291- // .help("session or effective group name"),
292383 // Arg::new("pPID").long("ppid").help("parent process id"),
293384 // Arg::new("qPID")
294385 // .short('q')
295386 // .long("quick-pid")
296387 // .help("process id"),
297- // Arg::new("session")
298- // .short('s')
299- // .long("sid")
300- // .help("session id"),
301388 // Arg::new("t").short('t').long("tty").help("terminal"),
302- // Arg::new("eUID")
303- // .short('u')
304- // .long("user")
305- // .help("effective user id or name"),
306- // Arg::new("rUID")
307- // .short('U')
308- // .long("User")
309- // .help("real user id or name"),
310389 // ])
311390}
0 commit comments