]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/pstree.c
merge
[plan9front.git] / sys / src / cmd / pstree.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 typedef struct Proc Proc;
6 struct Proc {
7         int pid;
8         Proc *first, *parent, *next;
9         Proc *hash;
10 };
11
12 Proc    *hash[1024];
13 Rune    buf[512];
14 Biobuf  bout;
15
16 Proc *
17 getproc(int pid)
18 {
19         Proc *p;
20
21         for(p = hash[pid % nelem(hash)]; p; p = p->hash)
22                 if(p->pid == pid)
23                         return p;
24         return nil;
25 }
26
27 void
28 addproc(int pid)
29 {
30         Proc *p;
31         
32         p = mallocz(sizeof(*p), 1);
33         if(p == nil)
34                 sysfatal("malloc: %r");
35         p->pid = pid;
36         p->hash = hash[pid % nelem(hash)];
37         hash[pid % nelem(hash)] = p;
38 }
39
40 int
41 theppid(int pid)
42 {
43         char b[128];
44         int fd, ppid;
45         
46         ppid = 0;
47         snprint(b, sizeof(b), "%d/ppid", pid);
48         fd = open(b, OREAD);
49         if(fd >= 0){
50                 memset(b, 0, sizeof b);
51                 if(read(fd, b, sizeof b-1) >= 0){
52                         ppid = atoi(b);
53                         if(ppid < 0)
54                                 ppid = 0;
55                 }
56                 close(fd);
57         }
58         return ppid;
59 }
60
61 void
62 addppid(int pid)
63 {
64         Proc *p, *par, **l;
65         
66         p = getproc(pid);
67         par = getproc(theppid(pid));
68         if(par == nil)
69                 par = getproc(0);
70         p->parent = par;
71         for(l = &par->first; *l; l = &((*l)->next))
72                 if((*l)->pid > pid)
73                         break;
74         p->next = *l;
75         *l = p;
76 }
77
78 void
79 addprocs(void)
80 {
81         int fd, rc, i;
82         Dir *d;
83         
84         fd = open(".", OREAD);
85         if(fd < 0)
86                 sysfatal("open: %r");
87         rc = dirreadall(fd, &d);
88         if(rc < 0)
89                 sysfatal("dirreadall: %r");
90         close(fd);
91         for(i = 0; i < rc; i++)
92                 if(d[i].mode & DMDIR)
93                         addproc(atoi(d[i].name));
94         for(i = 0; i < rc; i++)
95                 if(d[i].mode & DMDIR)
96                         addppid(atoi(d[i].name));
97         free(d);
98 }
99
100 int
101 readout(char *file)
102 {
103         int fd, rc, i, n;
104         char b[512];
105
106         fd = open(file, OREAD);
107         if(fd < 0)
108                 return -1;
109         n = 0;
110         while((rc = read(fd, b, sizeof b)) > 0){
111                 for(i=0; i<rc; i++)
112                         if(b[i] == '\n')
113                                 b[i] = ' ';
114                 n += Bwrite(&bout, b, rc);
115         }
116         close(fd);
117         return n;
118 }
119
120 void
121 printargs(int pid)
122 {
123         char b[128], *p;
124         int fd;
125
126         snprint(b, sizeof(b), "%d/args", pid);
127         if(readout(b) > 0)
128                 return;
129         snprint(b, sizeof(b), "%d/status", pid);
130         fd = open(b, OREAD);
131         if(fd >= 0){
132                 memset(b, 0, sizeof b);
133                 if(read(fd, b, 27) > 0){
134                         p = b + strlen(b);
135                         while(p > b && p[-1] == ' ')
136                                 *--p = 0;
137                         Bprint(&bout, "%s", b);
138                 }
139                 close(fd);
140         }
141 }
142
143 void
144 descend(Proc *p, Rune *r)
145 {
146         Rune last;
147         Proc *q;
148         
149         last = *--r;
150         *r = last == L' ' ? L'└' : L'├';
151         if(p->pid != 0){
152                 Bprint(&bout, "%-11d %S", p->pid, buf);
153                 printargs(p->pid);
154                 Bprint(&bout, "\n");
155         }
156         *r = last;
157         *++r = L'│';
158         for(q = p->first; q; q = q->next) {
159                 if(q->next == nil)
160                         *r = L' ';
161                 descend(q, r + 1);
162         }
163         *r = 0;
164 }
165
166 void
167 printprocs(void)
168 {
169         descend(getproc(0), buf);
170 }
171
172 void
173 main()
174 {
175         Binit(&bout, 1, OWRITE);
176         if(chdir("/proc")==-1)
177                 sysfatal("chdir: %r");
178
179         addproc(0);
180         addprocs();
181         printprocs();
182
183         exits(0);
184 }