xref: /original-bsd/bin/ps/print.c (revision 56c13d2e)
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.3 (Berkeley) 03/20/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 		secs += psecs / 100;
328 		psecs = psecs % 100;
329 	}
330 	(void) sprintf(obuff, "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
331 	(void) printf("%*s", v->width, obuff);
332 }
333 
334 double
335 getpcpu(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 
360 pcpu(k, v)
361 	KINFO *k;
362 	VAR *v;
363 {
364 	(void) printf("%*.1f", v->width, getpcpu(k));
365 }
366 
367 double
368 getpmem(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 
394 pmem(k, v)
395 	KINFO *k;
396 	VAR *v;
397 {
398 	(void) printf("%*.1f", v->width, getpmem(k));
399 }
400 
401 pagein(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 
408 maxrss(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 
418 tsize(k, v)
419 	KINFO *k;
420 	VAR *v;
421 {
422 	(void) printf("%*d", v->width, pgtok(k->ki_e->e_xsize));
423 }
424 
425 trss(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  */
436 pvar(k, v)
437 	KINFO *k;
438 	VAR *v;
439 {
440 	printval((char *)((char *)k->ki_p + v->off), v);
441 }
442 
443 evar(k, v)
444 	KINFO *k;
445 	VAR *v;
446 {
447 	printval((char *)((char *)k->ki_e + v->off), v);
448 }
449 
450 uvar(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 
460 rvar(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 
470 printval(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 }
508