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) ;