Home | History | Annotate | Line # | Download | only in ps
print.c revision 1.3
      1 /*-
      2  * Copyright (c) 1990 The Regents of the University of California.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *	This product includes software developed by the University of
     16  *	California, Berkeley and its contributors.
     17  * 4. Neither the name of the University nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #ifndef lint
     35 static char sccsid[] = "@(#)print.c	5.9 (Berkeley) 7/1/91";
     36 static char rcsid[] = "$Header: /tank/opengrok/rsync2/NetBSD/src/bin/ps/print.c,v 1.3 1993/03/23 00:26:36 cgd Exp $";
     37 #endif /* not lint */
     38 
     39 #include <sys/param.h>
     40 #include <sys/time.h>
     41 #include <sys/resource.h>
     42 #include <sys/proc.h>
     43 #include <sys/stat.h>
     44 #include <math.h>
     45 #include <tzfile.h>
     46 #include <stddef.h>
     47 #include <string.h>
     48 #include "ps.h"
     49 
     50 #ifdef SPPWAIT
     51 #define NEWVM
     52 #endif
     53 
     54 #ifdef NEWVM
     55 #include <vm/vm.h>
     56 #include <sys/ucred.h>
     57 #include <sys/kinfo_proc.h>
     58 #else
     59 #include <machine/pte.h>
     60 #include <sys/vmparam.h>
     61 #include <sys/vm.h>
     62 #endif
     63 
     64 printheader()
     65 {
     66 	register VAR *v;
     67 	register struct varent *vent;
     68 
     69 	for (vent = vhead; vent; vent = vent->next) {
     70 		v = vent->var;
     71 		if (v->flag & LJUST) {
     72 			if (vent->next == NULL)	/* last one */
     73 				(void) printf("%s", v->header);
     74 			else
     75 				(void) printf("%-*s", v->width, v->header);
     76 		} else
     77 			(void) printf("%*s", v->width, v->header);
     78 		if (vent->next != NULL)
     79 			(void) putchar(' ');
     80 	}
     81 	(void) putchar('\n');
     82 }
     83 
     84 command(k, v, next)
     85 	KINFO *k;
     86 	VAR *v;
     87 {
     88 	extern int termwidth, totwidth;
     89 
     90 	if (next == NULL) {
     91 		/* last field */
     92 		if (termwidth == UNLIMITED)
     93 			(void) printf("%s", k->ki_args);
     94 		else {
     95 			register int left = termwidth - (totwidth - v->width);
     96 			register char *cp = k->ki_args;
     97 
     98 			if (left < 1) /* already wrapped, just use std width */
     99 				left = v->width;
    100 			while (--left >= 0 && *cp)
    101 				(void) putchar(*cp++);
    102 		}
    103 	} else
    104 		(void) printf("%-*.*s", v->width, v->width, k->ki_args);
    105 
    106 }
    107 
    108 ucomm(k, v)
    109 	KINFO *k;
    110 	VAR *v;
    111 {
    112 	(void) printf("%-*s", v->width, k->ki_p->p_comm);
    113 }
    114 
    115 logname(k, v)
    116 	KINFO *k;
    117 	VAR *v;
    118 {
    119 #ifndef NEWVM
    120 	(void) printf("%-*s", v->width, k->ki_p->p_logname);
    121 #else /* NEWVM */
    122 	(void) printf("%-*s", v->width, k->ki_e->e_login);
    123 #endif /* NEWVM */
    124 }
    125 
    126 state(k, v)
    127 	KINFO *k;
    128 	VAR *v;
    129 {
    130 	char buf[16];
    131 	register char *cp = buf;
    132 	register struct proc *p = k->ki_p;
    133 	register flag = p->p_flag;
    134 
    135 	switch (p->p_stat) {
    136 
    137 	case SSTOP:
    138 		*cp = 'T';
    139 		break;
    140 
    141 	case SSLEEP:
    142 		if (flag & SSINTR)	/* interuptable (long) */
    143 			*cp = p->p_slptime >= MAXSLP ? 'I' : 'S';
    144 		else
    145 			*cp = (flag & SPAGE) ? 'P' : 'D';
    146 		break;
    147 
    148 	case SRUN:
    149 	case SIDL:
    150 		*cp = 'R';
    151 		break;
    152 
    153 	case SZOMB:
    154 		*cp = 'Z';
    155 		break;
    156 
    157 	default:
    158 		*cp = '?';
    159 	}
    160 	cp++;
    161 	if (flag & SLOAD) {
    162 #ifndef NEWVM
    163 		if (p->p_rssize > p->p_maxrss)
    164 			*cp++ = '>';
    165 #endif
    166 	} else
    167 		*cp++ = 'W';
    168 	if (p->p_nice < NZERO)
    169 		*cp++ = '<';
    170 	else if (p->p_nice > NZERO)
    171 		*cp++ = 'N';
    172 #ifndef NEWVM
    173 	if (flag & SUANOM)
    174 		*cp++ = 'A';
    175 	else if (flag & SSEQL)
    176 		*cp++ = 'S';
    177 #endif
    178 	if (flag & STRC)
    179 		*cp++ = 'X';
    180 	if (flag & SWEXIT && p->p_stat != SZOMB)
    181 		*cp++ = 'E';
    182 #ifdef NEWVM
    183 	if (flag & SPPWAIT)
    184 #else
    185 	if (flag & SVFORK)
    186 #endif
    187 		*cp++ = 'V';
    188 #ifdef NEWVM
    189 	if (flag & (SSYS|SLOCK|SKEEP|SPHYSIO))
    190 #else
    191 	if (flag & (SSYS|SLOCK|SULOCK|SKEEP|SPHYSIO))
    192 #endif
    193 		*cp++ = 'L';
    194 	if (k->ki_e->e_flag & EPROC_SLEADER)
    195 		*cp++ = 's';
    196 	if ((flag & SCTTY) && k->ki_e->e_pgid == k->ki_e->e_tpgid)
    197 		*cp++ = '+';
    198 	*cp = '\0';
    199 	(void) printf("%-*s", v->width, buf);
    200 }
    201 
    202 pri(k, v)
    203 	KINFO *k;
    204 	VAR *v;
    205 {
    206 	(void) printf("%*d", v->width, k->ki_p->p_pri - PZERO);
    207 }
    208 
    209 uname(k, v)
    210 	KINFO *k;
    211 	VAR *v;
    212 {
    213 #ifndef NEWVM
    214 	(void) printf("%-*s", v->width, user_from_uid(k->ki_p->p_uid, 0));
    215 #else /* NEWVM */
    216 	(void) printf("%-*s", v->width,
    217 		user_from_uid(k->ki_e->e_ucred.cr_uid, 0));
    218 #endif /* NEWVM */
    219 }
    220 
    221 runame(k, v)
    222 	KINFO *k;
    223 	VAR *v;
    224 {
    225 #ifndef NEWVM
    226 	(void) printf("%-*s", v->width, user_from_uid(k->ki_p->p_ruid, 0));
    227 #else /* NEWVM */
    228 	(void) printf("%-*s", v->width,
    229 		user_from_uid(k->ki_e->e_pcred.p_ruid, 0));
    230 #endif /* NEWVM */
    231 }
    232 
    233 tdev(k, v)
    234 	KINFO *k;
    235 	VAR *v;
    236 {
    237 	dev_t dev = k->ki_e->e_tdev;
    238 
    239 	if (dev == NODEV)
    240 		(void) printf("%*s", v->width, "??");
    241 	else {
    242 		char buff[16];
    243 
    244 		(void) sprintf(buff, "%d/%d", major(dev), minor(dev));
    245 		(void) printf("%*s", v->width, buff);
    246 	}
    247 }
    248 
    249 tname(k, v)
    250 	KINFO *k;
    251 	VAR *v;
    252 {
    253 	dev_t dev;
    254 	char *ttname, *devname();
    255 
    256 	dev = k->ki_e->e_tdev;
    257 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
    258 		(void) printf("%-*s", v->width, "??");
    259 	else {
    260 		if (strncmp(ttname, "tty", 3) == 0)
    261 			ttname += 3;
    262 		(void) printf("%*.*s%c", v->width-1, v->width-1, ttname,
    263 			k->ki_e->e_flag & EPROC_CTTY ? ' ' : '-');
    264 	}
    265 }
    266 
    267 longtname(k, v)
    268 	KINFO *k;
    269 	VAR *v;
    270 {
    271 	dev_t dev;
    272 	char *ttname, *devname();
    273 
    274 	dev = k->ki_e->e_tdev;
    275 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
    276 		(void) printf("%-*s", v->width, "??");
    277 	else
    278 		(void) printf("%-*s", v->width, ttname);
    279 }
    280 
    281 started(k, v)
    282 	KINFO *k;
    283 	VAR *v;
    284 {
    285 	static time_t now;
    286 	struct tm *tp;
    287 	char buf[100];
    288 
    289 	if (!k->ki_u) {
    290 		(void) printf("%-*s", v->width, "-");
    291 		return;
    292 	}
    293 
    294 	tp = localtime(&k->ki_u->u_start.tv_sec);
    295 	if (!now)
    296 		(void)time(&now);
    297 	if (now - k->ki_u->u_start.tv_sec < 24 * SECSPERHOUR) {
    298 		static char fmt[] = "%l:@M%p";
    299 		fmt[3] = '%';			/* I *hate* SCCS... */
    300 		(void) strftime(buf, sizeof(buf) - 1, fmt, tp);
    301 	} else if (now - k->ki_u->u_start.tv_sec < 7 * SECSPERDAY) {
    302 		static char fmt[] = "%a@I%p";
    303 		fmt[2] = '%';			/* I *hate* SCCS... */
    304 		(void) strftime(buf, sizeof(buf) - 1, fmt, tp);
    305 	} else
    306 		(void) strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
    307 	(void) printf("%-*s", v->width, buf);
    308 }
    309 
    310 lstarted(k, v)
    311 	KINFO *k;
    312 	VAR *v;
    313 {
    314 	char buf[100];
    315 
    316 	if (!k->ki_u) {
    317 		(void) printf("%-*s", v->width, "-");
    318 		return;
    319 	}
    320 	(void) strftime(buf, sizeof(buf) -1, "%C",
    321 	    localtime(&k->ki_u->u_start.tv_sec));
    322 	(void) printf("%-*s", v->width, buf);
    323 }
    324 
    325 wchan(k, v)
    326 	KINFO *k;
    327 	VAR *v;
    328 {
    329 	if (k->ki_p->p_wchan) {
    330 		if (k->ki_p->p_wmesg)
    331 			(void) printf("%-*.*s", v->width, v->width, k->ki_e->e_wmesg);
    332 		else
    333 			(void) printf("%-*x", v->width,
    334 			    (int)k->ki_p->p_wchan &~ KERNBASE);
    335 	} else
    336 		(void) printf("%-*s", v->width, "-");
    337 }
    338 
    339 #define pgtok(a)        (((a)*NBPG)/1024)
    340 
    341 vsize(k, v)
    342 	KINFO *k;
    343 	VAR *v;
    344 {
    345 	(void) printf("%*d", v->width,
    346 #ifndef NEWVM
    347 	    pgtok(k->ki_p->p_dsize + k->ki_p->p_ssize + k->ki_e->e_xsize));
    348 #else /* NEWVM */
    349 	    pgtok(k->ki_e->e_vm.vm_dsize + k->ki_e->e_vm.vm_ssize +
    350 		k->ki_e->e_vm.vm_tsize));
    351 #endif /* NEWVM */
    352 }
    353 
    354 rssize(k, v)
    355 	KINFO *k;
    356 	VAR *v;
    357 {
    358 #ifndef NEWVM
    359 	(void) printf("%*d", v->width,
    360 	    pgtok(k->ki_p->p_rssize + (k->ki_e->e_xccount ?
    361 	    (k->ki_e->e_xrssize / k->ki_e->e_xccount) : 0)));
    362 #else /* NEWVM */
    363 	/* XXX don't have info about shared */
    364 	(void) printf("%*d", v->width, pgtok(k->ki_e->e_vm.vm_rssize));
    365 #endif /* NEWVM */
    366 }
    367 
    368 p_rssize(k, v)		/* doesn't account for text */
    369 	KINFO *k;
    370 	VAR *v;
    371 {
    372 #ifndef NEWVM
    373 	(void) printf("%*d", v->width, pgtok(k->ki_p->p_rssize));
    374 #else /* NEWVM */
    375 	(void) printf("%*d", v->width, pgtok(k->ki_e->e_vm.vm_rssize));
    376 #endif /* NEWVM */
    377 }
    378 
    379 cputime(k, v)
    380 	KINFO *k;
    381 	VAR *v;
    382 {
    383 	extern int sumrusage;
    384 	long secs;
    385 	long psecs;	/* "parts" of a second. first micro, then centi */
    386 	char obuff[128];
    387 
    388 	if (k->ki_p->p_stat == SZOMB || k->ki_u == NULL) {
    389 		secs = 0;
    390 		psecs = 0;
    391 	} else {
    392 		secs = k->ki_p->p_utime.tv_sec +
    393 			k->ki_p->p_stime.tv_sec;
    394 		psecs = k->ki_p->p_utime.tv_usec +
    395 			k->ki_p->p_stime.tv_usec;
    396 		if (sumrusage) {
    397 			secs += k->ki_u->u_cru.ru_utime.tv_sec +
    398 				k->ki_u->u_cru.ru_stime.tv_sec;
    399 			psecs += k->ki_u->u_cru.ru_utime.tv_usec +
    400 				k->ki_u->u_cru.ru_stime.tv_usec;
    401 		}
    402 		/*
    403 		 * round and scale to 100's
    404 		 */
    405 		psecs = (psecs + 5000) / 10000;
    406 		secs += psecs / 100;
    407 		psecs = psecs % 100;
    408 	}
    409 	(void) sprintf(obuff, "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
    410 	(void) printf("%*s", v->width, obuff);
    411 }
    412 
    413 double
    414 getpcpu(k)
    415 	KINFO *k;
    416 {
    417 	extern fixpt_t ccpu;
    418 	extern int fscale, nlistread, rawcpu;
    419 	struct proc *p;
    420 	static int failure;
    421 
    422 	if (!nlistread)
    423 		failure = donlist();
    424 	if (failure)
    425 		return (0.0);
    426 
    427 	p = k->ki_p;
    428 #define	fxtofl(fixpt)	((double)(fixpt) / fscale)
    429 
    430 	/* XXX - I don't like this */
    431 	if (p->p_time == 0 || (p->p_flag & SLOAD) == 0)
    432 		return (0.0);
    433 	if (rawcpu)
    434 		return (100.0 * fxtofl(p->p_pctcpu));
    435 	return (100.0 * fxtofl(p->p_pctcpu) /
    436 		(1.0 - exp(p->p_time * log(fxtofl(ccpu)))));
    437 }
    438 
    439 pcpu(k, v)
    440 	KINFO *k;
    441 	VAR *v;
    442 {
    443 	(void) printf("%*.1f", v->width, getpcpu(k));
    444 }
    445 
    446 double
    447 getpmem(k)
    448 	KINFO *k;
    449 {
    450 	extern int mempages, nlistread;
    451 	static int failure;
    452 	struct proc *p;
    453 	struct eproc *e;
    454 	double fracmem;
    455 	int szptudot;
    456 
    457 	if (!nlistread)
    458 		failure = donlist();
    459 	if (failure)
    460 		return (0.0);
    461 
    462 	p = k->ki_p;
    463 	e = k->ki_e;
    464 	if ((p->p_flag & SLOAD) == 0)
    465 		return (0.0);
    466 #ifndef NEWVM
    467 	szptudot = UPAGES + clrnd(ctopt(p->p_dsize + p->p_ssize + e->e_xsize));
    468 	fracmem = ((float)p->p_rssize + szptudot)/CLSIZE/mempages;
    469 	if (p->p_textp && e->e_xccount)
    470 		fracmem += ((float)e->e_xrssize)/CLSIZE/e->e_xccount/mempages;
    471 #else /* NEWVM */
    472 	/* XXX want pmap ptpages, segtab, etc. (per architecture) */
    473 	szptudot = UPAGES;
    474 	/* XXX don't have info about shared */
    475 	fracmem = ((float)e->e_vm.vm_rssize + szptudot)/CLSIZE/mempages;
    476 #endif /* NEWVM */
    477 	return (100.0 * fracmem);
    478 }
    479 
    480 pmem(k, v)
    481 	KINFO *k;
    482 	VAR *v;
    483 {
    484 	(void) printf("%*.1f", v->width, getpmem(k));
    485 }
    486 
    487 pagein(k, v)
    488 	KINFO *k;
    489 	VAR *v;
    490 {
    491 	(void) printf("%*d", v->width, k->ki_u ? k->ki_u->u_ru.ru_majflt : 0);
    492 }
    493 
    494 maxrss(k, v)
    495 	KINFO *k;
    496 	VAR *v;
    497 {
    498 #ifndef NEWVM	/* not yet */
    499 	if (k->ki_p->p_maxrss != (RLIM_INFINITY/NBPG))
    500 		(void) printf("%*d", v->width, pgtok(k->ki_p->p_maxrss));
    501 	else
    502 #endif /* NEWVM */
    503 		(void) printf("%*s", v->width, "-");
    504 }
    505 
    506 tsize(k, v)
    507 	KINFO *k;
    508 	VAR *v;
    509 {
    510 #ifndef NEWVM
    511 	(void) printf("%*d", v->width, pgtok(k->ki_e->e_xsize));
    512 #else /* NEWVM */
    513 	(void) printf("%*d", v->width, pgtok(k->ki_e->e_vm.vm_tsize));
    514 #endif /* NEWVM */
    515 }
    516 
    517 #ifndef NEWVM
    518 trss(k, v)
    519 	KINFO *k;
    520 	VAR *v;
    521 {
    522 	(void) printf("%*d", v->width, pgtok(k->ki_e->e_xrssize));
    523 }
    524 #endif /* NEWVM */
    525 
    526 /*
    527  * Generic output routines.  Print fields from various prototype
    528  * structures.
    529  */
    530 pvar(k, v)
    531 	KINFO *k;
    532 	VAR *v;
    533 {
    534 	printval((char *)((char *)k->ki_p + v->off), v);
    535 }
    536 
    537 evar(k, v)
    538 	KINFO *k;
    539 	VAR *v;
    540 {
    541 	printval((char *)((char *)k->ki_e + v->off), v);
    542 }
    543 
    544 uvar(k, v)
    545 	KINFO *k;
    546 	VAR *v;
    547 {
    548 	if (k->ki_u)
    549 		printval((char *)((char *)k->ki_u + v->off), v);
    550 	else
    551 		(void) printf("%*s", v->width, "-");
    552 }
    553 
    554 rvar(k, v)
    555 	KINFO *k;
    556 	VAR *v;
    557 {
    558 	if (k->ki_u)
    559 		printval((char *)((char *)(&k->ki_u->u_ru) + v->off), v);
    560 	else
    561 		(void) printf("%*s", v->width, "-");
    562 }
    563 
    564 printval(bp, v)
    565 	char *bp;
    566 	VAR *v;
    567 {
    568 	static char ofmt[32] = "%";
    569 	register char *cp = ofmt+1, *fcp = v->fmt;
    570 
    571 	if (v->flag & LJUST)
    572 		*cp++ = '-';
    573 	*cp++ = '*';
    574 	while (*cp++ = *fcp++);
    575 
    576 	switch (v->type) {
    577 	case CHAR:
    578 		(void) printf(ofmt, v->width, *(char *)bp);
    579 		break;
    580 	case UCHAR:
    581 		(void) printf(ofmt, v->width, *(u_char *)bp);
    582 		break;
    583 	case SHORT:
    584 		(void) printf(ofmt, v->width, *(short *)bp);
    585 		break;
    586 	case USHORT:
    587 		(void) printf(ofmt, v->width, *(u_short *)bp);
    588 		break;
    589 	case LONG:
    590 		(void) printf(ofmt, v->width, *(long *)bp);
    591 		break;
    592 	case ULONG:
    593 		(void) printf(ofmt, v->width, *(u_long *)bp);
    594 		break;
    595 	case KPTR:
    596 		(void) printf(ofmt, v->width, *(u_long *)bp &~ KERNBASE);
    597 		break;
    598 	default:
    599 		err("unknown type %d", v->type);
    600 	}
    601 }
    602