1*1346Sbill /*
2*1346Sbill * ps; VAX 4BSD version
3*1346Sbill */
4*1346Sbill
5*1346Sbill #include <stdio.h>
6*1346Sbill #include <ctype.h>
7*1346Sbill #include <olda.out.h>
8*1346Sbill #include <pwd.h>
9*1346Sbill #include <sys/param.h>
10*1346Sbill #include <sys/tty.h>
11*1346Sbill #include <sys/dir.h>
12*1346Sbill #include <sys/user.h>
13*1346Sbill #include <sys/proc.h>
14*1346Sbill #include <sys/pte.h>
15*1346Sbill #include <sys/vm.h>
16*1346Sbill #include <sys/text.h>
17*1346Sbill #include <sys/stat.h>
18*1346Sbill
19*1346Sbill struct nlist nl[] = {
20*1346Sbill { "_proc" },
21*1346Sbill #define X_PROC 0
22*1346Sbill { "_Usrptma" },
23*1346Sbill #define X_USRPTMA 1
24*1346Sbill { "_usrpt" },
25*1346Sbill #define X_USRPT 2
26*1346Sbill { "_text" },
27*1346Sbill #define X_TEXT 3
28*1346Sbill { "_nswap" },
29*1346Sbill #define X_NSWAP 4
30*1346Sbill { 0 },
31*1346Sbill };
32*1346Sbill
33*1346Sbill struct savcom {
34*1346Sbill union {
35*1346Sbill struct lsav *lp;
36*1346Sbill float u_pctcpu;
37*1346Sbill struct vsav *vp;
38*1346Sbill int s_ssiz;
39*1346Sbill } sun;
40*1346Sbill struct asav *ap;
41*1346Sbill } savcom[NPROC];
42*1346Sbill
43*1346Sbill struct asav {
44*1346Sbill char *a_cmdp;
45*1346Sbill int a_flag;
46*1346Sbill short a_stat, a_uid, a_pid, a_nice;
47*1346Sbill size_t a_size, a_rss;
48*1346Sbill char a_tty[4];
49*1346Sbill dev_t a_ttyd;
50*1346Sbill time_t a_time;
51*1346Sbill };
52*1346Sbill
53*1346Sbill char *lhdr;
54*1346Sbill /* F S UID PID PPID CP PRI NICE ADDR SZ RSS WCHAN TTY TIME */
55*1346Sbill struct lsav {
56*1346Sbill short l_ppid;
57*1346Sbill char l_cpu, l_pri;
58*1346Sbill int l_addr;
59*1346Sbill caddr_t l_wchan;
60*1346Sbill };
61*1346Sbill
62*1346Sbill char *uhdr;
63*1346Sbill /* USER PID %%CPU NICE SZ RSS TTY TIME */
64*1346Sbill
65*1346Sbill char *shdr;
66*1346Sbill /* SSIZ PID TTY TIME */
67*1346Sbill
68*1346Sbill char *vhdr;
69*1346Sbill /* F PID TT TIME TIM SL MINFLT MAJFLT SIZE RSS SRS TSIZ TRS PF*/
70*1346Sbill struct vsav {
71*1346Sbill short v_slptime, v_pri;
72*1346Sbill u_int v_minflt, v_majflt;
73*1346Sbill size_t v_swrss, v_tsiz, v_txtrss, v_txtswrss;
74*1346Sbill short v_xccount;
75*1346Sbill short v_aveflt;
76*1346Sbill };
77*1346Sbill
78*1346Sbill struct proc mproc;
79*1346Sbill struct text *text;
80*1346Sbill
81*1346Sbill union {
82*1346Sbill struct user user;
83*1346Sbill char upages[UPAGES][NBPG];
84*1346Sbill } user;
85*1346Sbill #define u user.user
86*1346Sbill
87*1346Sbill #define clear(x) ((int)x & 0x7fffffff)
88*1346Sbill
89*1346Sbill int chkpid;
90*1346Sbill int aflg, cflg, gflg, kflg, lflg, sflg, uflg, vflg, xflg;
91*1346Sbill char *tptr;
92*1346Sbill char *gettty(), *getcmd(), *getname(), *savestr(), *alloc();
93*1346Sbill int pscomp();
94*1346Sbill int nswap;
95*1346Sbill struct pte *Usrptma, *usrpt;
96*1346Sbill
97*1346Sbill int ndev;
98*1346Sbill struct devl {
99*1346Sbill char dname[DIRSIZ];
100*1346Sbill dev_t dev;
101*1346Sbill struct devl *next;
102*1346Sbill struct devl *cand;
103*1346Sbill } devl[256], *cand[16], *cons;
104*1346Sbill
105*1346Sbill struct savcom savcom[NPROC];
106*1346Sbill int npr;
107*1346Sbill
108*1346Sbill int cmdstart;
109*1346Sbill int twidth;
110*1346Sbill char *kmemf, *memf, *swapf, *nlistf;
111*1346Sbill int kmem, mem, swap;
112*1346Sbill
113*1346Sbill int pcbpf;
114*1346Sbill int argaddr;
115*1346Sbill extern char _sobuf[];
116*1346Sbill
main(argc,argv)117*1346Sbill main(argc, argv)
118*1346Sbill char **argv;
119*1346Sbill {
120*1346Sbill register int i;
121*1346Sbill register char *ap;
122*1346Sbill int uid;
123*1346Sbill off_t procp;
124*1346Sbill
125*1346Sbill setbuf(stdout, _sobuf);
126*1346Sbill argc--, argv++;
127*1346Sbill if (argc > 0) {
128*1346Sbill ap = argv[0];
129*1346Sbill while (*ap) switch (*ap++) {
130*1346Sbill
131*1346Sbill case 'a':
132*1346Sbill aflg++;
133*1346Sbill break;
134*1346Sbill case 'c':
135*1346Sbill cflg = !cflg;
136*1346Sbill break;
137*1346Sbill case 'g':
138*1346Sbill gflg++;
139*1346Sbill break;
140*1346Sbill case 'k':
141*1346Sbill kflg++;
142*1346Sbill break;
143*1346Sbill case 'l':
144*1346Sbill lflg++;
145*1346Sbill break;
146*1346Sbill case 's':
147*1346Sbill sflg++;
148*1346Sbill break;
149*1346Sbill case 't':
150*1346Sbill if (*ap)
151*1346Sbill tptr = ap;
152*1346Sbill aflg++;
153*1346Sbill gflg++;
154*1346Sbill if (*tptr == '?')
155*1346Sbill xflg++;
156*1346Sbill while (*ap)
157*1346Sbill ap++;
158*1346Sbill break;
159*1346Sbill case 'u':
160*1346Sbill uflg++;
161*1346Sbill break;
162*1346Sbill case 'v':
163*1346Sbill cflg = 1;
164*1346Sbill vflg++;
165*1346Sbill break;
166*1346Sbill case 'w':
167*1346Sbill if (twidth == 80)
168*1346Sbill twidth = 132;
169*1346Sbill else
170*1346Sbill twidth = BUFSIZ;
171*1346Sbill break;
172*1346Sbill case 'x':
173*1346Sbill xflg++;
174*1346Sbill break;
175*1346Sbill default:
176*1346Sbill if (!isdigit(ap[-1]))
177*1346Sbill break;
178*1346Sbill chkpid = atoi(--ap);
179*1346Sbill *ap = 0;
180*1346Sbill aflg++;
181*1346Sbill xflg++;
182*1346Sbill break;
183*1346Sbill }
184*1346Sbill }
185*1346Sbill openfiles(argc, argv);
186*1346Sbill getkvars(argc, argv);
187*1346Sbill getdev();
188*1346Sbill uid = getuid();
189*1346Sbill printhdr();
190*1346Sbill procp = nl[X_PROC].n_value;
191*1346Sbill for (i=0; i<NPROC; i++) {
192*1346Sbill lseek(kmem, (char *)procp, 0);
193*1346Sbill if (read(kmem, (char *)&mproc, sizeof mproc) != sizeof mproc)
194*1346Sbill cantread("proc table", kmemf);
195*1346Sbill procp += sizeof (mproc);
196*1346Sbill if (mproc.p_stat == 0 || mproc.p_pgrp == 0 && xflg == 0)
197*1346Sbill continue;
198*1346Sbill if (tptr == 0 && gflg == 0 && xflg == 0 &&
199*1346Sbill mproc.p_ppid == 1 && (mproc.p_flag&SDETACH) == 0)
200*1346Sbill continue;
201*1346Sbill if (uid != mproc.p_uid && aflg==0 ||
202*1346Sbill chkpid != 0 && chkpid != mproc.p_pid)
203*1346Sbill continue;
204*1346Sbill if (vflg && gflg == 0 && xflg == 0) {
205*1346Sbill if (mproc.p_stat == SZOMB)
206*1346Sbill continue;
207*1346Sbill if (mproc.p_slptime > MAXSLP &&
208*1346Sbill (mproc.p_stat == SSLEEP || mproc.p_stat == SSTOP))
209*1346Sbill continue;
210*1346Sbill }
211*1346Sbill save();
212*1346Sbill }
213*1346Sbill qsort(savcom, npr, sizeof(savcom[0]), pscomp);
214*1346Sbill for (i=0; i<npr; i++) {
215*1346Sbill register struct savcom *sp = &savcom[i];
216*1346Sbill if (lflg)
217*1346Sbill lpr(sp);
218*1346Sbill else if (vflg)
219*1346Sbill vpr(sp);
220*1346Sbill else if (uflg)
221*1346Sbill upr(sp);
222*1346Sbill else
223*1346Sbill spr(sp);
224*1346Sbill if (sp->ap->a_pid == 0)
225*1346Sbill printf(" swapper");
226*1346Sbill else if (sp->ap->a_pid == 2)
227*1346Sbill printf(" pagedaemon");
228*1346Sbill else
229*1346Sbill printf(" %.*s", twidth - cmdstart - 2, sp->ap->a_cmdp);
230*1346Sbill printf("\n");
231*1346Sbill }
232*1346Sbill exit(npr == 0);
233*1346Sbill }
234*1346Sbill
openfiles(argc,argv)235*1346Sbill openfiles(argc, argv)
236*1346Sbill char **argv;
237*1346Sbill {
238*1346Sbill
239*1346Sbill kmemf = "/dev/kmem";
240*1346Sbill if (kflg)
241*1346Sbill kmemf = argc > 1 ? argv[1] : "/vmcore";
242*1346Sbill kmem = open(kmemf, 0);
243*1346Sbill if (kmem < 0) {
244*1346Sbill perror(kmemf);
245*1346Sbill exit(1);
246*1346Sbill }
247*1346Sbill if (kflg) {
248*1346Sbill mem = kmem;
249*1346Sbill memf = kmemf;
250*1346Sbill } else {
251*1346Sbill memf = "/dev/mem";
252*1346Sbill mem = open(memf, 0);
253*1346Sbill if (mem < 0) {
254*1346Sbill perror(memf);
255*1346Sbill exit(1);
256*1346Sbill }
257*1346Sbill }
258*1346Sbill swapf = argc>2 ? argv[2]: "/dev/drum";
259*1346Sbill swap = open(swapf, 0);
260*1346Sbill if (swap < 0) {
261*1346Sbill perror(swapf);
262*1346Sbill exit(1);
263*1346Sbill }
264*1346Sbill }
265*1346Sbill
getkvars(argc,argv)266*1346Sbill getkvars(argc, argv)
267*1346Sbill char **argv;
268*1346Sbill {
269*1346Sbill register struct nlist *nlp;
270*1346Sbill
271*1346Sbill nlistf = argc > 3 ? argv[3] : "/vmunix";
272*1346Sbill nlist(nlistf, nl);
273*1346Sbill if (nl[0].n_type == 0) {
274*1346Sbill fprintf(stderr, "%s: No namelist\n", nlistf);
275*1346Sbill exit(1);
276*1346Sbill }
277*1346Sbill if (chdir("/dev") < 0) {
278*1346Sbill perror("/dev");
279*1346Sbill exit(1);
280*1346Sbill }
281*1346Sbill if (kflg)
282*1346Sbill for (nlp = nl; nlp < &nl[sizeof (nl)/sizeof (nl[0])]; nlp++)
283*1346Sbill nlp->n_value = clear(nlp->n_value);
284*1346Sbill Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
285*1346Sbill usrpt = (struct pte *)nl[X_USRPT].n_value;
286*1346Sbill lseek(kmem, (long)nl[X_NSWAP].n_value, 0);
287*1346Sbill if (read(kmem, &nswap, sizeof (nswap)) != sizeof (nswap)) {
288*1346Sbill /*###287 [lint] read arg. 2 used inconsistently ps.c(41) :: ps.c(287)%%%*/
289*1346Sbill cantread("nswap", kmemf);
290*1346Sbill /*###288 [lint] cantread arg. 1 used inconsistently ps.c(322) :: ps.c(288)%%%*/
291*1346Sbill /*###288 [lint] cantread arg. 2 used inconsistently ps.c(322) :: ps.c(288)%%%*/
292*1346Sbill exit(1);
293*1346Sbill }
294*1346Sbill if (vflg) {
295*1346Sbill text = (struct text *)alloc(NTEXT * sizeof (struct text));
296*1346Sbill if (text == 0) {
297*1346Sbill fprintf(stderr, "no room for text table\n");
298*1346Sbill exit(1);
299*1346Sbill }
300*1346Sbill lseek(kmem, (long)nl[X_TEXT].n_value, 0);
301*1346Sbill if (read(kmem, text, sizeof (text)) != sizeof (text)) {
302*1346Sbill /*###298 [lint] read arg. 2 used inconsistently ps.c(41) :: ps.c(298)%%%*/
303*1346Sbill cantread("text table", kmemf);
304*1346Sbill /*###299 [lint] cantread arg. 1 used inconsistently ps.c(322) :: ps.c(299)%%%*/
305*1346Sbill /*###299 [lint] cantread arg. 2 used inconsistently ps.c(322) :: ps.c(299)%%%*/
306*1346Sbill exit(1);
307*1346Sbill }
308*1346Sbill }
309*1346Sbill }
310*1346Sbill
printhdr()311*1346Sbill printhdr()
312*1346Sbill {
313*1346Sbill char *hdr;
314*1346Sbill
315*1346Sbill if (sflg+lflg+vflg+uflg > 1) {
316*1346Sbill fprintf(stderr, "ps: specify only one of s,l,v and u\n");
317*1346Sbill exit(1);
318*1346Sbill }
319*1346Sbill hdr = lflg ? lhdr : (vflg ? vhdr : (uflg ? uhdr : shdr));
320*1346Sbill if (lflg+vflg+uflg+sflg == 0)
321*1346Sbill hdr += strlen(" SSIZ");
322*1346Sbill cmdstart = strlen(hdr);
323*1346Sbill printf("%s COMMAND\n", hdr);
324*1346Sbill fflush(stdout);
325*1346Sbill }
326*1346Sbill
cantread(what,fromwhat)327*1346Sbill cantread(what, fromwhat)
328*1346Sbill char *what, *fromwhat;
329*1346Sbill {
330*1346Sbill
331*1346Sbill fprintf(stderr, "ps: error reading %s from %s", what, fromwhat);
332*1346Sbill }
333*1346Sbill
getdev()334*1346Sbill getdev()
335*1346Sbill {
336*1346Sbill register FILE *df;
337*1346Sbill struct stat sbuf;
338*1346Sbill struct direct dbuf;
339*1346Sbill
340*1346Sbill if ((df = fopen("/dev", "r")) == NULL) {
341*1346Sbill fprintf(stderr, "Can't open /dev\n");
342*1346Sbill exit(1);
343*1346Sbill }
344*1346Sbill ndev = 0;
345*1346Sbill while (fread((char *)&dbuf, sizeof(dbuf), 1, df) == 1) {
346*1346Sbill if (dbuf.d_ino == 0)
347*1346Sbill continue;
348*1346Sbill if (stat(dbuf.d_name, &sbuf) < 0)
349*1346Sbill continue;
350*1346Sbill if ((sbuf.st_mode&S_IFMT) != S_IFCHR)
351*1346Sbill continue;
352*1346Sbill strcpy(devl[ndev].dname, dbuf.d_name);
353*1346Sbill devl[ndev].dev = sbuf.st_rdev;
354*1346Sbill ndev++;
355*1346Sbill }
356*1346Sbill fclose(df);
357*1346Sbill }
358*1346Sbill
save()359*1346Sbill save()
360*1346Sbill {
361*1346Sbill register struct savcom *sp;
362*1346Sbill register struct asav *ap;
363*1346Sbill register char *cp;
364*1346Sbill char *ttyp, *cmdp;
365*1346Sbill
366*1346Sbill if (mproc.p_stat != SZOMB && getu() == 0)
367*1346Sbill return;
368*1346Sbill ttyp = gettty();
369*1346Sbill if (tptr && strcmpn(tptr, ttyp, 2))
370*1346Sbill return;
371*1346Sbill sp = &savcom[npr];
372*1346Sbill cmdp = getcmd();
373*1346Sbill if (cmdp == 0)
374*1346Sbill return;
375*1346Sbill sp->ap = ap = (struct asav *)alloc(sizeof (struct asav));
376*1346Sbill sp->ap->a_cmdp = cmdp;
377*1346Sbill #define e(a,b) ap->a = mproc.b
378*1346Sbill e(a_flag, p_flag); e(a_stat, p_stat); e(a_nice, p_nice);
379*1346Sbill e(a_uid, p_uid); e(a_pid, p_pid); e(a_rss, p_rssize);
380*1346Sbill #undef e
381*1346Sbill ap->a_size = mproc.p_dsize + mproc.p_ssize;
382*1346Sbill ap->a_tty[0] = ttyp[0];
383*1346Sbill ap->a_tty[1] = ttyp[1] ? ttyp[1] : ' ';
384*1346Sbill ap->a_ttyd = u.u_ttyd;
385*1346Sbill ap->a_time = u.u_vm.vm_utime + u.u_vm.vm_stime;
386*1346Sbill if (lflg) {
387*1346Sbill register struct lsav *lp;
388*1346Sbill
389*1346Sbill sp->sun.lp = lp = (struct lsav *)alloc(sizeof (struct lsav));
390*1346Sbill #define e(a,b) lp->a = mproc.b
391*1346Sbill e(l_ppid, p_ppid); e(l_cpu, p_cpu);
392*1346Sbill e(l_pri, p_pri); e(l_wchan, p_wchan);
393*1346Sbill #undef e
394*1346Sbill lp->l_addr = pcbpf;
395*1346Sbill } else if (vflg) {
396*1346Sbill register struct vsav *vp;
397*1346Sbill register struct text *xp;
398*1346Sbill
399*1346Sbill sp->sun.vp = vp = (struct vsav *)alloc(sizeof (struct vsav));
400*1346Sbill #define e(a,b) vp->a = mproc.b
401*1346Sbill e(v_slptime, p_slptime); e(v_pri, p_pri);
402*1346Sbill e(v_swrss, p_swrss); e(v_aveflt, p_aveflt);
403*1346Sbill #undef e
404*1346Sbill vp->v_minflt = u.u_vm.vm_minflt;
405*1346Sbill vp->v_majflt = u.u_vm.vm_majflt;
406*1346Sbill if (mproc.p_textp) {
407*1346Sbill xp = &text[mproc.p_textp -
408*1346Sbill (struct text *)nl[X_TEXT].n_value];
409*1346Sbill vp->v_tsiz = xp->x_size;
410*1346Sbill vp->v_txtrss = xp->x_rssize;
411*1346Sbill vp->v_txtswrss = xp->x_swrss;
412*1346Sbill vp->v_xccount = xp->x_ccount;
413*1346Sbill } else {
414*1346Sbill vp->v_tsiz = 0;
415*1346Sbill vp->v_txtrss = 0;
416*1346Sbill vp->v_xccount = 0;
417*1346Sbill vp->v_txtswrss = 0;
418*1346Sbill }
419*1346Sbill } else if (uflg)
420*1346Sbill sp->sun.u_pctcpu = 0.0;
421*1346Sbill else if (sflg) {
422*1346Sbill for (cp = (char *)u.u_stack;
423*1346Sbill cp < (char *)&u + ctob(UPAGES); )
424*1346Sbill if (*cp++)
425*1346Sbill break;
426*1346Sbill sp->sun.s_ssiz = (int) ((char *)&u + ctob(UPAGES) - cp);
427*1346Sbill }
428*1346Sbill npr++;
429*1346Sbill }
430*1346Sbill
getu()431*1346Sbill getu()
432*1346Sbill {
433*1346Sbill struct pte *pteaddr, apte, arguutl[UPAGES+CLSIZE];
434*1346Sbill register int i;
435*1346Sbill int ncl, size;
436*1346Sbill
437*1346Sbill size = sflg ? ctob(UPAGES) : sizeof (struct user);
438*1346Sbill if ((mproc.p_flag & SLOAD) == 0) {
439*1346Sbill lseek(swap, ctob(mproc.p_swaddr), 0);
440*1346Sbill if (read(swap, (char *)&u, size) != size) {
441*1346Sbill fprintf(stderr, "ps: cant read u for pid %d from %s\n",
442*1346Sbill mproc.p_pid, swapf);
443*1346Sbill return (0);
444*1346Sbill }
445*1346Sbill pcbpf = 0;
446*1346Sbill argaddr = 0;
447*1346Sbill return (1);
448*1346Sbill }
449*1346Sbill pteaddr = &Usrptma[btokmx(mproc.p_p0br) + mproc.p_szpt - 1];
450*1346Sbill lseek(kmem, kflg ? clear(pteaddr) : (int)pteaddr, 0);
451*1346Sbill if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
452*1346Sbill printf("ps: cant read indir pte to get u for pid %d from %s\n",
453*1346Sbill mproc.p_pid, swapf);
454*1346Sbill return (0);
455*1346Sbill }
456*1346Sbill lseek(mem,
457*1346Sbill ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte), 0);
458*1346Sbill if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
459*1346Sbill printf("ps: cant read page table for u of pid %d from %s\n",
460*1346Sbill mproc.p_pid, swapf);
461*1346Sbill return (0);
462*1346Sbill }
463*1346Sbill if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
464*1346Sbill argaddr = ctob(arguutl[0].pg_pfnum);
465*1346Sbill else
466*1346Sbill argaddr = 0;
467*1346Sbill pcbpf = arguutl[CLSIZE].pg_pfnum;
468*1346Sbill ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
469*1346Sbill while (--ncl >= 0) {
470*1346Sbill i = ncl * CLSIZE;
471*1346Sbill lseek(mem, ctob(arguutl[CLSIZE+i].pg_pfnum), 0);
472*1346Sbill if (read(mem, user.upages[CLSIZE+i], CLSIZE*NBPG)
473*1346Sbill != CLSIZE*NBPG) {
474*1346Sbill printf("ps: cant read page %d of u of pid %d from %s\n",
475*1346Sbill arguutl[CLSIZE+i].pg_pfnum, mproc.p_pid, memf);
476*1346Sbill return(0);
477*1346Sbill }
478*1346Sbill }
479*1346Sbill return (1);
480*1346Sbill }
481*1346Sbill
482*1346Sbill char *
getcmd()483*1346Sbill getcmd()
484*1346Sbill {
485*1346Sbill char cmdbuf[BUFSIZ];
486*1346Sbill union {
487*1346Sbill char argc[CLSIZE*NBPG];
488*1346Sbill int argi[CLSIZE*NBPG/sizeof (int)];
489*1346Sbill } argspac;
490*1346Sbill register char *cp;
491*1346Sbill register int *ip;
492*1346Sbill char c;
493*1346Sbill int nbad;
494*1346Sbill struct dblock db;
495*1346Sbill
496*1346Sbill if (mproc.p_stat == SZOMB)
497*1346Sbill return ("");
498*1346Sbill if (cflg)
499*1346Sbill goto retucomm;
500*1346Sbill if ((mproc.p_flag & SLOAD) == 0 || argaddr == 0) {
501*1346Sbill vstodb(0, CLSIZE, &u.u_smap, &db, 1);
502*1346Sbill lseek(swap, ctob(db.db_base), 0);
503*1346Sbill if (read(swap, (char *)&argspac, sizeof(argspac))
504*1346Sbill != sizeof(argspac))
505*1346Sbill goto bad;
506*1346Sbill } else {
507*1346Sbill lseek(mem, argaddr, 0);
508*1346Sbill if (read(mem, (char *)&argspac, sizeof (argspac))
509*1346Sbill != sizeof (argspac))
510*1346Sbill goto bad;
511*1346Sbill }
512*1346Sbill ip = &argspac.argi[CLSIZE*NBPG/sizeof (int)];
513*1346Sbill *--ip = 0;
514*1346Sbill while (*--ip)
515*1346Sbill if (ip == argspac.argi)
516*1346Sbill goto retucomm;
517*1346Sbill *(char *)ip = ' ';
518*1346Sbill ip++;
519*1346Sbill nbad = 0;
520*1346Sbill for (cp = (char *)ip; cp < &argspac.argc[CLSIZE*NBPG]; cp++) {
521*1346Sbill c = *cp & 0177;
522*1346Sbill if (c == 0)
523*1346Sbill *cp = ' ';
524*1346Sbill else if (c < ' ' || c > 0176) {
525*1346Sbill if (++nbad >= 5) {
526*1346Sbill *cp++ = ' ';
527*1346Sbill break;
528*1346Sbill }
529*1346Sbill *cp = '?';
530*1346Sbill } else if (c == '=') {
531*1346Sbill while (*--cp != ' ')
532*1346Sbill if (cp <= (char *)ip)
533*1346Sbill break;
534*1346Sbill break;
535*1346Sbill }
536*1346Sbill }
537*1346Sbill *cp = 0;
538*1346Sbill while (*--cp == ' ')
539*1346Sbill *cp = 0;
540*1346Sbill cp = (char *)ip;
541*1346Sbill strncpy(cmdbuf, cp, &argspac.argc[CLSIZE*NBPG] - cp);
542*1346Sbill if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') {
543*1346Sbill strcat(cp, " (");
544*1346Sbill strncat(cp, u.u_comm, sizeof(u.u_comm));
545*1346Sbill strcat(cp, ")");
546*1346Sbill }
547*1346Sbill if (xflg == 0 && gflg == 0 && tptr == 0 && cp[0] == '-')
548*1346Sbill return (0);
549*1346Sbill return (savestr(cmdbuf));
550*1346Sbill
551*1346Sbill bad:
552*1346Sbill fprintf(stderr, "ps: error locating command name for pid %d\n",
553*1346Sbill mproc.p_pid);
554*1346Sbill retucomm:
555*1346Sbill strcat(cp, " (");
556*1346Sbill strncpy(cmdbuf, u.u_comm, sizeof (u.u_comm));
557*1346Sbill strcat(cp, ")");
558*1346Sbill return (savestr(cmdbuf));
559*1346Sbill }
560*1346Sbill
561*1346Sbill char *lhdr =
562*1346Sbill " F S UID PID PPID CP PRI NICE ADDR SZ RSS WCHAN TTY TIME";
563*1346Sbill lpr(sp)
564*1346Sbill struct savcom *sp;
565*1346Sbill {
566*1346Sbill register struct asav *ap = sp->ap;
567*1346Sbill register struct lsav *lp = sp->sun.lp;
568*1346Sbill
569*1346Sbill printf("%5x %c %4d%5u%6u%3d%4d%4d%6x%4d%5d",
570*1346Sbill ap->a_flag, "0SWRIZT"[ap->a_stat], ap->a_uid,
571*1346Sbill ap->a_pid, lp->l_ppid, lp->l_cpu&0377, lp->l_pri-PZERO,
572*1346Sbill ap->a_nice-NZERO, lp->l_addr, ap->a_size, ap->a_rss);
573*1346Sbill printf(lp->l_wchan ? "%6x" : " ", lp->l_wchan);
574*1346Sbill ptty(ap->a_tty);
575*1346Sbill ptime(ap);
576*1346Sbill }
577*1346Sbill
ptty(tp)578*1346Sbill ptty(tp)
579*1346Sbill char *tp;
580*1346Sbill {
581*1346Sbill
582*1346Sbill printf(" %-2.2s", tp);
583*1346Sbill }
584*1346Sbill
585*1346Sbill ptime(ap)
586*1346Sbill struct asav *ap;
587*1346Sbill {
588*1346Sbill
589*1346Sbill if (ap->a_stat == SZOMB)
590*1346Sbill printf(" <defunct>");
591*1346Sbill else
592*1346Sbill printf("%3ld:%02ld", ap->a_time / HZ, ap->a_time % HZ);
593*1346Sbill }
594*1346Sbill
595*1346Sbill char *uhdr =
596*1346Sbill "USER PID %%CPU NICE SZ RSS TTY TIME";
597*1346Sbill upr(sp)
598*1346Sbill struct savcom *sp;
599*1346Sbill {
600*1346Sbill register struct asav *ap = sp->ap;
601*1346Sbill
602*1346Sbill printf("%-8.8s%5u%5.1f%4d%4d%5d",
603*1346Sbill getname(ap->a_uid), ap->a_pid, sp->sun.u_pctcpu, ap->a_nice,
604*1346Sbill ap->a_size, ap->a_rss);
605*1346Sbill ptty(ap->a_tty);
606*1346Sbill ptime(ap);
607*1346Sbill }
608*1346Sbill
609*1346Sbill char *vhdr =
610*1346Sbill "F PID TT TIME TIM SL MINFLT MAJFLT SIZE RSS SRS TSIZ TRS PF";
611*1346Sbill vpr(sp)
612*1346Sbill struct savcom *sp;
613*1346Sbill {
614*1346Sbill register struct vsav *vp = sp->sun.vp;
615*1346Sbill register struct asav *ap = sp->ap;
616*1346Sbill char stat, nice, anom;
617*1346Sbill
618*1346Sbill switch (ap->a_stat) {
619*1346Sbill
620*1346Sbill case SSLEEP:
621*1346Sbill case SSTOP:
622*1346Sbill if ((ap->a_flag & SLOAD) == 0)
623*1346Sbill stat = 'W';
624*1346Sbill else if (vp->v_pri >= PZERO)
625*1346Sbill stat = 'S';
626*1346Sbill else if (ap->a_flag & SPAGE)
627*1346Sbill stat = 'P';
628*1346Sbill else
629*1346Sbill stat = 'D';
630*1346Sbill break;
631*1346Sbill
632*1346Sbill case SRUN:
633*1346Sbill case SIDL:
634*1346Sbill stat = ap->a_flag & SLOAD ? 'R' : 'W';
635*1346Sbill break;
636*1346Sbill }
637*1346Sbill nice = ap->a_nice > NZERO ? 'N' : ' ';
638*1346Sbill anom = ap->a_flag & (SANOM|SUANOM) ? 'A' : ' ';
639*1346Sbill printf("%c%c%c%5u", stat, nice, anom, ap->a_pid);
640*1346Sbill ptty(ap->a_tty);
641*1346Sbill ptime(ap);
642*1346Sbill printf("%3d%3d%8d%8d%5d%5d%5d%5d%4d%3d",
643*1346Sbill ap->a_time, vp->v_slptime, vp->v_majflt, vp->v_minflt,
644*1346Sbill ap->a_size, ap->a_rss, vp->v_swrss, vp->v_tsiz, vp->v_txtrss,
645*1346Sbill vp->v_aveflt);
646*1346Sbill }
647*1346Sbill
648*1346Sbill char *shdr =
649*1346Sbill " SSIZ PID TTY TIME";
650*1346Sbill spr(sp)
651*1346Sbill struct savcom *sp;
652*1346Sbill {
653*1346Sbill register struct asav *ap = sp->ap;
654*1346Sbill
655*1346Sbill if (sflg)
656*1346Sbill printf("%5d", sp->sun.s_ssiz);
657*1346Sbill printf(" %5u", ap->a_pid);
658*1346Sbill ptty(ap->a_tty);
659*1346Sbill ptime(ap);
660*1346Sbill }
661*1346Sbill
662*1346Sbill char *
gettty()663*1346Sbill gettty()
664*1346Sbill {
665*1346Sbill register i;
666*1346Sbill register char *p;
667*1346Sbill
668*1346Sbill if (u.u_ttyp == 0)
669*1346Sbill return("?");
670*1346Sbill for (i=0; i<ndev; i++) {
671*1346Sbill if (devl[i].dev == u.u_ttyd) {
672*1346Sbill p = devl[i].dname;
673*1346Sbill if (p[0]=='t' && p[1]=='t' && p[2]=='y')
674*1346Sbill p += 3;
675*1346Sbill return(p);
676*1346Sbill }
677*1346Sbill }
678*1346Sbill return("?");
679*1346Sbill }
680*1346Sbill
681*1346Sbill /*
682*1346Sbill * Given a base/size pair in virtual swap area,
683*1346Sbill * return a physical base/size pair which is the
684*1346Sbill * (largest) initial, physically contiguous block.
685*1346Sbill */
vstodb(vsbase,vssize,dmp,dbp,rev)686*1346Sbill vstodb(vsbase, vssize, dmp, dbp, rev)
687*1346Sbill register int vsbase;
688*1346Sbill int vssize;
689*1346Sbill struct dmap *dmp;
690*1346Sbill register struct dblock *dbp;
691*1346Sbill {
692*1346Sbill register int blk = DMMIN;
693*1346Sbill register swblk_t *ip = dmp->dm_map;
694*1346Sbill
695*1346Sbill if (vsbase < 0 || vsbase + vssize > dmp->dm_size)
696*1346Sbill panic("vstodb");
697*1346Sbill while (vsbase >= blk) {
698*1346Sbill vsbase -= blk;
699*1346Sbill if (blk < DMMAX)
700*1346Sbill blk *= 2;
701*1346Sbill ip++;
702*1346Sbill }
703*1346Sbill if (*ip <= 0 || *ip + blk > nswap)
704*1346Sbill panic("vstodb *ip");
705*1346Sbill dbp->db_size = min(vssize, blk - vsbase);
706*1346Sbill dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
707*1346Sbill }
708*1346Sbill
709*1346Sbill /*ARGSUSED*/
panic(cp)710*1346Sbill panic(cp)
711*1346Sbill char *cp;
712*1346Sbill {
713*1346Sbill
714*1346Sbill #ifdef DEBUG
715*1346Sbill printf("%s\n", cp);
716*1346Sbill #endif
717*1346Sbill }
718*1346Sbill
min(a,b)719*1346Sbill min(a, b)
720*1346Sbill {
721*1346Sbill
722*1346Sbill return (a < b ? a : b);
723*1346Sbill }
724*1346Sbill
725*1346Sbill pscomp(s1, s2)
726*1346Sbill struct savcom *s1, *s2;
727*1346Sbill {
728*1346Sbill register int i;
729*1346Sbill
730*1346Sbill if (vflg)
731*1346Sbill return (vsize(s2) - vsize(s1));
732*1346Sbill i = s1->ap->a_ttyd - s2->ap->a_ttyd;
733*1346Sbill if (i == 0)
734*1346Sbill i = s1->ap->a_pid - s2->ap->a_pid;
735*1346Sbill return (i);
736*1346Sbill }
737*1346Sbill
738*1346Sbill vsize(sp)
739*1346Sbill struct savcom *sp;
740*1346Sbill {
741*1346Sbill register struct asav *ap = sp->ap;
742*1346Sbill register struct vsav *vp = sp->sun.vp;
743*1346Sbill
744*1346Sbill if (ap->a_flag & SLOAD)
745*1346Sbill return (ap->a_rss +
746*1346Sbill vp->v_txtrss / (vp->v_xccount ? vp->v_xccount : 1));
747*1346Sbill return (vp->v_swrss + (vp->v_xccount ? 0 : vp->v_txtswrss));
748*1346Sbill }
749*1346Sbill
750*1346Sbill #define NMAX 8
751*1346Sbill #define NUID 2048
752*1346Sbill
753*1346Sbill char names[NUID][NMAX+1];
754*1346Sbill
755*1346Sbill /*
756*1346Sbill * Stolen from ls...
757*1346Sbill */
758*1346Sbill char *
getname(uid)759*1346Sbill getname(uid)
760*1346Sbill {
761*1346Sbill register struct passwd *pw;
762*1346Sbill static init;
763*1346Sbill struct passwd *getpwent();
764*1346Sbill
765*1346Sbill if (names[uid][0])
766*1346Sbill return (&names[uid][0]);
767*1346Sbill if (init == 2)
768*1346Sbill return (0);
769*1346Sbill if (init == 0)
770*1346Sbill setpwent(), init = 1;
771*1346Sbill while (pw = getpwent()) {
772*1346Sbill if (pw->pw_uid >= NUID)
773*1346Sbill continue;
774*1346Sbill if (names[pw->pw_uid][0])
775*1346Sbill continue;
776*1346Sbill strncpy(names[pw->pw_uid], pw->pw_name, NMAX);
777*1346Sbill if (pw->pw_uid == uid)
778*1346Sbill return (&names[uid][0]);
779*1346Sbill }
780*1346Sbill init = 2;
781*1346Sbill endpwent();
782*1346Sbill return (0);
783*1346Sbill }
784*1346Sbill
785*1346Sbill char *freebase;
786*1346Sbill int nleft;
787*1346Sbill
788*1346Sbill char *
alloc(size)789*1346Sbill alloc(size)
790*1346Sbill int size;
791*1346Sbill {
792*1346Sbill register char *cp;
793*1346Sbill register int i;
794*1346Sbill
795*1346Sbill if (size > nleft) {
796*1346Sbill freebase = (char *)sbrk(size > 2048 ? size : 2048);
797*1346Sbill if (freebase == 0) {
798*1346Sbill fprintf(stderr, "ps: ran out of memory\n");
799*1346Sbill exit(1);
800*1346Sbill }
801*1346Sbill }
802*1346Sbill cp = freebase;
803*1346Sbill for (i = size; --i >= 0; )
804*1346Sbill *cp++ = 0;
805*1346Sbill freebase = cp;
806*1346Sbill return (cp - size);
807*1346Sbill }
808*1346Sbill
809*1346Sbill char *
savestr(cp)810*1346Sbill savestr(cp)
811*1346Sbill char *cp;
812*1346Sbill {
813*1346Sbill register int len;
814*1346Sbill register char *dp;
815*1346Sbill
816*1346Sbill len = strlen(cp);
817*1346Sbill dp = (char *)alloc(len+1);
818*1346Sbill strcpy(dp, cp);
819*1346Sbill return (dp);
820*1346Sbill }
821