xref: /plan9/sys/src/cmd/ps.c (revision 3b56890da2282dbd3cc0fc1501f968e20f5e5f6a)
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