diff options
| author | cinap_lenrek <cinap_lenrek@localhost> | 2011-06-27 23:01:53 +0000 |
|---|---|---|
| committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-06-27 23:01:53 +0000 |
| commit | a5717fb10f4d959ce5ce765bbc73d81baf492da4 (patch) | |
| tree | 69f8a5316e25ded67d85dd59052442a6035dedbd | |
| parent | e715b511e0c553d995afcb90047ffd9a3b906f19 (diff) | |
| parent | 44e08ff4a1ae7281ee3711c9f0dd45775cefcc81 (diff) | |
| download | plan9front-a5717fb10f4d959ce5ce765bbc73d81baf492da4.tar.xz | |
merge
| -rw-r--r-- | sys/src/9/port/devproc.c | 5 | ||||
| -rw-r--r-- | sys/src/cmd/5e/fns.h | 1 | ||||
| -rw-r--r-- | sys/src/cmd/5e/proc.c | 10 | ||||
| -rw-r--r-- | sys/src/cmd/5e/sys.c | 1 | ||||
| -rw-r--r-- | sys/src/cmd/pstree.c | 189 |
5 files changed, 205 insertions, 1 deletions
diff --git a/sys/src/9/port/devproc.c b/sys/src/9/port/devproc.c index d1ee87d5f..f133f3d5d 100644 --- a/sys/src/9/port/devproc.c +++ b/sys/src/9/port/devproc.c @@ -23,6 +23,7 @@ enum Qnoteid, Qnotepg, Qns, + Qppid, Qproc, Qregs, Qsegment, @@ -87,6 +88,7 @@ Dirtab procdir[] = "noteid", {Qnoteid}, 0, 0664, "notepg", {Qnotepg}, 0, 0000, "ns", {Qns}, 0, 0444, + "ppid", {Qppid}, 0, 0444, "proc", {Qproc}, 0, 0400, "regs", {Qregs}, sizeof(Ureg), 0000, "segment", {Qsegment}, 0, 0444, @@ -417,6 +419,7 @@ procopen(Chan *c, int omode) case Qregs: case Qfpregs: case Qsyscall: + case Qppid: nonone(p); break; @@ -963,6 +966,8 @@ procread(Chan *c, void *va, long n, vlong off) case Qnoteid: return readnum(offset, va, n, p->noteid, NUMSIZE); + case Qppid: + return readnum(offset, va, n, p->parentpid, NUMSIZE); case Qfd: return procfds(p, va, n, offset); } diff --git a/sys/src/cmd/5e/fns.h b/sys/src/cmd/5e/fns.h index 2d28c522e..68d60f785 100644 --- a/sys/src/cmd/5e/fns.h +++ b/sys/src/cmd/5e/fns.h @@ -35,3 +35,4 @@ void invalid(u32int); void fpatransfer(u32int); void fpaoperation(u32int); void fparegtransfer(u32int); +void inittos(void); diff --git a/sys/src/cmd/5e/proc.c b/sys/src/cmd/5e/proc.c index 85768df56..9ef5280ef 100644 --- a/sys/src/cmd/5e/proc.c +++ b/sys/src/cmd/5e/proc.c @@ -108,8 +108,16 @@ initstack(int argc, char **argv) ap += len; } *(ulong *) vaddrnol(sp, 4) = 0; + inittos(); +} - ((Tos *) vaddrnol(tos, sizeof(Tos)))->pid = getpid(); +void +inittos(void) +{ + ulong tos; + + tos = mach->utop - sizeof(Tos) * 2; + ((Tos *) vaddrnol(tos, sizeof(Tos)))->pid = P->pid; } static int diff --git a/sys/src/cmd/5e/sys.c b/sys/src/cmd/5e/sys.c index 0f9fb1c03..38fd0c076 100644 --- a/sys/src/cmd/5e/sys.c +++ b/sys/src/cmd/5e/sys.c @@ -401,6 +401,7 @@ sysrfork(void) P = p; atexit(cleanup); P->pid = getpid(); + inittos(); addproc(P); } P->R[0] = rc; diff --git a/sys/src/cmd/pstree.c b/sys/src/cmd/pstree.c new file mode 100644 index 000000000..069c98e22 --- /dev/null +++ b/sys/src/cmd/pstree.c @@ -0,0 +1,189 @@ +#include <u.h> +#include <libc.h> + +enum { NBUCKETS = 1024 }; + +typedef struct Proc Proc; +typedef struct Bucket Bucket; + +struct Proc { + int pid; + Proc *first, *last, *parent, *next; + Proc *bnext; +}; + +struct Bucket { + Proc *first, *last; +} buck[NBUCKETS]; + +Proc * +getproc(int pid) +{ + Proc *p; + + for(p = buck[pid % NBUCKETS].first; p; p = p->bnext) + if(p->pid == pid) + return p; + + return nil; +} + +void +addproc(int pid) +{ + Proc *p; + Bucket *b; + + p = mallocz(sizeof(*p), 1); + if(p == nil) + sysfatal("malloc: %r"); + p->pid = pid; + b = buck + pid % NBUCKETS; + if(b->first != nil) + b->last->bnext = p; + else + b->first = p; + b->last = p; +} + +int +theppid(int pid) +{ + char *file; + int fd; + char buf[12]; + int ppid; + + file = smprint("/proc/%d/ppid", pid); + fd = open(file, OREAD); + free(file); + if(fd < 0) + return 0; + ppid = 0; + if(read(fd, buf, sizeof buf) >= 0) + ppid = atoi(buf); + close(fd); + return ppid; +} + +void +addppid(int pid) +{ + int ppid; + Proc *p, *par; + + p = getproc(pid); + ppid = theppid(pid); + par = getproc(ppid); + if(par == nil) + par = getproc(0); + p->parent = par; + if(par->first != nil) + par->last->next = p; + else + par->first = p; + par->last = p; +} + +void +addprocs(void) +{ + int fd, rc, i; + Dir *d; + + fd = open("/proc", 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); +} + +Rune buf[512]; + +int +readout(char *file) +{ + int fd, rc, n; + char b[512]; + + fd = open(file, OREAD); + free(file); + if(fd < 0) + return -1; + n = 0; + while(rc = read(fd, b, 512), rc > 0) { + write(1, b, rc); + n += rc; + } + close(fd); + return n; +} + +void +printargs(int pid) +{ + char *file; + char b[28], *p; + int fd; + + if(pid == 0) + return; + if(readout(smprint("/proc/%d/args", pid)) > 0) + return; + file = smprint("/proc/%d/status", pid); + fd = open(file, OREAD); + free(file); + if(fd < 0) + return; + memset(b, 0, sizeof b); + if(read(fd, b, 27) <= 0) + return; + p = b + strlen(b) - 1; + while(*p == ' ') + *p-- = 0; + print("%s", b); +} + +void +descend(Proc *p, Rune *r) +{ + Rune last; + Proc *q; + + last = *--r; + *r = last == L' ' ? L'└' : L'├'; + print("%S", buf); + printargs(p->pid); + print(" [%d]\n", p->pid); + *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() +{ + addproc(0); + addprocs(); + printprocs(); +} |
