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