xref: /plan9-contrib/sys/src/cmd/ps.c (revision d46c239f8612929b7dbade67d0d071633df3a15d)
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 
13 void
14 main(int argc, char *argv[])
15 {
16 	int fd, i, tot, none = 1;
17 	Dir *dir, **mem;
18 
19 
20 	ARGBEGIN {
21 	case 'a':
22 		aflag++;
23 		break;
24 	case 'p':
25 		pflag++;
26 		break;
27 	} ARGEND;
28 	Binit(&bout, 1, OWRITE);
29 	if(chdir("/proc")==-1)
30 		error("/proc");
31 	fd=open(".", OREAD);
32 	if(fd<0)
33 		error("/proc");
34 	tot = dirreadall(fd, &dir);
35 	if(tot <= 0){
36 		fprint(2, "ps: empty directory /proc\n");
37 		exits("empty");
38 	}
39 	mem = malloc(tot*sizeof(Dir*));
40 	for(i=0; i<tot; i++)
41 		mem[i] = dir++;
42 
43 	qsort(mem, tot, sizeof(Dir*), cmp);
44 	for(i=0; i<tot; i++){
45 		ps(mem[i]->name);
46 		none = 0;
47 	}
48 
49 	if(none)
50 		error("no processes; bad #p");
51 	exits(0);
52 }
53 
54 void
55 ps(char *s)
56 {
57 	int i, n, fd;
58 	char buf[64];
59 	int basepri, pri;
60 	long utime, stime, size;
61 	char pbuf[8];
62 #define NAMELEN 28
63 	char status[2*NAMELEN+12+9*12+1];
64 	char args[256];
65 	char *p;
66 
67 	sprint(buf, "%s/status", s);
68 	fd = open(buf, OREAD);
69 	if(fd<0)
70 		return;
71 	n = read(fd, status, sizeof status-1);
72 	close(fd);
73 	if(n <= 0)
74 		return;
75 	status[n] = '\0';
76 	p = strchr(status, ' ');
77 	if(!p)
78 		return;
79 	*p = 0;
80 	p = strchr(status+NAMELEN, ' ');
81 	if(!p)
82 		return;
83 	*p = 0;
84 	status[2*NAMELEN+12-1] = 0;
85 	utime = atol(status+2*NAMELEN+12)/1000;
86 	stime = atol(status+2*NAMELEN+12+1*12)/1000;
87 	size  = atol(status+2*NAMELEN+12+6*12);
88 	if(pflag){
89 		basepri = atol(status+2*NAMELEN+12+7*12);
90 		pri = atol(status+2*NAMELEN+12+8*12);
91 		sprint(pbuf, " %2d %2d", basepri, pri);
92 	} else
93 		pbuf[0] = 0;
94 	Bprint(&bout, "%-10s %8s %4ld:%.2ld %3ld:%.2ld%s %7ldK %-.8s ",
95 			status+NAMELEN,
96 			s,
97 			utime/60, utime%60,
98 			stime/60, stime%60,
99 			pbuf,
100 			size,
101 			status+2*NAMELEN);
102 
103 	if(aflag == 0){
104     Noargs:
105 		Bprint(&bout, "%s\n", status);
106 		return;
107 	}
108 
109 	sprint(buf, "%s/args", s);
110 	fd = open(buf, OREAD);
111 	if(fd < 0)
112 		goto Badargs;
113 	n = read(fd, args, sizeof args-1);
114 	close(fd);
115 	if(n < 0)
116 		goto Badargs;
117 	if(n == 0)
118 		goto Noargs;
119 	args[n] = '\0';
120 	for(i=0; i<n; i++)
121 		if(args[i] == '\n')
122 			args[i] = ' ';
123 	Bprint(&bout, "%s\n", args);
124 	return;
125 
126     Badargs:
127 	Bprint(&bout, "%s ?\n", status);
128 }
129 
130 void
131 error(char *s)
132 {
133 	fprint(2, "ps: %s: ", s);
134 	perror("error");
135 	exits(s);
136 }
137 
138 int
139 cmp(void *va, void *vb)
140 {
141 	Dir **a, **b;
142 
143 	a = va;
144 	b = vb;
145 	return atoi((*a)->name) - atoi((*b)->name);
146 }
147