ref: 493bac79b63f1949a29aeec8270fab4a599a6ee3
parent: 5969b872bb244f6f9083fd06779a50cf68078455
author: qwx <qwx@sciops.net>
date: Wed Oct 30 19:43:47 EDT 2024
pstree: reimplement in awk, optionally restrict to a given process
--- /dev/null
+++ b/rc/bin/pstree
@@ -1,0 +1,49 @@
+#!/bin/rc
+p=0
+if(! ~ $#* 0)
+ p=$1
+cd /proc || exit
+ls -d [0-9]* | sort -n | awk -v 'this='^$p '
+function cat(f, v){
+ getline v < f
+ close(f)
+ return v
+}
+BEGIN{
+ OFS="\t"
+}
+{
+ s = cat($1"/args")
+ if(s == ""){
+ s = cat($1"/status")
+ s = substr(s, 1, 27)
+ gsub(" *", "", s)
+ }
+ p = int(cat($1"/ppid"))
+ child[p,++nchild[p]] = $1
+ proc[$1] = s
+ ppid[$1] = p
+ pid[NR] = $1
+}
+function out(p, sep, k, m, i, n, c, s){
+ n = nchild[p]
+ if(p != 0 && proc[p] != "")
+ printf "%-11s%s%s%s\n", p, sep, k, proc[p]
+ s = m > 0 ? "│" : " "
+ k = "├"
+ for(i=1; i<=n; i++){
+ c = child[p,i]
+ if(i == n)
+ k = "└"
+ out(c, sep s, k, n - i)
+ }
+}
+END{
+ for(i=1; i<=length(pid); i++){
+ p = pid[i]
+ if(!(ppid[p] in proc) && ppid[p] != 0)
+ child[0,++nchild[0]] = p
+ }
+ out(this, "", "", 0)
+}
+'
--- a/sys/man/1/ps
+++ b/sys/man/1/ps
@@ -16,6 +16,9 @@
]
.PP
.B pstree
+[
+.I pid
+]
.SH DESCRIPTION
.I Ps
prints information about processes.
@@ -113,6 +116,9 @@
the first column being the process id and second column
the program name and arguments indented and prefixed with
line drawing runes to reflect the nesting in the hierarchy.
+It optionally accepts an argument
+.I pid
+to only print a tree for the corresponding process.
.SH FILES
.B /proc/*/status
.SH SOURCE
@@ -120,7 +126,7 @@
.br
.B /rc/bin/psu
.br
-.B /sys/src/cmd/pstree.c
+.B /rc/bin/pstree
.SH "SEE ALSO"
.IR acid (1),
.IR db (1),
--- a/sys/src/cmd/pstree.c
+++ /dev/null
@@ -1,184 +1,0 @@
-#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);
-}
--
⑨