#!/bin/rc rfork e # get a sorted list of process in "ppid pid" format fn procs { {cd /proc; for (i in */ppid) {cat $i; echo $i | sed -e 's/\/ppid//'}} | sort -n } # create variables $pid. that contains all child processes fn collect { procs | while (pp=`{read}) { echo $pp(2) >> /env/pid.$pp(1) } } # print n spaces. fn spaces { for (i in `{seq 1 $1}) echo -n ' ' } # extract the proc name from /proc/$/status fn status { if (test -e /proc/$1) { dd -bs 1 -count 20 -quiet 1 < /proc/$1/status | tr -d ' \t' } echo -n ([$1]) } # recursively get the parent of the given pid. fn parent { switch ($1) { case 0 case * if (test -f /proc/$1/ppid) { parent `{cat /proc/$1/ppid} echo -n '->' } } status $1 } # recursively get the children of the given pid. # also passes in the number of levels of recursion so that # we can use it to print indentation fn children { spaces $2 ; echo -n '|-'; status $1 ; echo if (test -f /env/pid.^$1) { for (x in `{cat /env/pid.^$1}) { children $x `{echo $2 1 + p|dc} } } } fn usage { echo 'pstree -p pid' echo ' Show parents of the passed pid' echo 'pstree -c pid' echo ' Show children of the passed pid' } fn main { switch($1) { case -p collect parent $2 echo case -c collect children $2 0 case * usage } } main $*