xref: /original-bsd/bin/ps/print.c (revision 1d767c41)
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
9 static char sccsid[] = "@(#)print.c	5.2 (Berkeley) 02/08/91";
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 
27 printheader()
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 
45 command(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 
69 ucomm(k, v)
70 	KINFO *k;
71 	VAR *v;
72 {
73 	(void) printf("%-*s", v->width, k->ki_p->p_comm);
74 }
75 
76 logname(k, v)
77 	KINFO *k;
78 	VAR *v;
79 {
80 	(void) printf("%-*s", v->width, k->ki_p->p_logname);
81 }
82 
83 state(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 
147 pri(k, v)
148 	KINFO *k;
149 	VAR *v;
150 {
151 	(void) printf("%*d", v->width, k->ki_p->p_pri - PZERO);
152 }
153 
154 uname(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 
161 runame(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 
168 tdev(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 
184 tname(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 
202 longtname(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 
216 started(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);
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
241 		(void) strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
242 	(void) printf("%-*s", v->width, buf);
243 }
244 
245 lstarted(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 
260 wchan(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 
276 vsize(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 
284 rssize(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 
293 p_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 
300 cputime(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;
327 		if (psecs >= 100) {
328 			psecs -= 100;
329 			secs++;
330 		}
331 	}
332 	(void) sprintf(obuff, "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
333 	(void) printf("%*s", v->width, obuff);
334 }
335 
336 double
337 getpcpu(k)
338 	KINFO *k;
339 {
340 	extern fixpt_t ccpu;
341 	extern int fscale, nlistread, rawcpu;
342 	struct proc *p;
343 	static int failure;
344 
345 	if (!nlistread)
346 		failure = donlist();
347 	if (failure)
348 		return (0.0);
349 
350 	p = k->ki_p;
351 #define	fxtofl(fixpt)	((double)(fixpt) / fscale)
352 
353 	/* XXX - I don't like this */
354 	if (p->p_time == 0 || (p->p_flag & SLOAD) == 0)
355 		return (0.0);
356 	if (rawcpu)
357 		return (100.0 * fxtofl(p->p_pctcpu));
358 	return (100.0 * fxtofl(p->p_pctcpu) /
359 		(1.0 - exp(p->p_time * log(fxtofl(ccpu)))));
360 }
361 
362 pcpu(k, v)
363 	KINFO *k;
364 	VAR *v;
365 {
366 	(void) printf("%*.1f", v->width, getpcpu(k));
367 }
368 
369 double
370 getpmem(k)
371 	KINFO *k;
372 {
373 	extern int ecmx, nlistread;
374 	static int failure;
375 	struct proc *p;
376 	struct eproc *e;
377 	double fracmem;
378 	int szptudot;
379 
380 	if (!nlistread)
381 		failure = donlist();
382 	if (failure)
383 		return (0.0);
384 
385 	p = k->ki_p;
386 	e = k->ki_e;
387 	if ((p->p_flag & SLOAD) == 0)
388 		return (0.0);
389 	szptudot = UPAGES + clrnd(ctopt(p->p_dsize + p->p_ssize + e->e_xsize));
390 	fracmem = ((float)p->p_rssize + szptudot)/CLSIZE/ecmx;
391 	if (p->p_textp && e->e_xccount)
392 		fracmem += ((float)e->e_xrssize)/CLSIZE/e->e_xccount/ecmx;
393 	return (100.0 * fracmem);
394 }
395 
396 pmem(k, v)
397 	KINFO *k;
398 	VAR *v;
399 {
400 	(void) printf("%*.1f", v->width, getpmem(k));
401 }
402 
403 pagein(k, v)
404 	KINFO *k;
405 	VAR *v;
406 {
407 	(void) printf("%*d", v->width, k->ki_u ? k->ki_u->u_ru.ru_majflt : 0);
408 }
409 
410 maxrss(k, v)
411 	KINFO *k;
412 	VAR *v;
413 {
414 	if (k->ki_p->p_maxrss != (RLIM_INFINITY/NBPG))
415 		(void) printf("%*d", v->width, pgtok(k->ki_p->p_maxrss));
416 	else
417 		(void) printf("%*s", v->width, "-");
418 }
419 
420 tsize(k, v)
421 	KINFO *k;
422 	VAR *v;
423 {
424 	(void) printf("%*d", v->width, pgtok(k->ki_e->e_xsize));
425 }
426 
427 trss(k, v)
428 	KINFO *k;
429 	VAR *v;
430 {
431 	(void) printf("%*d", v->width, pgtok(k->ki_e->e_xrssize));
432 }
433 
434 /*
435  * Generic output routines.  Print fields from various prototype
436  * structures.
437  */
438 pvar(k, v)
439 	KINFO *k;
440 	VAR *v;
441 {
442 	printval((char *)((char *)k->ki_p + v->off), v);
443 }
444 
445 evar(k, v)
446 	KINFO *k;
447 	VAR *v;
448 {
449 	printval((char *)((char *)k->ki_e + v->off), v);
450 }
451 
452 uvar(k, v)
453 	KINFO *k;
454 	VAR *v;
455 {
456 	if (k->ki_u)
457 		printval((char *)((char *)k->ki_u + v->off), v);
458 	else
459 		(void) printf("%*s", v->width, "-");
460 }
461 
462 rvar(k, v)
463 	KINFO *k;
464 	VAR *v;
465 {
466 	if (k->ki_u)
467 		printval((char *)((char *)(&k->ki_u->u_ru) + v->off), v);
468 	else
469 		(void) printf("%*s", v->width, "-");
470 }
471 
472 printval(bp, v)
473 	char *bp;
474 	VAR *v;
475 {
476 	static char ofmt[32] = "%";
477 	register char *cp = ofmt+1, *fcp = v->fmt;
478 
479 	if (v->flag & LJUST)
480 		*cp++ = '-';
481 	*cp++ = '*';
482 	while (*cp++ = *fcp++);
483 
484 	switch (v->type) {
485 	case CHAR:
486 		(void) printf(ofmt, v->width, *(char *)bp);
487 		break;
488 	case UCHAR:
489 		(void) printf(ofmt, v->width, *(u_char *)bp);
490 		break;
491 	case SHORT:
492 		(void) printf(ofmt, v->width, *(short *)bp);
493 		break;
494 	case USHORT:
495 		(void) printf(ofmt, v->width, *(u_short *)bp);
496 		break;
497 	case LONG:
498 		(void) printf(ofmt, v->width, *(long *)bp);
499 		break;
500 	case ULONG:
501 		(void) printf(ofmt, v->width, *(u_long *)bp);
502 		break;
503 	case KPTR:
504 		(void) printf(ofmt, v->width, *(u_long *)bp &~ KERNBASE);
505 		break;
506 	default:
507 		error("unknown type %d", v->type);
508 	}
509 }
510