From fc2e066ca0cb3c861d3f80560ee862a735498e3b Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Tue, 7 Nov 2017 00:52:05 +0100 Subject: [PATCH] cmd: import pstree from 9front --- sys/src/cmd/cmds.json | 1 + sys/src/cmd/pstree.c | 184 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 sys/src/cmd/pstree.c diff --git a/sys/src/cmd/cmds.json b/sys/src/cmd/cmds.json index 2194b31..a8b0f03 100644 --- a/sys/src/cmd/cmds.json +++ b/sys/src/cmd/cmds.json @@ -40,6 +40,7 @@ "p.c", "pipefile.c", "ps.c", + "pstree.c", "pwd.c", "ramfs.c", "rm.c", diff --git a/sys/src/cmd/pstree.c b/sys/src/cmd/pstree.c new file mode 100644 index 0000000..8618095 --- /dev/null +++ b/sys/src/cmd/pstree.c @@ -0,0 +1,184 @@ +#include +#include +#include + +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 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); +}