Xref: utzoo comp.unix.programmer:2018 comp.lang.perl:5620 Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!ucsd!orion.oac.uci.edu!cerritos.edu!arizona.edu!arizona!noao!ncar!elroy.jpl.nasa.gov!swrinde! zaphod.mps.ohio-state.edu!rpi!batcomputer!munnari.oz.au!murtoa.cs.mu.oz.au!csv.viccol.edu.au!timcc From: timcc@csv.viccol.edu.au (Tim Cook) Newsgroups: comp.unix.programmer,comp.lang.perl Subject: Re: Finding the PIDs of all decendants (source) Message-ID: <1991Jun7.183530.6706@csv.viccol.edu.au> Date: 7 Jun 91 23:35:30 GMT References: <1991May17.130543@anusf.anu.edu.au> Organization: Computer Services, Victoria College, Melbourne Lines: 50 In article <1991May17.130543@anusf.anu.edu.au>, mbl900@anusf.anu.edu.au (Mathew BM LIM) writes: > Has anyone got some C code which, given a PID, will (recursively) create > an array of the PIDs of all it's decendants? > > If not, have you any ideas as to how to implement this? Sorry I was a bit slow in seeing this, but try this on for size. Not only does it find all descendants of a given process, it also attempts to kill the process and its dependants. This may not be portable to systems on which "ps axl" does not produce what it does on BSD unix (adjust the two "substr" calls to suit). #!/usr/local/bin/perl # master_kill - Kill (SIGKILL) a process and all its descendants # # $Header: /cs/source/misc/master_kill,v 1.1 91/06/07 18:35:02 timcc Exp $ if ($#ARGV != 0) { print (STDERR "Usage: $0 \n") ; exit (1) ; } $master_pid = $ARGV[0] ; while (length ($master_pid) < 5) { $master_pid = ' '. $master_pid ; } open (PS, "/bin/ps axl |") || die ("ps") ; $_ = ; # Throw away ps header while () { push (@pids, substr ($_, 12, 5)) ; push (@parent_pids, substr ($_, 18, 5)) ; } close (PS) ; $before = $#pids_to_kill ; push (@pids_to_kill, $master_pid) ; while ($#pids_to_kill > $before) { $before = $#pids_to_kill ; for ($i = 0 ; $i <= $#pids ; $i++) { if (index ('/' . join ('/', @pids_to_kill) . '/', '/' . $parent_pids[$i] . '/') != -1) { # This process is a descendant of one we want to kill if (index ('/' . join ('/', @pids_to_kill) . '/', '/' . $pids[$i] . '/') == -1) { # This process has not already been added to the list push (@pids_to_kill, $pids[$i]) ; } } } } # Do the dirty work # print ("Processes to be killed:\n", join ("\n", @pids_to_kill), "\n") ; kill (9, @pids_to_kill) ;