#!/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.<pidnum> 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 $*
|