new vm
[unix-history] / usr / src / bin / ps / print.c
CommitLineData
fd57c467
KB
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8#ifndef lint
1d2a7f51 9static char sccsid[] = "@(#)print.c 5.4 (Berkeley) %G%";
fd57c467
KB
10#endif /* not lint */
11
fd57c467
KB
12#include <sys/param.h>
13#include <sys/time.h>
14#include <sys/resource.h>
15#include <sys/proc.h>
16#include <sys/stat.h>
fd57c467
KB
17#include <math.h>
18#include <tzfile.h>
19#include <stddef.h>
20#include <string.h>
21#include "ps.h"
22
1d2a7f51
MK
23#ifdef SPPWAIT
24#define NEWVM
25#endif
26
27#ifdef NEWVM
28#include <vm/vm.h>
29#include <sys/ucred.h>
30#include <sys/kinfo_proc.h>
31#else
32#include <machine/pte.h>
33#include <sys/vmparam.h>
34#include <sys/vm.h>
35#endif
36
fd57c467
KB
37printheader()
38{
39 register VAR *v;
40
41 for (v = vhead; v; v = v->next) {
42 if (v->flag & LJUST) {
43 if (v->next == NULL) /* last one */
44 (void) printf("%s", v->header);
45 else
46 (void) printf("%-*s", v->width, v->header);
47 } else
48 (void) printf("%*s", v->width, v->header);
49 if (v->next != NULL)
50 (void) putchar(' ');
51 }
52 (void) putchar('\n');
53}
54
55command(k, v)
56 KINFO *k;
57 VAR *v;
58{
59 extern int termwidth, totwidth;
60
61 if (v->next == NULL) {
62 /* last field */
63 if (termwidth == UNLIMITED)
64 (void) printf("%s", k->ki_args);
65 else {
66 register int left = termwidth - (totwidth - v->width);
67 register char *cp = k->ki_args;
68
69 if (left < 1) /* already wrapped, just use std width */
70 left = v->width;
71 while (--left >= 0 && *cp)
72 (void) putchar(*cp++);
73 }
74 } else
75 (void) printf("%-*.*s", v->width, v->width, k->ki_args);
76
77}
78
79ucomm(k, v)
80 KINFO *k;
81 VAR *v;
82{
83 (void) printf("%-*s", v->width, k->ki_p->p_comm);
84}
85
86logname(k, v)
87 KINFO *k;
88 VAR *v;
89{
1d2a7f51 90#ifndef NEWVM
fd57c467 91 (void) printf("%-*s", v->width, k->ki_p->p_logname);
1d2a7f51
MK
92#else /* NEWVM */
93 (void) printf("%-*s", v->width, k->ki_e->e_login);
94#endif /* NEWVM */
fd57c467
KB
95}
96
97state(k, v)
98 KINFO *k;
99 VAR *v;
100{
101 char buf[16];
102 register char *cp = buf;
103 register struct proc *p = k->ki_p;
104 register flag = p->p_flag;
105
106 switch (p->p_stat) {
107
108 case SSTOP:
109 *cp = 'T';
110 break;
111
112 case SSLEEP:
113 if (flag & SSINTR) /* interuptable (long) */
114 *cp = p->p_slptime >= MAXSLP ? 'I' : 'S';
115 else
116 *cp = (flag & SPAGE) ? 'P' : 'D';
117 break;
118
119 case SRUN:
120 case SIDL:
121 *cp = 'R';
122 break;
123
124 case SZOMB:
125 *cp = 'Z';
126 break;
127
128 default:
129 *cp = '?';
130 }
131 cp++;
132 if (flag & SLOAD) {
1d2a7f51 133#ifndef NEWVM
fd57c467
KB
134 if (p->p_rssize > p->p_maxrss)
135 *cp++ = '>';
1d2a7f51 136#endif
fd57c467
KB
137 } else
138 *cp++ = 'W';
139 if (p->p_nice < NZERO)
140 *cp++ = '<';
141 else if (p->p_nice > NZERO)
142 *cp++ = 'N';
143 if (flag & SUANOM)
144 *cp++ = 'A';
145 else if (flag & SSEQL)
146 *cp++ = 'S';
147 if (flag & STRC)
148 *cp++ = 'X';
1d2a7f51 149 if (flag & SWEXIT && p->p_stat != SZOMB)
fd57c467 150 *cp++ = 'E';
1d2a7f51
MK
151#ifdef NEWVM
152 if (flag & SPPWAIT)
153#else
fd57c467 154 if (flag & SVFORK)
1d2a7f51 155#endif
fd57c467
KB
156 *cp++ = 'V';
157 if (flag & (SSYS|SLOCK|SULOCK|SKEEP|SPHYSIO))
158 *cp++ = 'L';
159 if (k->ki_e->e_flag & EPROC_SLEADER)
160 *cp++ = 's';
161 if ((flag & SCTTY) && k->ki_e->e_pgid == k->ki_e->e_tpgid)
162 *cp++ = '+';
163 *cp = '\0';
164 (void) printf("%-*s", v->width, buf);
165}
166
167pri(k, v)
168 KINFO *k;
169 VAR *v;
170{
171 (void) printf("%*d", v->width, k->ki_p->p_pri - PZERO);
172}
173
174uname(k, v)
175 KINFO *k;
176 VAR *v;
177{
1d2a7f51 178#ifndef NEWVM
fd57c467 179 (void) printf("%-*s", v->width, user_from_uid(k->ki_p->p_uid, 0));
1d2a7f51
MK
180#else /* NEWVM */
181 (void) printf("%-*s", v->width,
182 user_from_uid(k->ki_e->e_ucred.cr_uid, 0));
183#endif /* NEWVM */
fd57c467
KB
184}
185
186runame(k, v)
187 KINFO *k;
188 VAR *v;
189{
1d2a7f51 190#ifndef NEWVM
fd57c467 191 (void) printf("%-*s", v->width, user_from_uid(k->ki_p->p_ruid, 0));
1d2a7f51
MK
192#else /* NEWVM */
193 (void) printf("%-*s", v->width,
194 user_from_uid(k->ki_e->e_pcred.p_ruid, 0));
195#endif /* NEWVM */
fd57c467
KB
196}
197
198tdev(k, v)
199 KINFO *k;
200 VAR *v;
201{
202 dev_t dev = k->ki_e->e_tdev;
203
204 if (dev == NODEV)
205 (void) printf("%*s", v->width, "??");
206 else {
207 char buff[16];
208
209 (void) sprintf(buff, "%d/%d", major(dev), minor(dev));
210 (void) printf("%*s", v->width, buff);
211 }
212}
213
214tname(k, v)
215 KINFO *k;
216 VAR *v;
217{
218 dev_t dev;
219 char *ttname, *devname();
220
221 dev = k->ki_e->e_tdev;
222 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
223 (void) printf("%-*s", v->width, "??");
224 else {
225 if (strncmp(ttname, "tty", 3) == 0)
226 ttname += 3;
227 (void) printf("%*.*s%c", v->width-1, v->width-1, ttname,
228 k->ki_e->e_flag & EPROC_CTTY ? ' ' : '-');
229 }
230}
231
232longtname(k, v)
233 KINFO *k;
234 VAR *v;
235{
236 dev_t dev;
237 char *ttname, *devname();
238
239 dev = k->ki_e->e_tdev;
240 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
241 (void) printf("%-*s", v->width, "??");
242 else
243 (void) printf("%-*s", v->width, ttname);
244}
245
246started(k, v)
247 KINFO *k;
248 VAR *v;
249{
250 static time_t now;
251 struct tm *tp;
252 char buf[100];
253
254 if (!k->ki_u) {
255 (void) printf("%-*s", v->width, "-");
256 return;
257 }
258
259 tp = localtime(&k->ki_u->u_start.tv_sec);
260 if (!now)
261 (void)time(&now);
3be22949
KB
262 if (now - k->ki_u->u_start.tv_sec < 24 * SECSPERHOUR) {
263 static char *fmt = "%l:@M%p";
264 fmt[3] = '%'; /* I *hate* SCCS... */
265 (void) strftime(buf, sizeof(buf) - 1, fmt, tp);
266 } else if (now - k->ki_u->u_start.tv_sec < 7 * SECSPERDAY) {
267 static char *fmt = "%a@I%p";
268 fmt[2] = '%'; /* I *hate* SCCS... */
269 (void) strftime(buf, sizeof(buf) - 1, fmt, tp);
270 } else
fd57c467
KB
271 (void) strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
272 (void) printf("%-*s", v->width, buf);
273}
274
275lstarted(k, v)
276 KINFO *k;
277 VAR *v;
278{
279 char buf[100];
280
281 if (!k->ki_u) {
282 (void) printf("%-*s", v->width, "-");
283 return;
284 }
285 (void) strftime(buf, sizeof(buf) -1, "%C",
286 localtime(&k->ki_u->u_start.tv_sec));
287 (void) printf("%-*s", v->width, buf);
288}
289
290wchan(k, v)
291 KINFO *k;
292 VAR *v;
293{
294 if (k->ki_p->p_wchan) {
1d2a7f51 295 if (k->ki_p->p_wmesg)
fd57c467
KB
296 (void) printf("%-*.*s", v->width, v->width, k->ki_e->e_wmesg);
297 else
298 (void) printf("%*x", v->width,
299 (int)k->ki_p->p_wchan &~ KERNBASE);
300 } else
301 (void) printf("%-*s", v->width, "-");
302}
303
304#define pgtok(a) (((a)*NBPG)/1024)
305
306vsize(k, v)
307 KINFO *k;
308 VAR *v;
309{
310 (void) printf("%*d", v->width,
1d2a7f51 311#ifndef NEWVM
fd57c467 312 pgtok(k->ki_p->p_dsize + k->ki_p->p_ssize + k->ki_e->e_xsize));
1d2a7f51
MK
313#else /* NEWVM */
314 pgtok(k->ki_e->e_vm.vm_dsize + k->ki_e->e_vm.vm_ssize +
315 k->ki_e->e_vm.vm_tsize));
316#endif /* NEWVM */
fd57c467
KB
317}
318
319rssize(k, v)
320 KINFO *k;
321 VAR *v;
322{
1d2a7f51 323#ifndef NEWVM
fd57c467
KB
324 (void) printf("%*d", v->width,
325 pgtok(k->ki_p->p_rssize + (k->ki_e->e_xccount ?
326 (k->ki_e->e_xrssize / k->ki_e->e_xccount) : 0)));
1d2a7f51
MK
327#else /* NEWVM */
328 /* XXX don't have info about shared */
329 (void) printf("%*d", v->width, pgtok(k->ki_e->e_vm.vm_rssize));
330#endif /* NEWVM */
fd57c467
KB
331}
332
333p_rssize(k, v) /* doesn't account for text */
334 KINFO *k;
335 VAR *v;
336{
1d2a7f51 337#ifndef NEWVM
fd57c467 338 (void) printf("%*d", v->width, pgtok(k->ki_p->p_rssize));
1d2a7f51
MK
339#else /* NEWVM */
340 (void) printf("%*d", v->width, pgtok(k->ki_e->e_vm.vm_rssize));
341#endif /* NEWVM */
fd57c467
KB
342}
343
344cputime(k, v)
345 KINFO *k;
346 VAR *v;
347{
348 extern int sumrusage;
349 long secs;
350 long psecs; /* "parts" of a second. first micro, then centi */
351 char obuff[128];
352
353 if (k->ki_p->p_stat == SZOMB || k->ki_u == NULL) {
354 secs = 0;
355 psecs = 0;
356 } else {
357 secs = k->ki_p->p_utime.tv_sec +
358 k->ki_p->p_stime.tv_sec;
359 psecs = k->ki_p->p_utime.tv_usec +
360 k->ki_p->p_stime.tv_usec;
361 if (sumrusage) {
362 secs += k->ki_u->u_cru.ru_utime.tv_sec +
363 k->ki_u->u_cru.ru_stime.tv_sec;
364 psecs += k->ki_u->u_cru.ru_utime.tv_usec +
365 k->ki_u->u_cru.ru_stime.tv_usec;
366 }
367 /*
368 * round and scale to 100's
369 */
370 psecs = (psecs + 5000) / 10000;
6728dbc4
KB
371 secs += psecs / 100;
372 psecs = psecs % 100;
fd57c467
KB
373 }
374 (void) sprintf(obuff, "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
375 (void) printf("%*s", v->width, obuff);
376}
377
378double
379getpcpu(k)
380 KINFO *k;
381{
382 extern fixpt_t ccpu;
383 extern int fscale, nlistread, rawcpu;
384 struct proc *p;
385 static int failure;
386
387 if (!nlistread)
388 failure = donlist();
389 if (failure)
390 return (0.0);
391
392 p = k->ki_p;
393#define fxtofl(fixpt) ((double)(fixpt) / fscale)
394
395 /* XXX - I don't like this */
396 if (p->p_time == 0 || (p->p_flag & SLOAD) == 0)
397 return (0.0);
398 if (rawcpu)
399 return (100.0 * fxtofl(p->p_pctcpu));
400 return (100.0 * fxtofl(p->p_pctcpu) /
401 (1.0 - exp(p->p_time * log(fxtofl(ccpu)))));
402}
403
404pcpu(k, v)
405 KINFO *k;
406 VAR *v;
407{
408 (void) printf("%*.1f", v->width, getpcpu(k));
409}
410
411double
412getpmem(k)
413 KINFO *k;
414{
415 extern int ecmx, nlistread;
416 static int failure;
417 struct proc *p;
418 struct eproc *e;
419 double fracmem;
420 int szptudot;
421
422 if (!nlistread)
423 failure = donlist();
424 if (failure)
425 return (0.0);
426
427 p = k->ki_p;
428 e = k->ki_e;
429 if ((p->p_flag & SLOAD) == 0)
430 return (0.0);
1d2a7f51 431#ifndef NEWVM
fd57c467
KB
432 szptudot = UPAGES + clrnd(ctopt(p->p_dsize + p->p_ssize + e->e_xsize));
433 fracmem = ((float)p->p_rssize + szptudot)/CLSIZE/ecmx;
434 if (p->p_textp && e->e_xccount)
435 fracmem += ((float)e->e_xrssize)/CLSIZE/e->e_xccount/ecmx;
1d2a7f51
MK
436#else /* NEWVM */
437 /* XXX want pmap ptpages, segtab, etc. (per architecture) */
438 szptudot = UPAGES;
439 /* XXX don't have info about shared */
440 fracmem = ((float)e->e_vm.vm_rssize + szptudot)/CLSIZE/ecmx;
441#endif /* NEWVM */
fd57c467
KB
442 return (100.0 * fracmem);
443}
444
445pmem(k, v)
446 KINFO *k;
447 VAR *v;
448{
449 (void) printf("%*.1f", v->width, getpmem(k));
450}
451
452pagein(k, v)
453 KINFO *k;
454 VAR *v;
455{
456 (void) printf("%*d", v->width, k->ki_u ? k->ki_u->u_ru.ru_majflt : 0);
457}
458
459maxrss(k, v)
460 KINFO *k;
461 VAR *v;
462{
1d2a7f51 463#ifndef NEWVM /* not yet */
fd57c467
KB
464 if (k->ki_p->p_maxrss != (RLIM_INFINITY/NBPG))
465 (void) printf("%*d", v->width, pgtok(k->ki_p->p_maxrss));
466 else
1d2a7f51 467#endif /* NEWVM */
fd57c467
KB
468 (void) printf("%*s", v->width, "-");
469}
470
471tsize(k, v)
472 KINFO *k;
473 VAR *v;
474{
1d2a7f51 475#ifndef NEWVM
fd57c467 476 (void) printf("%*d", v->width, pgtok(k->ki_e->e_xsize));
1d2a7f51
MK
477#else /* NEWVM */
478 (void) printf("%*d", v->width, pgtok(k->ki_e->e_vm.vm_tsize));
479#endif /* NEWVM */
fd57c467
KB
480}
481
1d2a7f51 482#ifndef NEWVM
fd57c467
KB
483trss(k, v)
484 KINFO *k;
485 VAR *v;
486{
487 (void) printf("%*d", v->width, pgtok(k->ki_e->e_xrssize));
488}
1d2a7f51 489#endif /* NEWVM */
fd57c467
KB
490
491/*
492 * Generic output routines. Print fields from various prototype
493 * structures.
494 */
495pvar(k, v)
496 KINFO *k;
497 VAR *v;
498{
499 printval((char *)((char *)k->ki_p + v->off), v);
500}
501
502evar(k, v)
503 KINFO *k;
504 VAR *v;
505{
506 printval((char *)((char *)k->ki_e + v->off), v);
507}
508
509uvar(k, v)
510 KINFO *k;
511 VAR *v;
512{
513 if (k->ki_u)
514 printval((char *)((char *)k->ki_u + v->off), v);
515 else
516 (void) printf("%*s", v->width, "-");
517}
518
519rvar(k, v)
520 KINFO *k;
521 VAR *v;
522{
523 if (k->ki_u)
524 printval((char *)((char *)(&k->ki_u->u_ru) + v->off), v);
525 else
526 (void) printf("%*s", v->width, "-");
527}
528
529printval(bp, v)
530 char *bp;
531 VAR *v;
532{
533 static char ofmt[32] = "%";
534 register char *cp = ofmt+1, *fcp = v->fmt;
535
536 if (v->flag & LJUST)
537 *cp++ = '-';
538 *cp++ = '*';
539 while (*cp++ = *fcp++);
540
541 switch (v->type) {
542 case CHAR:
543 (void) printf(ofmt, v->width, *(char *)bp);
544 break;
545 case UCHAR:
546 (void) printf(ofmt, v->width, *(u_char *)bp);
547 break;
548 case SHORT:
549 (void) printf(ofmt, v->width, *(short *)bp);
550 break;
551 case USHORT:
552 (void) printf(ofmt, v->width, *(u_short *)bp);
553 break;
554 case LONG:
555 (void) printf(ofmt, v->width, *(long *)bp);
556 break;
557 case ULONG:
558 (void) printf(ofmt, v->width, *(u_long *)bp);
559 break;
560 case KPTR:
561 (void) printf(ofmt, v->width, *(u_long *)bp &~ KERNBASE);
562 break;
563 default:
564 error("unknown type %d", v->type);
565 }
566}