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