[comp.unix.programmer] Finding the PIDs of all decendants

mbl900@anusf.anu.edu.au (Mathew BM LIM) (05/17/91)

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?

-- 
Mathew Lim, Unix Systems Programmer, ANU Supercomputer Facility,	
Australian National University,	GPO Box 4, Canberra City, ACT, Australia 2601.
Telephone : +61 6 249 2750 	| ACSnet    : Mathew.BM.Lim@anu.oz
Fax       : +61 6 247 3425	| Internet  : Mathew.BM.Lim@anu.edu.au

boyd@prl.dec.com (Boyd Roberts) (05/17/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?
> 

ps axl | sed 1d | awk '
BEGIN {
		p = 0
		parent[p++] = pid
}

{
		for (i = 0; i < p; i++)
		{
			if (parent[i] == $3)
			{
				parent[p++] = $2
				print "proc " $2 " parent " $3
				break
			}
		}
		next
}' pid=$1


Boyd Roberts			boyd@prl.dec.com

``When the going gets wierd, the weird turn pro...''

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