Pstree is a clone of the standard Linux pstree command, which displays process information in a heirarchical fashion. It builds and runs on SLS linux, RedHat linux (tested rhel3,centos 7), Debian linux, FreeBSD (tested on 4.4 & 4.8,) MacOS 10.4 through 10.12, and Minix 3. Unlike the standard pstree, it uses either sysctl() [macOS], kvm_getprocs() [FreeBSD 4.?] or /proc [SLS linux] as needed.

pstree is free software; it is released under a BSD-style license that allows you to do as you wish with it as long as you don’t attempt to claim it as your own work.

To install pstree, do

    $ ./
    $ make

then become root and do

    # make install

If pstree needs to use sysctl() or kvm_getprocs() to read process information, it will be installed as a setuid process to allow it to read all of the process data.

Source Code

A small handful of tweaks to catch up to changes in MacOS (echo bit me again, so I modified to generate a local echo command that does echo -n properly), support for Minix 3.3 (new /proc filesystem support), and a couple of bugfixes to deal with zero-length command lines.)

FreeBSD 7.1 changed some of its kernel data structures, which made the whole kvm_… world just stop working. After extensive work with grep, I figured out what had become of them and modified ps-etc to work here.

And then I found a bug in the BSD support, in that if a process modified its command line, those changes wouldn’t show up in pstree -a. It turns out that modified command lines end up in argv[0], which I was clipping off in favor of the kinfo_proc process name. So I had to redo that code to use argv[0] instead, and as a side-effect of that I was able to track changes in command names, so I can do the same thing that FreeBSD does with ps -a and put a (command) suffix onto the output if argv[0] was actually changed.


On top of all that, I modified the way commandlines are printed to have embedded spaces display as spaces instead of \040 – the -s option disables that new feature if you wish to see the old behavior.

basename() on the BSDs uses a static buffer to hold the new basename. This makes it pretty much impossible to use basename() for anything non-trivial unless you surround it with a strdup() wrapper. The 0.5 release corrects this misfeature by replacing basename() with a local function.
  1. Internal range checking to take away the fun of having a setuid program possibly doing a stack overrun and giving J. Random. Hacker a free doorway to root privileges.
  2. Implement the -A option (like -a, except it shows, if possible, the full pathname to the program name.)
  3. Try to automatically configure whether to look at /proc or use sysctl() or kvm_getprocs().
A README file, support for the -l option, automatic window width detection, more work on sysctl() vs kvm_getprocs() so that it will work on FreeBSD versions that don’t support kvm_getprocs() anymore.
The first release that works on more than one platform; 0.2 works on FreeBSD 4.x and SLS linux, and doesn’t have an embarrassing number of misfeatures and/or bugs.
The initial release, which almost works on SLS linux.