|
|
1.1 root 1: static char *sccsid = "@(#)ps.c 4.13 (Berkeley) 81/07/08";
2: /*
3: * ps; VAX 4BSD version
4: */
5:
6: #include <stdio.h>
7: #include <ctype.h>
8: #include <nlist.h>
9: #include <pwd.h>
10: #include <sys/param.h>
11: #include <sys/dir.h>
12: #include <sys/user.h>
13: #include <sys/proc.h>
14: #include <sys/pte.h>
15: #include <sys/vm.h>
16: #include <sys/text.h>
17: #include <sys/stat.h>
18: #include <math.h>
19: #include <sys/vlimit.h>
20: #include <ftw.h>
21:
22: struct nlist nl[] = {
23: { "_proc" },
24: #define X_PROC 0
25: { "_Usrptmap" },
26: #define X_USRPTMA 1
27: { "_usrpt" },
28: #define X_USRPT 2
29: { "_text" },
30: #define X_TEXT 3
31: { "_nswap" },
32: #define X_NSWAP 4
33: { "_maxslp" },
34: #define X_MAXSLP 5
35: { "_ccpu" },
36: #define X_CCPU 6
37: { "_ecmx" },
38: #define X_ECMX 7
39: { "_nproc" },
40: #define X_NPROC 8
41: { "_ntext" },
42: #define X_NTEXT 9
43: { "_hz" },
44: #define X_HZ 10
45: { 0 },
46: };
47:
48: struct savcom {
49: union {
50: struct lsav *lp;
51: float u_pctcpu;
52: struct vsav *vp;
53: int s_ssiz;
54: } sun;
55: struct asav *ap;
56: } *savcom;
57:
58: struct asav {
59: char *a_cmdp;
60: int a_flag;
61: short a_stat, a_uid, a_pid, a_nice, a_pri, a_slptime, a_time;
62: size_t a_size, a_rss, a_tsiz, a_txtrss;
63: short a_xccount;
64: char a_tty[DIRSIZ+1];
65: dev_t a_ttyd;
66: time_t a_cpu;
67: size_t a_maxrss;
68: };
69:
70: char *lhdr;
71: struct lsav {
72: short l_ppid;
73: char l_cpu;
74: int l_addr;
75: caddr_t l_wchan;
76: };
77:
78: char *uhdr;
79: char *shdr;
80:
81: char *vhdr;
82: struct vsav {
83: u_int v_majflt;
84: size_t v_swrss, v_txtswrss;
85: float v_pctcpu;
86: };
87:
88: struct proc proc[8]; /* 8 = a few, for less syscalls */
89: struct proc *mproc;
90: struct text *text;
91:
92: int paduser1; /* avoid hardware mem clobbering botch */
93: union {
94: struct user user;
95: char upages[UPAGES][NBPG];
96: } user;
97: #define u user.user
98: int paduser2; /* avoid hardware mem clobbering botch */
99:
100: #define clear(x) ((int)x & 0xffffff)
101:
102: int chkpid;
103: int aflg, cflg, eflg, gflg, kflg, lflg, sflg, uflg, vflg, xflg;
104: char *tptr;
105: char *gettty(), *getcmd(), *getname(), *savestr(), *alloc(), *state();
106: double pcpu(), pmem();
107: int pscomp();
108: int nswap, maxslp;
109: struct text *atext;
110: double ccpu;
111: int ecmx;
112: struct pte *Usrptma, *usrpt;
113: int nproc, ntext, hz;
114:
115: struct ttys {
116: char name[DIRSIZ+1];
117: dev_t ttyd;
118: struct ttys *next;
119: } *allttys;
120:
121:
122: int npr;
123:
124: int cmdstart;
125: int twidth;
126: char *kmemf, *memf, *swapf, *nlistf;
127: int kmem, mem, swap;
128: int rawcpu, sumcpu;
129:
130: int pcbpf;
131: int argaddr;
132: extern char _sobuf[];
133:
134: main(argc, argv)
135: char **argv;
136: {
137: register int i, j;
138: register char *ap;
139: int uid, pgrp;
140: off_t procp;
141:
142: argc--, argv++;
143: twidth = 80;
144: setbuf(stdout, _sobuf);
145: if (argc > 0) {
146: ap = argv[0];
147: while (*ap) switch (*ap++) {
148:
149: case 'C':
150: rawcpu++;
151: break;
152: case 'S':
153: sumcpu++;
154: break;
155: case 'a':
156: aflg++;
157: break;
158: case 'c':
159: cflg = !cflg;
160: break;
161: case 'e':
162: eflg++;
163: break;
164: case 'g':
165: gflg++;
166: break;
167: case 'k':
168: kflg++;
169: break;
170: case 'l':
171: lflg++;
172: break;
173: case 's':
174: sflg++;
175: break;
176: case 't':
177: if (*ap)
178: tptr = ap;
179: aflg++;
180: gflg++;
181: if (*tptr == '?')
182: xflg++;
183: while (*ap)
184: ap++;
185: break;
186: case 'u':
187: uflg++;
188: break;
189: case 'v':
190: cflg = 1;
191: vflg++;
192: break;
193: case 'w':
194: if (twidth == 80)
195: twidth = 132;
196: else
197: twidth = BUFSIZ;
198: break;
199: case 'x':
200: xflg++;
201: break;
202: default:
203: if (!isdigit(ap[-1]))
204: break;
205: chkpid = atoi(--ap);
206: *ap = 0;
207: aflg++;
208: xflg++;
209: break;
210: }
211: }
212: openfiles(argc, argv);
213: getkvars(argc, argv);
214: getdev("/dev");
215: getdev("/dev/dk");
216: getdev("/dev/pt");
217: uid = getuid();
218: pgrp = getpgrp();
219: printhdr();
220: procp = getw(nl[X_PROC].n_value);
221: nproc = getw(nl[X_NPROC].n_value);
222: hz = getw(nl[X_HZ].n_value);
223: savcom = (struct savcom *)calloc(nproc, sizeof (*savcom));
224: for (i=0; i<nproc; i += 8) {
225: KMlseek(kmem, (char *)procp, 0);
226: j = nproc - i;
227: if (j > 8)
228: j = 8;
229: j *= sizeof (struct proc);
230: if (read(kmem, (char *)proc, j) != j)
231: cantread("proc table", kmemf);
232: procp += j;
233: for (j = j / sizeof (struct proc) - 1; j >= 0; j--) {
234: mproc = &proc[j];
235: if (mproc->p_stat == 0 ||
236: mproc->p_pgrp == 0 && xflg == 0)
237: continue;
238: /*
239: if (tptr == 0 && gflg == 0 && xflg == 0 &&
240: mproc->p_ppid == 1 && (mproc->p_flag&SDETACH) == 0)
241: continue;
242: */
243:
244: if(uid != mproc->p_uid && !aflg && mproc->p_pgrp != pgrp ||
245: chkpid != 0 && chkpid != mproc->p_pid)
246: continue;
247: if (vflg && gflg == 0 && xflg == 0) {
248: if (mproc->p_stat == SZOMB ||
249: mproc->p_flag&SWEXIT)
250: continue;
251: if (mproc->p_slptime > MAXSLP &&
252: (mproc->p_stat == SSLEEP ||
253: mproc->p_stat == SSTOP))
254: continue;
255: }
256: save();
257: }
258: }
259: qsort(savcom, npr, sizeof(savcom[0]), pscomp);
260: for (i=0; i<npr; i++) {
261: register struct savcom *sp = &savcom[i];
262: if (lflg)
263: lpr(sp);
264: else if (vflg)
265: vpr(sp);
266: else if (uflg)
267: upr(sp);
268: else
269: spr(sp);
270: if (sp->ap->a_flag & SWEXIT)
271: printf(" <exiting>");
272: else if (sp->ap->a_stat == SZOMB)
273: printf(" <defunct>");
274: else if (sp->ap->a_pid == 0)
275: printf(" swapper");
276: else if (sp->ap->a_pid == 2)
277: printf(" pagedaemon");
278: else if (sp->ap->a_pid == 3 && sp->ap->a_flag & SSYS)
279: printf(" ip input");
280: else
281: printf(" %.*s", twidth - cmdstart - 2, sp->ap->a_cmdp);
282: printf("\n");
283: }
284: exit(npr == 0);
285: }
286:
287: getw(loc)
288: off_t loc;
289: {
290: long word;
291:
292: KMlseek(kmem, loc, 0);
293: if (read(kmem, &word, sizeof (word)) != sizeof (word))
294: printf("error reading kmem at %x\n", loc);
295: return (word);
296: }
297:
298: openfiles(argc, argv)
299: char **argv;
300: {
301:
302: kmemf = "/dev/kmem";
303: if (kflg)
304: kmemf = argc > 1 ? argv[1] : "/vmcore";
305: kmem = open(kmemf, 0);
306: if (kmem < 0) {
307: perror(kmemf);
308: exit(1);
309: }
310: if (kflg) {
311: mem = kmem;
312: memf = kmemf;
313: } else {
314: memf = "/dev/mem";
315: mem = open(memf, 0);
316: if (mem < 0) {
317: perror(memf);
318: exit(1);
319: }
320: }
321: swapf = argc>3 ? argv[3]: "/dev/drum";
322: swap = open(swapf, 0);
323: if (swap < 0) {
324: perror(swapf);
325: exit(1);
326: }
327: }
328:
329: getkvars(argc, argv)
330: char **argv;
331: {
332: register struct nlist *nlp;
333:
334: nlistf = argc > 2 ? argv[2] : "/unix";
335: nlist(nlistf, nl);
336: if (nl[0].n_type == 0) {
337: fprintf(stderr, "%s: No namelist\n", nlistf);
338: exit(1);
339: }
340: if (kflg)
341: for (nlp = nl; nlp < &nl[sizeof (nl)/sizeof (nl[0])]; nlp++)
342: nlp->n_value = clear(nlp->n_value);
343: Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
344: usrpt = (struct pte *)nl[X_USRPT].n_value;
345: KMlseek(kmem, (long)nl[X_NSWAP].n_value, 0);
346: if (read(kmem, &nswap, sizeof (nswap)) != sizeof (nswap)) {
347: cantread("nswap", kmemf);
348: exit(1);
349: }
350: KMlseek(kmem, (long)nl[X_MAXSLP].n_value, 0);
351: if (read(kmem, &maxslp, sizeof (maxslp)) != sizeof (maxslp)) {
352: cantread("maxslp", kmemf);
353: exit(1);
354: }
355: KMlseek(kmem, (long)nl[X_CCPU].n_value, 0);
356: if (read(kmem, &ccpu, sizeof (ccpu)) != sizeof (ccpu)) {
357: cantread("ccpu", kmemf);
358: exit(1);
359: }
360: KMlseek(kmem, (long)nl[X_ECMX].n_value, 0);
361: if (read(kmem, &ecmx, sizeof (ecmx)) != sizeof (ecmx)) {
362: cantread("ecmx", kmemf);
363: exit(1);
364: }
365: if (uflg || vflg) {
366: ntext = getw(nl[X_NTEXT].n_value);
367: text = (struct text *)alloc(ntext * sizeof (struct text));
368: if (text == 0) {
369: fprintf(stderr, "no room for text table\n");
370: exit(1);
371: }
372: atext = (struct text *)getw(nl[X_TEXT].n_value);
373: KMlseek(kmem, (int)atext, 0);
374: if (read(kmem, (char *)text, ntext * sizeof (struct text))
375: != ntext * sizeof (struct text)) {
376: cantread("text table", kmemf);
377: exit(1);
378: }
379: }
380: }
381:
382: printhdr()
383: {
384: char *hdr;
385:
386: if (sflg+lflg+vflg+uflg > 1) {
387: fprintf(stderr, "ps: specify only one of s,l,v and u\n");
388: exit(1);
389: }
390: hdr = lflg ? lhdr : (vflg ? vhdr : (uflg ? uhdr : shdr));
391: if (lflg+vflg+uflg+sflg == 0)
392: hdr += strlen("SSIZ ");
393: cmdstart = strlen(hdr);
394: printf("%s COMMAND\n", hdr);
395: fflush(stdout);
396: }
397:
398: cantread(what, fromwhat)
399: char *what, *fromwhat;
400: {
401: fprintf(stderr, "ps: error reading %s from %s\n", what, fromwhat);
402: }
403:
404: getdev(dir)
405: register char *dir;
406: {
407: register FILE *df;
408: struct direct dirent;
409: register struct ttys *dp;
410:
411: df = fopen (dir, "r");
412: if (df != NULL) {
413: while (fread (&dirent, sizeof (dirent), 1, df) == 1) {
414: dp = (struct ttys *) alloc (sizeof (struct ttys));
415: strncpy(dp->name, dirent.d_name, DIRSIZ);
416: dp->ttyd = dirent.d_ino;
417: dp->next = allttys;
418: allttys = dp;
419: }
420: fclose (df);
421: }
422: }
423:
424: char *
425: gettty()
426: {
427: register char *p;
428: register struct ttys *dp;
429:
430: if (u.u_ttyino != 0) {
431: for (dp = allttys; dp; dp = dp -> next) {
432: if (dp->ttyd == u.u_ttyino) {
433: p = dp->name;
434: if (p[0]=='t' && p[1]=='t' && p[2]=='y')
435: p += 3;
436: return (p);
437: }
438: }
439: }
440: return ("?");
441: }
442:
443: save()
444: {
445: register struct savcom *sp;
446: register struct asav *ap;
447: register char *cp;
448: register struct text *xp;
449: char *ttyp, *cmdp;
450:
451: if (mproc->p_stat != SZOMB && getu() == 0)
452: return;
453: ttyp = gettty();
454: if (xflg == 0 && ttyp[0] == '?' || tptr && strcmp(tptr, ttyp))
455: return;
456: sp = &savcom[npr];
457: cmdp = getcmd();
458: if (cmdp == 0)
459: return;
460: sp->ap = ap = (struct asav *)alloc(sizeof (struct asav));
461: sp->ap->a_cmdp = cmdp;
462: #define e(a,b) ap->a = mproc->b
463: e(a_flag, p_flag); e(a_stat, p_stat); e(a_nice, p_nice);
464: e(a_uid, p_uid); e(a_pid, p_pid); e(a_pri, p_pri);
465: e(a_slptime, p_slptime); e(a_time, p_time);
466: strncpy(ap->a_tty, ttyp, 5);
467: if (ap->a_stat == SZOMB) {
468: register struct xproc *xp = (struct xproc *)mproc;
469:
470: ap->a_cpu = xp->xp_vm.vm_utime + xp->xp_vm.vm_stime;
471: } else {
472: ap->a_size = mproc->p_dsize + mproc->p_ssize;
473: e(a_rss, p_rssize);
474: ap->a_ttyd = u.u_ttyino;
475: ap->a_cpu = u.u_vm.vm_utime + u.u_vm.vm_stime;
476: if (sumcpu)
477: ap->a_cpu += u.u_cvm.vm_utime + u.u_cvm.vm_stime;
478: if (mproc->p_textp && text) {
479: xp = &text[mproc->p_textp - atext];
480: ap->a_tsiz = xp->x_size;
481: ap->a_txtrss = xp->x_rssize;
482: ap->a_xccount = xp->x_ccount;
483: }
484: }
485: #undef e
486: ap->a_cpu /= hz;
487: ap->a_maxrss = mproc->p_maxrss;
488: if (lflg) {
489: register struct lsav *lp;
490:
491: sp->sun.lp = lp = (struct lsav *)alloc(sizeof (struct lsav));
492: #define e(a,b) lp->a = mproc->b
493: e(l_ppid, p_ppid); e(l_cpu, p_cpu);
494: if (ap->a_stat != SZOMB)
495: e(l_wchan, p_wchan);
496: #undef e
497: lp->l_addr = pcbpf;
498: } else if (vflg) {
499: register struct vsav *vp;
500:
501: sp->sun.vp = vp = (struct vsav *)alloc(sizeof (struct vsav));
502: #define e(a,b) vp->a = mproc->b
503: if (ap->a_stat != SZOMB) {
504: e(v_swrss, p_swrss);
505: vp->v_majflt = u.u_vm.vm_majflt;
506: if (mproc->p_textp)
507: vp->v_txtswrss = xp->x_swrss;
508: }
509: vp->v_pctcpu = pcpu();
510: #undef e
511: } else if (uflg)
512: sp->sun.u_pctcpu = pcpu();
513: else if (sflg) {
514: if (ap->a_stat != SZOMB) {
515: for (cp = (char *)u.u_stack;
516: cp < &user.upages[UPAGES][0]; )
517: if (*cp++)
518: break;
519: sp->sun.s_ssiz = (&user.upages[UPAGES][0] - cp);
520: }
521: }
522: npr++;
523: }
524:
525: double
526: pmem(ap)
527: register struct asav *ap;
528: {
529: double fracmem;
530: int szptudot;
531:
532: if ((ap->a_flag&SLOAD) == 0)
533: fracmem = 0.0;
534: else {
535: szptudot = UPAGES + clrnd(ctopt(ap->a_size+ap->a_tsiz));
536: fracmem = ((float)ap->a_rss+szptudot)/CLSIZE/ecmx;
537: if (ap->a_xccount)
538: fracmem += ((float)ap->a_txtrss)/CLSIZE/
539: ap->a_xccount/ecmx;
540: }
541: return (100.0 * fracmem);
542: }
543:
544: double
545: pcpu()
546: {
547: time_t time;
548:
549: time = mproc->p_time;
550: if (time == 0 || (mproc->p_flag&SLOAD) == 0)
551: return (0.0);
552: if (rawcpu)
553: return (100.0 * mproc->p_pctcpu);
554: return (100.0 * mproc->p_pctcpu / (1.0 - exp(time * log(ccpu))));
555: }
556:
557: getu()
558: {
559: struct pte *pteaddr, apte;
560: int pad1; /* avoid hardware botch */
561: struct pte arguutl[UPAGES+CLSIZE];
562: int pad2; /* avoid hardware botch */
563: register int i;
564: int ncl, size;
565:
566: size = sflg ? ctob(UPAGES) : sizeof (struct user);
567: if ((mproc->p_flag & SLOAD) == 0) {
568: lseek(swap, ctob(mproc->p_swaddr), 0);
569: if (read(swap, (char *)&user.user, size) != size) {
570: fprintf(stderr, "ps: cant read u for pid %d from %s\n",
571: mproc->p_pid, swapf);
572: return (0);
573: }
574: pcbpf = 0;
575: argaddr = 0;
576: return (1);
577: }
578: pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
579: KMlseek(kmem, kflg ? clear(pteaddr) : (int)pteaddr, 0);
580: if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
581: printf("ps: cant read indir pte at %x to get u for pid %d from %s\n",
582: pteaddr, mproc->p_pid, kmemf);
583: return (0);
584: }
585: lseek(mem,
586: ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte), 0);
587: if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
588: printf("ps: cant read page table for u of pid %d from %s\n",
589: mproc->p_pid, memf);
590: return (0);
591: }
592: if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
593: argaddr = ctob(arguutl[0].pg_pfnum);
594: else
595: argaddr = 0;
596: pcbpf = arguutl[CLSIZE].pg_pfnum;
597: ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
598: while (--ncl >= 0) {
599: i = ncl * CLSIZE;
600: lseek(mem, ctob(arguutl[CLSIZE+i].pg_pfnum), 0);
601: if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
602: printf("ps: cant read page %d of u of pid %d from %s\n",
603: arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, memf);
604: return(0);
605: }
606: }
607: return (1);
608: }
609:
610: char *
611: getcmd()
612: {
613: char cmdbuf[BUFSIZ];
614: int pad1; /* avoid hardware botch */
615: union {
616: char argc[CLSIZE*NBPG];
617: int argi[CLSIZE*NBPG/sizeof (int)];
618: } argspac;
619: int pad2; /* avoid hardware botch */
620: register char *cp;
621: register int *ip;
622: char c;
623: int nbad;
624: struct dblock db;
625:
626: if (mproc->p_stat == SZOMB || mproc->p_flag&(SSYS|SWEXIT))
627: return ("");
628: if (cflg) {
629: strncpy(cmdbuf, u.u_comm, sizeof (u.u_comm));
630: return (savestr(cmdbuf));
631: }
632: if ((mproc->p_flag & SLOAD) == 0 || argaddr == 0) {
633: vstodb(0, CLSIZE, &u.u_smap, &db, 1);
634: lseek(swap, ctob(db.db_base), 0);
635: if (read(swap, (char *)&argspac, sizeof(argspac))
636: != sizeof(argspac))
637: goto bad;
638: } else {
639: lseek(mem, argaddr, 0);
640: if (read(mem, (char *)&argspac, sizeof (argspac))
641: != sizeof (argspac))
642: goto bad;
643: }
644: ip = &argspac.argi[CLSIZE*NBPG/sizeof (int)];
645: ip -= 2; /* last arg word and .long 0 */
646: while (*--ip)
647: if (ip == argspac.argi)
648: goto retucomm;
649: *(char *)ip = ' ';
650: ip++;
651: nbad = 0;
652: for (cp = (char *)ip; cp < &argspac.argc[CLSIZE*NBPG]; cp++) {
653: c = *cp & 0177;
654: if (c == 0)
655: *cp = ' ';
656: else if (c < ' ' || c > 0176) {
657: if (++nbad >= 5*(eflg+1)) {
658: *cp++ = ' ';
659: break;
660: }
661: *cp = '?';
662: } else if (eflg == 0 && c == '=') {
663: while (*--cp != ' ')
664: if (cp <= (char *)ip)
665: break;
666: break;
667: }
668: }
669: *cp = 0;
670: while (*--cp == ' ')
671: *cp = 0;
672: cp = (char *)ip;
673: strncpy(cmdbuf, cp, &argspac.argc[CLSIZE*NBPG] - cp);
674: if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') {
675: strcat(cmdbuf, " (");
676: strncat(cmdbuf, u.u_comm, sizeof(u.u_comm));
677: strcat(cmdbuf, ")");
678: }
679: if (xflg == 0 && gflg == 0 && tptr == 0 && cp[0] == '-')
680: return (0);
681: return (savestr(cmdbuf));
682:
683: bad:
684: fprintf(stderr, "ps: error locating command name for pid %d\n",
685: mproc->p_pid);
686: retucomm:
687: strcpy(cmdbuf, " (");
688: strncat(cmdbuf, u.u_comm, sizeof (u.u_comm));
689: strcat(cmdbuf, ")");
690: return (savestr(cmdbuf));
691: }
692:
693: char *lhdr =
694: "F UID PID PPID CP PRI NI ADDR SZ RSS WCHAN STAT TTY TIME";
695: lpr(sp)
696: struct savcom *sp;
697: {
698: register struct asav *ap = sp->ap;
699: register struct lsav *lp = sp->sun.lp;
700:
701: printf("%x%5d%6u%6u%4d%4d%4d%5x%4d%5d",
702: ap->a_flag, ap->a_uid,
703: ap->a_pid, lp->l_ppid, lp->l_cpu&0377, ap->a_pri-PZERO,
704: ap->a_nice-NZERO, lp->l_addr, ap->a_size/2, ap->a_rss/2);
705: printf(lp->l_wchan ? "%9x" : " ", (int)lp->l_wchan&~0x80000000);
706: printf(" %4.4s ", state(ap));
707: ptty(ap->a_tty);
708: ptime(ap);
709: }
710:
711: ptty(tp)
712: char *tp;
713: {
714:
715: printf("%-5.5s", tp);
716: }
717:
718: ptime(ap)
719: struct asav *ap;
720: {
721:
722: printf("%4ld:%02ld", ap->a_cpu / hz, ap->a_cpu % hz);
723: }
724:
725: char *uhdr =
726: "USER PID %CPU %MEM SZ RSS TTY STAT TIME";
727: upr(sp)
728: struct savcom *sp;
729: {
730: register struct asav *ap = sp->ap;
731: int vmsize, rmsize;
732:
733: vmsize = (ap->a_size + ap->a_tsiz)/2;
734: rmsize = ap->a_rss/2;
735: if (ap->a_xccount)
736: rmsize += ap->a_txtrss/ap->a_xccount/2;
737: printf("%-8.8s %5d%5.1f%5.1f%5d%5d",
738: getname(ap->a_uid), ap->a_pid, sp->sun.u_pctcpu, pmem(ap),
739: vmsize, rmsize);
740: putchar(' ');
741: ptty(ap->a_tty);
742: printf(" %4.4s", state(ap));
743: ptime(ap);
744: }
745:
746: char *vhdr =
747: " PID TTY STAT TIME SL RE PAGEIN SIZE RSS LIM TSIZ TRS %CPU %MEM";
748: vpr(sp)
749: struct savcom *sp;
750: {
751: register struct vsav *vp = sp->sun.vp;
752: register struct asav *ap = sp->ap;
753:
754: printf("%5u ", ap->a_pid);
755: ptty(ap->a_tty);
756: printf(" %4.4s", state(ap));
757: ptime(ap);
758: printf("%3d%3d%7d%5d%5d",
759: ap->a_slptime > 99 ? 99 : ap-> a_slptime,
760: ap->a_time > 99 ? 99 : ap->a_time, vp->v_majflt,
761: ap->a_size/2, ap->a_rss/2);
762: if (ap->a_maxrss == (INFINITY/NBPG))
763: printf(" xx");
764: else
765: printf("%5d", ap->a_maxrss/2);
766: printf("%5d%4d%5.1f%5.1f",
767: ap->a_tsiz/2, ap->a_txtrss/2, vp->v_pctcpu, pmem(ap));
768: }
769:
770: char *shdr =
771: "SSIZ PID TTY STAT TIME";
772: spr(sp)
773: struct savcom *sp;
774: {
775: register struct asav *ap = sp->ap;
776:
777: if (sflg)
778: printf("%4d ", sp->sun.s_ssiz);
779: printf("%5u", ap->a_pid);
780: putchar(' ');
781: ptty(ap->a_tty);
782: printf(" %4.4s", state(ap));
783: ptime(ap);
784: }
785:
786: char *
787: state(ap)
788: register struct asav *ap;
789: {
790: char stat, load, nice, anom;
791: static char res[5];
792:
793: switch (ap->a_stat) {
794:
795: case SSTOP:
796: stat = 'T';
797: break;
798:
799: case SSLEEP:
800: if (ap->a_pri >= PZERO)
801: if (ap->a_slptime >= MAXSLP)
802: stat = 'I';
803: else
804: stat = 'S';
805: else if (ap->a_flag & SPAGE)
806: stat = 'P';
807: else
808: stat = 'D';
809: break;
810:
811: case SWAIT:
812: case SRUN:
813: case SIDL:
814: stat = 'R';
815: break;
816:
817: case SZOMB:
818: stat = 'Z';
819: break;
820:
821: default:
822: stat = '?';
823: }
824: load = ap->a_flag & SLOAD ? (ap->a_rss>ap->a_maxrss ? '>' : ' ') : 'W';
825: if (ap->a_nice < NZERO)
826: nice = '<';
827: else if (ap->a_nice > NZERO)
828: nice = 'N';
829: else
830: nice = ' ';
831: anom = (ap->a_flag&SUANOM) ? 'A' : ((ap->a_flag&SSEQL) ? 'S' : ' ');
832: res[0] = stat; res[1] = load; res[2] = nice; res[3] = anom;
833: return (res);
834: }
835:
836: /*
837: * Given a base/size pair in virtual swap area,
838: * return a physical base/size pair which is the
839: * (largest) initial, physically contiguous block.
840: */
841: vstodb(vsbase, vssize, dmp, dbp, rev)
842: register int vsbase;
843: int vssize;
844: struct dmap *dmp;
845: register struct dblock *dbp;
846: {
847: register int blk = DMMIN;
848: register swblk_t *ip = dmp->dm_map;
849:
850: if (vsbase < 0 || vsbase + vssize > dmp->dm_size)
851: panic("vstodb");
852: while (vsbase >= blk) {
853: vsbase -= blk;
854: if (blk < DMMAX)
855: blk *= 2;
856: ip++;
857: }
858: if (*ip <= 0 || *ip + blk > nswap)
859: panic("vstodb *ip");
860: dbp->db_size = min(vssize, blk - vsbase);
861: dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
862: }
863:
864: /*ARGSUSED*/
865: panic(cp)
866: char *cp;
867: {
868:
869: #ifdef DEBUG
870: printf("%s\n", cp);
871: #endif
872: }
873:
874: min(a, b)
875: {
876:
877: return (a < b ? a : b);
878: }
879:
880: pscomp(s1, s2)
881: struct savcom *s1, *s2;
882: {
883: register int i;
884:
885: if (uflg)
886: return (s2->sun.u_pctcpu > s1->sun.u_pctcpu ? 1 : -1);
887: if (vflg)
888: return (vsize(s2) - vsize(s1));
889: i = s1->ap->a_ttyd - s2->ap->a_ttyd;
890: if (i == 0)
891: i = s1->ap->a_pid - s2->ap->a_pid;
892: return (i);
893: }
894:
895: vsize(sp)
896: struct savcom *sp;
897: {
898: register struct asav *ap = sp->ap;
899: register struct vsav *vp = sp->sun.vp;
900:
901: if (ap->a_flag & SLOAD)
902: return (ap->a_rss +
903: ap->a_txtrss / (ap->a_xccount ? ap->a_xccount : 1));
904: return (vp->v_swrss + (ap->a_xccount ? 0 : vp->v_txtswrss));
905: }
906:
907: #define NMAX 8
908: #define NUID 2048
909:
910: char names[NUID][NMAX+1];
911:
912: /*
913: * Stolen from ls...
914: */
915: char *
916: getname(uid)
917: {
918: register struct passwd *pw;
919: static init;
920: struct passwd *getpwent();
921:
922: if (uid >= 0 && uid < NUID && names[uid][0])
923: return (&names[uid][0]);
924: if (init == 2)
925: return (0);
926: if (init == 0)
927: setpwent(), init = 1;
928: while (pw = getpwent()) {
929: if (pw->pw_uid >= NUID)
930: continue;
931: if (names[pw->pw_uid][0])
932: continue;
933: strncpy(names[pw->pw_uid], pw->pw_name, NMAX);
934: if (pw->pw_uid == uid)
935: return (&names[uid][0]);
936: }
937: init = 2;
938: endpwent();
939: return (0);
940: }
941:
942: char *freebase;
943: int nleft;
944:
945: char *
946: alloc(size)
947: int size;
948: {
949: register char *cp;
950: register int i;
951:
952: if (size > nleft) {
953: freebase = (char *)sbrk(i = size > 2048 ? size : 2048);
954: if (freebase == 0) {
955: fprintf(stderr, "ps: ran out of memory\n");
956: exit(1);
957: }
958: nleft = i - size;
959: } else
960: nleft -= size;
961: cp = freebase;
962: for (i = size; --i >= 0; )
963: *cp++ = 0;
964: freebase = cp;
965: return (cp - size);
966: }
967:
968: char *
969: savestr(cp)
970: char *cp;
971: {
972: register int len;
973: register char *dp;
974:
975: len = strlen(cp);
976: dp = (char *)alloc(len+1);
977: strcpy(dp, cp);
978: return (dp);
979: }
980:
981: KMlseek(f, a, c)
982: long a;
983: {
984: if (kflg)
985: a = clear(a);
986: lseek(f, a, c);
987: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.