[comp.lang.perl] Finding the PIDs of all decendants

timcc@csv.viccol.edu.au (Tim Cook) (06/08/91)

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 <master-pid>\n") ; exit (1) ; }

$master_pid = $ARGV[0] ;
while (length ($master_pid) < 5) {
   $master_pid = ' '. $master_pid ; }

open (PS, "/bin/ps axl |") || die ("ps") ;
$_ = <PS> ;		# Throw away ps header
while (<PS>) {
   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) ;