ref: 24e73840072b4214b3c5e2167a85bdc408fd3b03
dir: /sys/src/cmd/pstree.c/
#include <u.h> #include <libc.h> #include <bio.h> typedef struct Proc Proc; struct Proc { int pid; Proc *first, *parent, *next; Proc *hash; }; Proc *hash[1024]; Rune buf[512]; Biobuf bout; Proc * getproc(int pid) { Proc *p; for(p = hash[pid % nelem(hash)]; p; p = p->hash) if(p->pid == pid) return p; return nil; } void addproc(int pid) { Proc *p; p = mallocz(sizeof(*p), 1); if(p == nil) sysfatal("malloc: %r"); p->pid = pid; p->hash = hash[pid % nelem(hash)]; hash[pid % nelem(hash)] = p; } int theppid(int pid) { char b[128]; int fd, ppid; ppid = 0; snprint(b, sizeof(b), "%d/ppid", pid); fd = open(b, OREAD); if(fd >= 0){ memset(b, 0, sizeof b); if(read(fd, b, sizeof b-1) >= 0){ ppid = atoi(b); if(ppid < 0) ppid = 0; } close(fd); } return ppid; } void addppid(int pid) { Proc *p, *par, **l; p = getproc(pid); par = getproc(theppid(pid)); if(par == nil) par = getproc(0); p->parent = par; for(l = &par->first; *l; l = &((*l)->next)) if((*l)->pid > pid) break; p->next = *l; *l = p; } void addprocs(void) { int fd, rc, i; Dir *d; fd = open(".", OREAD); if(fd < 0) sysfatal("open: %r"); rc = dirreadall(fd, &d); if(rc < 0) sysfatal("dirreadall: %r"); close(fd); for(i = 0; i < rc; i++) if(d[i].mode & DMDIR) addproc(atoi(d[i].name)); for(i = 0; i < rc; i++) if(d[i].mode & DMDIR) addppid(atoi(d[i].name)); free(d); } int readout(char *file) { int fd, rc, i, n; char b[512]; fd = open(file, OREAD); if(fd < 0) return -1; n = 0; while((rc = read(fd, b, sizeof b)) > 0){ for(i=0; i<rc; i++) if(b[i] == '\n') b[i] = ' '; n += Bwrite(&bout, b, rc); } close(fd); return n; } void printargs(int pid) { char b[128], *p; int fd; snprint(b, sizeof(b), "%d/args", pid); if(readout(b) > 0) return; snprint(b, sizeof(b), "%d/status", pid); fd = open(b, OREAD); if(fd >= 0){ memset(b, 0, sizeof b); if(read(fd, b, 27) > 0){ p = b + strlen(b); while(p > b && p[-1] == ' ') *--p = 0; Bprint(&bout, "%s", b); } close(fd); } } void descend(Proc *p, Rune *r) { Rune last; Proc *q; last = *--r; *r = last == L' ' ? L'└' : L'├'; if(p->pid != 0){ Bprint(&bout, "%-11d %S", p->pid, buf); printargs(p->pid); Bprint(&bout, "\n"); } *r = last; *++r = L'│'; for(q = p->first; q; q = q->next) { if(q->next == nil) *r = L' '; descend(q, r + 1); } *r = 0; } void printprocs(void) { descend(getproc(0), buf); } void main() { Binit(&bout, 1, OWRITE); if(chdir("/proc")==-1) sysfatal("chdir: %r"); addproc(0); addprocs(); printprocs(); exits(0); }