@@ -51,6 +51,7 @@ pub struct Settings {
5151
5252 pub pidfile : Option < String > ,
5353 pub logpidfile : bool ,
54+ pub ignore_ancestors : bool ,
5455}
5556
5657pub fn get_match_settings ( matches : & ArgMatches ) -> UResult < Settings > {
@@ -113,6 +114,7 @@ pub fn get_match_settings(matches: &ArgMatches) -> UResult<Settings> {
113114 threads : false ,
114115 pidfile : matches. get_one :: < String > ( "pidfile" ) . cloned ( ) ,
115116 logpidfile : matches. get_flag ( "logpidfile" ) ,
117+ ignore_ancestors : matches. get_flag ( "ignore-ancestors" ) ,
116118 } ;
117119
118120 if !settings. newest
@@ -196,26 +198,45 @@ fn any_matches<T: Eq + Hash>(optional_ids: &Option<HashSet<T>>, id: T) -> bool {
196198 optional_ids. as_ref ( ) . is_none_or ( |ids| ids. contains ( & id) )
197199}
198200
201+ fn get_ancestors ( process_infos : & mut [ ProcessInformation ] , mut pid : usize ) -> HashSet < usize > {
202+ let mut ret = HashSet :: from ( [ pid] ) ;
203+ while pid != 1 {
204+ if let Some ( process) = process_infos. iter_mut ( ) . find ( |p| p. pid == pid) {
205+ pid = process. ppid ( ) . unwrap ( ) as usize ;
206+ ret. insert ( pid) ;
207+ } else {
208+ break ;
209+ }
210+ }
211+ ret
212+ }
213+
199214/// Collect pids with filter construct from command line arguments
200215fn collect_matched_pids ( settings : & Settings ) -> UResult < Vec < ProcessInformation > > {
201216 // Filtration general parameters
202217 let filtered: Vec < ProcessInformation > = {
203218 let mut tmp_vec = Vec :: new ( ) ;
204219
205- let pids = if settings. threads {
220+ let mut pids = if settings. threads {
206221 walk_threads ( ) . collect :: < Vec < _ > > ( )
207222 } else {
208223 walk_process ( ) . collect :: < Vec < _ > > ( )
209224 } ;
210225 let our_pid = std:: process:: id ( ) as usize ;
226+ let ignored_pids = if settings. ignore_ancestors {
227+ get_ancestors ( & mut pids, our_pid)
228+ } else {
229+ HashSet :: from ( [ our_pid] )
230+ } ;
231+
211232 let pid_from_pidfile = settings
212233 . pidfile
213234 . as_ref ( )
214235 . map ( |filename| read_pidfile ( filename, settings. logpidfile ) )
215236 . transpose ( ) ?;
216237
217238 for mut pid in pids {
218- if pid. pid == our_pid {
239+ if ignored_pids . contains ( & pid. pid ) {
219240 continue ;
220241 }
221242
@@ -507,7 +528,7 @@ pub fn clap_args(pattern_help: &'static str, enable_v_flag: bool) -> Vec<Arg> {
507528 arg!( -F --pidfile <file> "read PIDs from file" ) ,
508529 arg!( -L --logpidfile "fail if PID file is not locked" ) ,
509530 arg!( -r --runstates <state> "match runstates [D,S,Z,...]" ) ,
510- // arg!(-A --"ignore-ancestors" "exclude our ancestors from results"),
531+ arg!( -A --"ignore-ancestors" "exclude our ancestors from results" ) ,
511532 arg!( --cgroup <grp> "match by cgroup v2 names" ) . value_delimiter( ',' ) ,
512533 // arg!(--ns <PID> "match the processes that belong to the same namespace as <pid>"),
513534 // arg!(--nslist <ns> "list which namespaces will be considered for the --ns option.")
0 commit comments