1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 void ps(char*);
6 void error(char*);
7 int cmp(void*, void*);
8
9 Biobuf bout;
10 int pflag;
11 int aflag;
12 int rflag;
13
14 void
main(int argc,char * argv[])15 main(int argc, char *argv[])
16 {
17 int fd, i, tot, none = 1;
18 Dir *dir, **mem;
19
20
21 ARGBEGIN {
22 case 'a':
23 aflag++;
24 break;
25 case 'p':
26 pflag++;
27 break;
28 case 'r':
29 rflag++;
30 break;
31 } ARGEND;
32 Binit(&bout, 1, OWRITE);
33 if(chdir("/proc")==-1)
34 error("/proc");
35 fd=open(".", OREAD);
36 if(fd<0)
37 error("/proc");
38 tot = dirreadall(fd, &dir);
39 if(tot <= 0){
40 fprint(2, "ps: empty directory /proc\n");
41 exits("empty");
42 }
43 mem = malloc(tot*sizeof(Dir*));
44 for(i=0; i<tot; i++)
45 mem[i] = dir++;
46
47 qsort(mem, tot, sizeof(Dir*), cmp);
48 for(i=0; i<tot; i++){
49 ps(mem[i]->name);
50 none = 0;
51 }
52
53 if(none)
54 error("no processes; bad #p");
55 exits(0);
56 }
57
58 void
ps(char * s)59 ps(char *s)
60 {
61 ulong utime, stime, rtime, size;
62 int argc, basepri, fd, i, n, pri;
63 char args[256], *argv[16], buf[64], pbuf[8], rbuf[20], rbuf1[20], status[4096];
64
65 sprint(buf, "%s/status", s);
66 fd = open(buf, OREAD);
67 if(fd<0)
68 return;
69 n = read(fd, status, sizeof status-1);
70 close(fd);
71 if(n <= 0)
72 return;
73 status[n] = '\0';
74
75 if((argc = tokenize(status, argv, nelem(argv)-1)) < 12)
76 return;
77 argv[argc] = 0;
78
79 /*
80 * 0 text
81 * 1 user
82 * 2 state
83 * 3 cputime[6]
84 * 9 memory
85 * 10 basepri
86 * 11 pri
87 */
88 utime = strtoul(argv[3], 0, 0)/1000;
89 stime = strtoul(argv[4], 0, 0)/1000;
90 rtime = strtoul(argv[5], 0, 0)/1000;
91 size = strtoul(argv[9], 0, 0);
92 if(pflag){
93 basepri = strtoul(argv[10], 0, 0);
94 pri = strtoul(argv[11], 0, 0);
95 sprint(pbuf, " %2d %2d", basepri, pri);
96 } else
97 pbuf[0] = 0;
98
99 if(rflag){
100 if(rtime >= 86400)
101 sprint(rbuf, " %lud:%02lud:%02lud:%02lud", rtime/86400, (rtime/3600)%24, (rtime/60)%60, rtime%60);
102 else if(rtime >= 3600)
103 sprint(rbuf, " %lud:%02lud:%02lud", rtime/3600, (rtime/60)%60, rtime%60);
104 else
105 sprint(rbuf, " %lud:%02lud", rtime/60, rtime%60);
106 sprint(rbuf1, "%12s", rbuf);
107 }else
108 rbuf1[0] = 0;
109
110 Bprint(&bout, "%-10s %8s%s %4lud:%.2lud %3lud:%.2lud %s %7ludK %-8.8s ",
111 argv[1],
112 s,
113 rbuf1,
114 utime/60, utime%60,
115 stime/60, stime%60,
116 pbuf,
117 size,
118 argv[2]);
119
120 if(aflag == 0){
121 Noargs:
122 Bprint(&bout, "%s\n", argv[0]);
123 return;
124 }
125
126 sprint(buf, "%s/args", s);
127 fd = open(buf, OREAD);
128 if(fd < 0)
129 goto Badargs;
130 n = read(fd, args, sizeof args-1);
131 close(fd);
132 if(n < 0)
133 goto Badargs;
134 if(n == 0)
135 goto Noargs;
136 args[n] = '\0';
137 for(i=0; i<n; i++)
138 if(args[i] == '\n')
139 args[i] = ' ';
140 Bprint(&bout, "%s\n", args);
141 return;
142
143 Badargs:
144 Bprint(&bout, "%s ?\n", argv[0]);
145 }
146
147 void
error(char * s)148 error(char *s)
149 {
150 fprint(2, "ps: %s: ", s);
151 perror("error");
152 exits(s);
153 }
154
155 int
cmp(void * va,void * vb)156 cmp(void *va, void *vb)
157 {
158 Dir **a, **b;
159
160 a = va;
161 b = vb;
162 return atoi((*a)->name) - atoi((*b)->name);
163 }
164