@@ -23,7 +23,7 @@ use uucore::{
2323
2424use uucore:: error:: { UResult , USimpleError } ;
2525
26- use crate :: process:: { walk_process, walk_threads, ProcessInformation , Teletype } ;
26+ use crate :: process:: { walk_process, walk_threads, Namespace , ProcessInformation , Teletype } ;
2727
2828pub struct Settings {
2929 pub regex : Regex ,
@@ -47,6 +47,7 @@ pub struct Settings {
4747 pub pgroup : Option < HashSet < u64 > > ,
4848 pub session : Option < HashSet < u64 > > ,
4949 pub cgroup : Option < HashSet < String > > ,
50+ pub namespaces : Option < Namespace > ,
5051 pub env : Option < HashSet < String > > ,
5152 pub threads : bool ,
5253
@@ -112,6 +113,17 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> {
112113 cgroup : matches
113114 . get_many :: < String > ( "cgroup" )
114115 . map ( |groups| groups. cloned ( ) . collect ( ) ) ,
116+ namespaces : matches
117+ . get_one :: < usize > ( "ns" )
118+ . map ( |pid| {
119+ get_namespaces (
120+ * pid,
121+ matches
122+ . get_many :: < String > ( "nslist" )
123+ . map ( |v| v. into_iter ( ) . map ( |s| s. as_str ( ) ) . collect ( ) ) ,
124+ )
125+ } )
126+ . transpose ( ) ?,
115127 env : matches
116128 . get_many :: < String > ( "env" )
117129 . map ( |env_vars| env_vars. cloned ( ) . collect ( ) ) ,
@@ -133,6 +145,7 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> {
133145 && settings. pgroup . is_none ( )
134146 && settings. session . is_none ( )
135147 && settings. cgroup . is_none ( )
148+ && settings. namespaces . is_none ( )
136149 && settings. env . is_none ( )
137150 && !settings. require_handler
138151 && settings. pidfile . is_none ( )
@@ -216,6 +229,22 @@ fn get_ancestors(process_infos: &mut [ProcessInformation], mut pid: usize) -> Ha
216229 ret
217230}
218231
232+ #[ cfg( target_os = "linux" ) ]
233+ fn get_namespaces ( pid : usize , list : Option < Vec < & str > > ) -> UResult < Namespace > {
234+ let mut ns = Namespace :: from_pid ( pid)
235+ . map_err ( |_| USimpleError :: new ( 1 , "Error reading reference namespace information" ) ) ?;
236+ if let Some ( list) = list {
237+ ns. filter ( & list) ;
238+ }
239+
240+ Ok ( ns)
241+ }
242+
243+ #[ cfg( not( target_os = "linux" ) ) ]
244+ fn get_namespaces ( _pid : usize , _list : Option < Vec < & str > > ) -> UResult < Namespace > {
245+ Ok ( Namespace :: new ( ) )
246+ }
247+
219248/// Collect pids with filter construct from command line arguments
220249fn collect_matched_pids ( settings : & Settings ) -> UResult < Vec < ProcessInformation > > {
221250 // Filtration general parameters
@@ -283,6 +312,10 @@ fn collect_matched_pids(settings: &Settings) -> UResult<Vec<ProcessInformation>>
283312 & settings. cgroup ,
284313 pid. cgroup_v2_path ( ) . unwrap_or ( "/" . to_string ( ) ) ,
285314 ) ;
315+ let namespace_matched = settings
316+ . namespaces
317+ . as_ref ( )
318+ . is_none_or ( |ns| ns. matches ( & pid. namespaces ( ) . unwrap_or_default ( ) ) ) ;
286319
287320 let env_matched = match & settings. env {
288321 Some ( env_filters) => {
@@ -331,6 +364,7 @@ fn collect_matched_pids(settings: &Settings) -> UResult<Vec<ProcessInformation>>
331364 && pgroup_matched
332365 && session_matched
333366 && cgroup_matched
367+ && namespace_matched
334368 && env_matched
335369 && ids_matched
336370 && handler_matched
@@ -552,10 +586,11 @@ pub fn clap_args(pattern_help: &'static str, enable_v_flag: bool) -> Vec<Arg> {
552586 arg!( -A --"ignore-ancestors" "exclude our ancestors from results" ) ,
553587 arg!( --cgroup <grp> "match by cgroup v2 names" ) . value_delimiter( ',' ) ,
554588 arg!( --env <"name[=val],..." > "match on environment variable" ) . value_delimiter( ',' ) ,
555- // arg!(--ns <PID> "match the processes that belong to the same namespace as <pid>"),
556- // arg!(--nslist <ns> "list which namespaces will be considered for the --ns option.")
557- // .value_delimiter(',')
558- // .value_parser(["ipc", "mnt", "net", "pid", "user", "uts"]),
589+ arg!( --ns <PID > "match the processes that belong to the same namespace as <pid>" )
590+ . value_parser( clap:: value_parser!( usize ) ) ,
591+ arg!( --nslist <ns> "list which namespaces will be considered for the --ns option." )
592+ . value_delimiter( ',' )
593+ . value_parser( [ "ipc" , "mnt" , "net" , "pid" , "user" , "uts" ] ) ,
559594 Arg :: new( "pattern" )
560595 . help( pattern_help)
561596 . action( ArgAction :: Append )
0 commit comments