Commit | Line | Data |
---|---|---|
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 | 9 | static 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 |
37 | printheader() |
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 | ||
55 | command(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 | ||
79 | ucomm(k, v) | |
80 | KINFO *k; | |
81 | VAR *v; | |
82 | { | |
83 | (void) printf("%-*s", v->width, k->ki_p->p_comm); | |
84 | } | |
85 | ||
86 | logname(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 | ||
97 | state(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 | ||
167 | pri(k, v) | |
168 | KINFO *k; | |
169 | VAR *v; | |
170 | { | |
171 | (void) printf("%*d", v->width, k->ki_p->p_pri - PZERO); | |
172 | } | |
173 | ||
174 | uname(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 | ||
186 | runame(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 | ||
198 | tdev(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 | ||
214 | tname(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 | ||
232 | longtname(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 | ||
246 | started(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 | ||
275 | lstarted(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 | ||
290 | wchan(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 | ||
306 | vsize(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 | ||
319 | rssize(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 | ||
333 | p_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 | ||
344 | cputime(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 | ||
378 | double | |
379 | getpcpu(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 | ||
404 | pcpu(k, v) | |
405 | KINFO *k; | |
406 | VAR *v; | |
407 | { | |
408 | (void) printf("%*.1f", v->width, getpcpu(k)); | |
409 | } | |
410 | ||
411 | double | |
412 | getpmem(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 | ||
445 | pmem(k, v) | |
446 | KINFO *k; | |
447 | VAR *v; | |
448 | { | |
449 | (void) printf("%*.1f", v->width, getpmem(k)); | |
450 | } | |
451 | ||
452 | pagein(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 | ||
459 | maxrss(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 | ||
471 | tsize(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 |
483 | trss(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 | */ | |
495 | pvar(k, v) | |
496 | KINFO *k; | |
497 | VAR *v; | |
498 | { | |
499 | printval((char *)((char *)k->ki_p + v->off), v); | |
500 | } | |
501 | ||
502 | evar(k, v) | |
503 | KINFO *k; | |
504 | VAR *v; | |
505 | { | |
506 | printval((char *)((char *)k->ki_e + v->off), v); | |
507 | } | |
508 | ||
509 | uvar(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 | ||
519 | rvar(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 | ||
529 | printval(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 | } |