Research V7 development
[unix-history] / usr / src / cmd / ps.c
CommitLineData
b4e2e355
KT
1/*
2 * ps - process status
3 * examine and print certain things about processes
4 */
5
6#include <stdio.h>
7#include <a.out.h>
8#include <core.h>
9#include <sys/param.h>
10#include <sys/proc.h>
11#include <sys/tty.h>
12#include <sys/dir.h>
13#include <sys/user.h>
14
15struct nlist nl[] = {
16 { "_proc" },
17 { "_swapdev" },
18 { "_swplo" },
19 { "" },
20};
21
22struct proc mproc;
23
24struct user u;
25int chkpid;
26int retcode=1;
27int lflg;
28int vflg;
29int kflg;
30int xflg;
31char *tptr;
32long lseek();
33char *gettty();
34char *getptr();
35char *strncmp();
36int aflg;
37int mem;
38int swmem;
39int swap;
40daddr_t swplo;
41
42int ndev;
43struct devl {
44 char dname[DIRSIZ];
45 dev_t dev;
46} devl[256];
47
48char *coref;
49
50main(argc, argv)
51char **argv;
52{
53 int i;
54 char *ap;
55 int uid, puid;
56
57 if (argc>1) {
58 ap = argv[1];
59 while (*ap) switch (*ap++) {
60
61 case 'v':
62 vflg++;
63 break;
64
65 case 'a':
66 aflg++;
67 break;
68
69 case 't':
70 if(*ap)
71 tptr = ap;
72 aflg++;
73 if (*tptr == '?')
74 xflg++;
75 goto bbreak;
76
77 case 'x':
78 xflg++;
79 break;
80
81 case '-':
82 break;
83
84 case 'l':
85 lflg++;
86 break;
87
88 case 'k':
89 kflg++;
90 break;
91
92 default:
93 chkpid = atoi(ap-1);
94 goto bbreak;
95 break;
96 }
97 }
98
99bbreak:
100 if(chdir("/dev") < 0) {
101 fprintf(stderr, "Can't change to /dev\n");
102 exit(1);
103 }
104 nlist(argc>2? argv[2]:"/unix", nl);
105 if (nl[0].n_type==0) {
106 fprintf(stderr, "No namelist\n");
107 exit(1);
108 }
109 coref = "/dev/mem";
110 if(kflg)
111 coref = "/usr/sys/core";
112 if ((mem = open(coref, 0)) < 0) {
113 fprintf(stderr, "No mem\n");
114 exit(1);
115 }
116 swmem = open(coref, 0);
117 /*
118 * read mem to find swap dev.
119 */
120 lseek(mem, (long)nl[1].n_value, 0);
121 read(mem, (char *)&nl[1].n_value, sizeof(nl[1].n_value));
122 /*
123 * Find base of swap
124 */
125 lseek(mem, (long)nl[2].n_value, 0);
126 read(mem, (char *)&swplo, sizeof(swplo));
127 /*
128 * Locate proc table
129 */
130 lseek(mem, (long)nl[0].n_value, 0);
131 getdev();
132 uid = getuid();
133 if (lflg)
134 printf(" F S UID PID PPID CPU PRI NICE ADDR SZ WCHAN TTY TIME CMD\n"); else
135 if (chkpid==0) printf(" PID TTY TIME CMD\n");
136 for (i=0; i<NPROC; i++) {
137 read(mem, (char *)&mproc, sizeof mproc);
138 if (mproc.p_stat==0)
139 continue;
140 if (mproc.p_pgrp==0 && xflg==0 && mproc.p_uid==0)
141 continue;
142 puid = mproc.p_uid;
143 if ((uid != puid && aflg==0) ||
144 (chkpid!=0 && chkpid!=mproc.p_pid))
145 continue;
146 if(prcom(puid)) {
147 printf("\n");
148 retcode=0;
149 }
150 }
151 exit(retcode);
152}
153
154getdev()
155{
156#include <sys/stat.h>
157 register FILE *df;
158 struct stat sbuf;
159 struct direct dbuf;
160
161 if ((df = fopen("/dev", "r")) == NULL) {
162 fprintf(stderr, "Can't open /dev\n");
163 exit(1);
164 }
165 ndev = 0;
166 while (fread((char *)&dbuf, sizeof(dbuf), 1, df) == 1) {
167 if(dbuf.d_ino == 0)
168 continue;
169 if(stat(dbuf.d_name, &sbuf) < 0)
170 continue;
171 if ((sbuf.st_mode&S_IFMT) != S_IFCHR)
172 continue;
173 strcpy(devl[ndev].dname, dbuf.d_name);
174 devl[ndev].dev = sbuf.st_rdev;
175 ndev++;
176 }
177 fclose(df);
178 if ((swap = open("/dev/swap", 0)) < 0) {
179 fprintf(stderr, "Can't open /dev/swap\n");
180 exit(1);
181 }
182}
183
184long
185round(a, b)
186 long a, b;
187{
188 long w = ((a+b-1)/b)*b;
189
190 return(w);
191}
192
193struct map {
194 long b1, e1; long f1;
195 long b2, e2; long f2;
196};
197struct map datmap;
198int file;
199prcom(puid)
200{
201 char abuf[512];
202 long addr;
203 register int *ip;
204 register char *cp, *cp1;
205 long tm;
206 int c, nbad;
207 register char *tp;
208 long txtsiz, datsiz, stksiz;
209 int septxt;
210 int lw=(lflg?35:80);
211 char **ap;
212
213 if (mproc.p_flag&SLOAD) {
214 addr = ctob((long)mproc.p_addr);
215 file = swmem;
216 } else {
217 addr = (mproc.p_addr+swplo)<<9;
218 file = swap;
219 }
220 lseek(file, addr, 0);
221 if (read(file, (char *)&u, sizeof(u)) != sizeof(u))
222 return(0);
223
224 /* set up address maps for user pcs */
225 txtsiz = ctob(u.u_tsize);
226 datsiz = ctob(u.u_dsize);
227 stksiz = ctob(u.u_ssize);
228 septxt = u.u_sep;
229 datmap.b1 = (septxt ? 0 : round(txtsiz,TXTRNDSIZ));
230 datmap.e1 = datmap.b1+datsiz;
231 datmap.f1 = ctob(USIZE)+addr;
232 datmap.b2 = stackbas(stksiz);
233 datmap.e2 = stacktop(stksiz);
234 datmap.f2 = ctob(USIZE)+(datmap.e1-datmap.b1)+addr;
235
236 tp = gettty();
237 if (tptr && strncmp(tptr, tp, 2))
238 return(0);
239 if (lflg) {
240 printf("%2o %c%4d", mproc.p_flag,
241 "0SWRIZT"[mproc.p_stat], puid);
242 }
243 printf("%6u", mproc.p_pid);
244 if (lflg) {
245 printf("%6u%4d%4d%5d%6o%4d", mproc.p_ppid, mproc.p_cpu&0377,
246 mproc.p_pri,
247 mproc.p_nice,
248 mproc.p_addr, (mproc.p_size+7)>>3);
249 if (mproc.p_wchan)
250 printf("%7o", mproc.p_wchan);
251 else
252 printf(" ");
253 }
254 printf(" %-2.2s", tp);
255 if (mproc.p_stat==SZOMB) {
256 printf(" <defunct>");
257 return(1);
258 }
259 tm = (u.u_utime + u.u_stime + 30)/60;
260 printf(" %2ld:", tm/60);
261 tm %= 60;
262 printf(tm<10?"0%ld":"%ld", tm);
263 if (vflg && lflg==0) { /* 0 == old tflg (print long times) */
264 tm = (u.u_cstime + 30)/60;
265 printf(" %2ld:", tm/60);
266 tm %= 60;
267 printf(tm<10?"0%ld":"%ld", tm);
268 tm = (u.u_cutime + 30)/60;
269 printf(" %2ld:", tm/60);
270 tm %= 60;
271 printf(tm<10?"0%ld":"%ld", tm);
272 }
273 if (mproc.p_pid == 0) {
274 printf(" swapper");
275 return(1);
276 }
277 addr += ctob((long)mproc.p_size) - 512;
278
279 /* look for sh special */
280 lseek(file, addr+512-sizeof(char **), 0);
281 if (read(file, (char *)&ap, sizeof(char *)) != sizeof(char *))
282 return(1);
283 if (ap) {
284 char b[82];
285 char *bp = b;
286 while((cp=getptr(ap++)) && cp && (bp<b+lw) ) {
287 nbad = 0;
288 while((c=getbyte(cp++)) && (bp<b+lw)) {
289 if (c<' ' || c>'~') {
290 if (nbad++>3)
291 break;
292 continue;
293 }
294 *bp++ = c;
295 }
296 *bp++ = ' ';
297 }
298 *bp++ = 0;
299 printf(lflg?" %.30s":" %.60s", b);
300 return(1);
301 }
302
303 lseek(file, addr, 0);
304 if (read(file, abuf, sizeof(abuf)) != sizeof(abuf))
305 return(1);
306 for (ip = (int *)&abuf[512]-2; ip > (int *)abuf; ) {
307 if (*--ip == -1 || *ip==0) {
308 cp = (char *)(ip+1);
309 if (*cp==0)
310 cp++;
311 nbad = 0;
312 for (cp1 = cp; cp1 < &abuf[512]; cp1++) {
313 c = *cp1&0177;
314 if (c==0)
315 *cp1 = ' ';
316 else if (c < ' ' || c > 0176) {
317 if (++nbad >= 5) {
318 *cp1++ = ' ';
319 break;
320 }
321 *cp1 = '?';
322 } else if (c=='=') {
323 *cp1 = 0;
324 while (cp1>cp && *--cp1!=' ')
325 *cp1 = 0;
326 break;
327 }
328 }
329 while (*--cp1==' ')
330 *cp1 = 0;
331 printf(lflg?" %.30s":" %.60s", cp);
332 return(1);
333 }
334 }
335 return(1);
336}
337
338char *
339gettty()
340{
341 register i;
342 register char *p;
343
344 if (u.u_ttyp==0)
345 return("?");
346 for (i=0; i<ndev; i++) {
347 if (devl[i].dev == u.u_ttyd) {
348 p = devl[i].dname;
349 if (p[0]=='t' && p[1]=='t' && p[2]=='y')
350 p += 3;
351 return(p);
352 }
353 }
354 return("?");
355}
356
357char *
358getptr(adr)
359char **adr;
360{
361 char *ptr;
362 register char *p, *pa;
363 register i;
364
365 ptr = 0;
366 pa = (char *)adr;
367 p = (char *)&ptr;
368 for (i=0; i<sizeof(ptr); i++)
369 *p++ = getbyte(pa++);
370 return(ptr);
371}
372
373getbyte(adr)
374char *adr;
375{
376 register struct map *amap = &datmap;
377 char b;
378 long saddr;
379
380 if(!within(adr, amap->b1, amap->e1)) {
381 if(within(adr, amap->b2, amap->e2)) {
382 saddr = (unsigned)adr + amap->f2 - amap->b2;
383 } else
384 return(0);
385 } else
386 saddr = (unsigned)adr + amap->f1 - amap->b1;
387 if(lseek(file, saddr, 0)==-1
388 || read(file, &b, 1)<1) {
389 return(0);
390 }
391 return((unsigned)b);
392}
393
394
395within(adr,lbd,ubd)
396char *adr;
397long lbd, ubd;
398{
399 return((unsigned)adr>=lbd && (unsigned)adr<ubd);
400}