Home | History | Annotate | Line # | Download | only in ps
print.c revision 1.36
      1 /*	$NetBSD: print.c,v 1.36 1998/02/06 04:47:35 mrg Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1990, 1993, 1994
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by the University of
     18  *	California, Berkeley and its contributors.
     19  * 4. Neither the name of the University nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #include <sys/cdefs.h>
     37 #ifndef lint
     38 #if 0
     39 static char sccsid[] = "@(#)print.c	8.6 (Berkeley) 4/16/94";
     40 #else
     41 __RCSID("$NetBSD: print.c,v 1.36 1998/02/06 04:47:35 mrg Exp $");
     42 #endif
     43 #endif /* not lint */
     44 
     45 #include <sys/param.h>
     46 #include <sys/time.h>
     47 #include <sys/resource.h>
     48 #include <sys/proc.h>
     49 #include <sys/stat.h>
     50 #include <sys/ucred.h>
     51 #include <sys/sysctl.h>
     52 
     53 #include <vm/vm.h>
     54 
     55 #include <err.h>
     56 #include <kvm.h>
     57 #include <math.h>
     58 #include <nlist.h>
     59 #include <pwd.h>
     60 #include <stddef.h>
     61 #include <stdio.h>
     62 #include <stdlib.h>
     63 #include <string.h>
     64 #include <tzfile.h>
     65 #include <unistd.h>
     66 
     67 #include "ps.h"
     68 
     69 extern kvm_t *kd;
     70 extern int needenv, needcomm, commandonly;
     71 
     72 static char *cmdpart __P((char *));
     73 static void  printval __P((char *, VAR *));
     74 
     75 #define	min(a,b)	((a) <= (b) ? (a) : (b))
     76 #define	max(a,b)	((a) >= (b) ? (a) : (b))
     77 
     78 static char *
     79 cmdpart(arg0)
     80 	char *arg0;
     81 {
     82 	char *cp;
     83 
     84 	return ((cp = strrchr(arg0, '/')) != NULL ? cp + 1 : arg0);
     85 }
     86 
     87 void
     88 printheader()
     89 {
     90 	VAR *v;
     91 	struct varent *vent;
     92 
     93 	for (vent = vhead; vent; vent = vent->next) {
     94 		v = vent->var;
     95 		if (v->flag & LJUST) {
     96 			if (vent->next == NULL)	/* last one */
     97 				(void)printf("%s", v->header);
     98 			else
     99 				(void)printf("%-*s", v->width, v->header);
    100 		} else
    101 			(void)printf("%*s", v->width, v->header);
    102 		if (vent->next != NULL)
    103 			(void)putchar(' ');
    104 	}
    105 	(void)putchar('\n');
    106 }
    107 
    108 void
    109 command(ki, ve)
    110 	KINFO *ki;
    111 	VARENT *ve;
    112 {
    113 	VAR *v;
    114 	int left;
    115 	char **argv, **p;
    116 
    117 	v = ve->var;
    118 	if (ve->next != NULL || termwidth != UNLIMITED) {
    119 		if (ve->next == NULL) {
    120 			left = termwidth - (totwidth - v->width);
    121 			if (left < 1) /* already wrapped, just use std width */
    122 				left = v->width;
    123 		} else
    124 			left = v->width;
    125 	} else
    126 		left = -1;
    127 	if (needenv) {
    128 		argv = kvm_getenvv(kd, ki->ki_p, termwidth);
    129 		if ((p = argv) != NULL) {
    130 			while (*p) {
    131 				fmt_puts(*p, &left);
    132 				p++;
    133 				fmt_putc(' ', &left);
    134 			}
    135 		}
    136 	}
    137 	if (needcomm) {
    138 		if (!commandonly) {
    139 			argv = kvm_getargv(kd, ki->ki_p, termwidth);
    140 			if ((p = argv) != NULL) {
    141 				while (*p) {
    142 					fmt_puts(*p, &left);
    143 					p++;
    144 					fmt_putc(' ', &left);
    145 				}
    146 			}
    147 			if (argv == 0 || argv[0] == 0 ||
    148 			    strcmp(cmdpart(argv[0]), KI_PROC(ki)->p_comm)) {
    149 				fmt_putc('(', &left);
    150 				fmt_puts(KI_PROC(ki)->p_comm, &left);
    151 				fmt_putc(')', &left);
    152 			}
    153 		} else {
    154 			fmt_puts(KI_PROC(ki)->p_comm, &left);
    155 		}
    156 	}
    157 	if (ve->next && left > 0)
    158 		printf("%*s", left, "");
    159 }
    160 
    161 void
    162 ucomm(k, ve)
    163 	KINFO *k;
    164 	VARENT *ve;
    165 {
    166 	VAR *v;
    167 
    168 	v = ve->var;
    169 	(void)printf("%-*s", v->width, KI_PROC(k)->p_comm);
    170 }
    171 
    172 void
    173 logname(k, ve)
    174 	KINFO *k;
    175 	VARENT *ve;
    176 {
    177 	VAR *v;
    178 	int n;
    179 
    180 	v = ve->var;
    181 	n = min(v->width, MAXLOGNAME);
    182 	(void)printf("%-*.*s", n, n, KI_EPROC(k)->e_login);
    183 	if (v->width > n)
    184 		(void)printf("%*s", v->width - n, "");
    185 }
    186 
    187 void
    188 state(k, ve)
    189 	KINFO *k;
    190 	VARENT *ve;
    191 {
    192 	struct proc *p;
    193 	int flag;
    194 	char *cp;
    195 	VAR *v;
    196 	char buf[16];
    197 
    198 	v = ve->var;
    199 	p = KI_PROC(k);
    200 	flag = p->p_flag;
    201 	cp = buf;
    202 
    203 	switch (p->p_stat) {
    204 
    205 	case SSTOP:
    206 		*cp = 'T';
    207 		break;
    208 
    209 	case SSLEEP:
    210 		if (flag & P_SINTR)	/* interuptable (long) */
    211 			*cp = p->p_slptime >= MAXSLP ? 'I' : 'S';
    212 		else
    213 			*cp = 'D';
    214 		break;
    215 
    216 	case SRUN:
    217 	case SIDL:
    218 		*cp = 'R';
    219 		break;
    220 
    221 	case SZOMB:
    222 		*cp = 'Z';
    223 		break;
    224 
    225 	default:
    226 		*cp = '?';
    227 	}
    228 	cp++;
    229 	if (flag & P_INMEM) {
    230 	} else
    231 		*cp++ = 'W';
    232 	if (p->p_nice < NZERO)
    233 		*cp++ = '<';
    234 	else if (p->p_nice > NZERO)
    235 		*cp++ = 'N';
    236 	if (flag & P_TRACED)
    237 		*cp++ = 'X';
    238 	if (flag & P_WEXIT && p->p_stat != SZOMB)
    239 		*cp++ = 'E';
    240 	if (flag & P_PPWAIT)
    241 		*cp++ = 'V';
    242 	if ((flag & P_SYSTEM) || p->p_holdcnt)
    243 		*cp++ = 'L';
    244 	if (KI_EPROC(k)->e_flag & EPROC_SLEADER)
    245 		*cp++ = 's';
    246 	if ((flag & P_CONTROLT) && KI_EPROC(k)->e_pgid == KI_EPROC(k)->e_tpgid)
    247 		*cp++ = '+';
    248 	*cp = '\0';
    249 	(void)printf("%-*s", v->width, buf);
    250 }
    251 
    252 void
    253 pnice(k, ve)
    254 	KINFO *k;
    255 	VARENT *ve;
    256 {
    257 	VAR *v;
    258 
    259 	v = ve->var;
    260 	(void)printf("%*d", v->width, KI_PROC(k)->p_nice - NZERO);
    261 }
    262 
    263 void
    264 pri(k, ve)
    265 	KINFO *k;
    266 	VARENT *ve;
    267 {
    268 	VAR *v;
    269 
    270 	v = ve->var;
    271 	(void)printf("%*d", v->width, KI_PROC(k)->p_priority - PZERO);
    272 }
    273 
    274 void
    275 uname(k, ve)
    276 	KINFO *k;
    277 	VARENT *ve;
    278 {
    279 	VAR *v;
    280 
    281 	v = ve->var;
    282 	(void)printf("%-*s",
    283 	    (int)v->width, user_from_uid(KI_EPROC(k)->e_ucred.cr_uid, 0));
    284 }
    285 
    286 void
    287 runame(k, ve)
    288 	KINFO *k;
    289 	VARENT *ve;
    290 {
    291 	VAR *v;
    292 
    293 	v = ve->var;
    294 	(void)printf("%-*s",
    295 	    (int)v->width, user_from_uid(KI_EPROC(k)->e_pcred.p_ruid, 0));
    296 }
    297 
    298 void
    299 tdev(k, ve)
    300 	KINFO *k;
    301 	VARENT *ve;
    302 {
    303 	VAR *v;
    304 	dev_t dev;
    305 	char buff[16];
    306 
    307 	v = ve->var;
    308 	dev = KI_EPROC(k)->e_tdev;
    309 	if (dev == NODEV)
    310 		(void)printf("%*s", v->width, "??");
    311 	else {
    312 		(void)snprintf(buff, sizeof(buff),
    313 		    "%d/%d", major(dev), minor(dev));
    314 		(void)printf("%*s", v->width, buff);
    315 	}
    316 }
    317 
    318 void
    319 tname(k, ve)
    320 	KINFO *k;
    321 	VARENT *ve;
    322 {
    323 	VAR *v;
    324 	dev_t dev;
    325 	char *ttname;
    326 
    327 	v = ve->var;
    328 	dev = KI_EPROC(k)->e_tdev;
    329 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
    330 		(void)printf("%-*s", v->width, "??");
    331 	else {
    332 		if (strncmp(ttname, "tty", 3) == 0)
    333 			ttname += 3;
    334 		(void)printf("%*.*s%c", v->width-1, v->width-1, ttname,
    335 			KI_EPROC(k)->e_flag & EPROC_CTTY ? ' ' : '-');
    336 	}
    337 }
    338 
    339 void
    340 longtname(k, ve)
    341 	KINFO *k;
    342 	VARENT *ve;
    343 {
    344 	VAR *v;
    345 	dev_t dev;
    346 	char *ttname;
    347 
    348 	v = ve->var;
    349 	dev = KI_EPROC(k)->e_tdev;
    350 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
    351 		(void)printf("%-*s", v->width, "??");
    352 	else
    353 		(void)printf("%-*s", v->width, ttname);
    354 }
    355 
    356 void
    357 started(k, ve)
    358 	KINFO *k;
    359 	VARENT *ve;
    360 {
    361 	VAR *v;
    362 	static time_t now;
    363 	time_t startt;
    364 	struct tm *tp;
    365 	char buf[100];
    366 
    367 	v = ve->var;
    368 	if (!k->ki_u.u_valid) {
    369 		(void)printf("%-*s", v->width, "-");
    370 		return;
    371 	}
    372 
    373 	startt = k->ki_u.u_start.tv_sec;
    374 	tp = localtime(&startt);
    375 	if (!now)
    376 		(void)time(&now);
    377 	if (now - k->ki_u.u_start.tv_sec < 24 * SECSPERHOUR) {
    378 		/* I *hate* SCCS... */
    379 		static char fmt[] = __CONCAT("%l:%", "M%p");
    380 		(void)strftime(buf, sizeof(buf) - 1, fmt, tp);
    381 	} else if (now - k->ki_u.u_start.tv_sec < 7 * SECSPERDAY) {
    382 		/* I *hate* SCCS... */
    383 		static char fmt[] = __CONCAT("%a%", "I%p");
    384 		(void)strftime(buf, sizeof(buf) - 1, fmt, tp);
    385 	} else
    386 		(void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
    387 	(void)printf("%-*s", v->width, buf);
    388 }
    389 
    390 void
    391 lstarted(k, ve)
    392 	KINFO *k;
    393 	VARENT *ve;
    394 {
    395 	VAR *v;
    396 	time_t startt;
    397 	char buf[100];
    398 
    399 	v = ve->var;
    400 	if (!k->ki_u.u_valid) {
    401 		(void)printf("%-*s", v->width, "-");
    402 		return;
    403 	}
    404 	startt = k->ki_u.u_start.tv_sec;
    405 	(void)strftime(buf, sizeof(buf) -1, "%c",
    406 	    localtime(&startt));
    407 	(void)printf("%-*s", v->width, buf);
    408 }
    409 
    410 void
    411 wchan(k, ve)
    412 	KINFO *k;
    413 	VARENT *ve;
    414 {
    415 	VAR *v;
    416 	int n;
    417 
    418 	v = ve->var;
    419 	if (KI_PROC(k)->p_wchan) {
    420 		if (KI_PROC(k)->p_wmesg) {
    421 			n = min(v->width, WMESGLEN);
    422 			(void)printf("%-*.*s", n, n, KI_EPROC(k)->e_wmesg);
    423 			if (v->width > n)
    424 				(void)printf("%*s", v->width - n, "");
    425 		} else
    426 			(void)printf("%-*lx", v->width,
    427 			    (long)KI_PROC(k)->p_wchan);
    428 	} else
    429 		(void)printf("%-*s", v->width, "-");
    430 }
    431 
    432 #define pgtok(a)        (((a)*getpagesize())/1024)
    433 
    434 void
    435 vsize(k, ve)
    436 	KINFO *k;
    437 	VARENT *ve;
    438 {
    439 	VAR *v;
    440 
    441 	v = ve->var;
    442 	(void)printf("%*d", v->width,
    443 	    pgtok(KI_EPROC(k)->e_vm.vm_dsize + KI_EPROC(k)->e_vm.vm_ssize +
    444 		KI_EPROC(k)->e_vm.vm_tsize));
    445 }
    446 
    447 void
    448 rssize(k, ve)
    449 	KINFO *k;
    450 	VARENT *ve;
    451 {
    452 	VAR *v;
    453 
    454 	v = ve->var;
    455 	/* XXX don't have info about shared */
    456 	(void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_vm.vm_rssize));
    457 }
    458 
    459 void
    460 p_rssize(k, ve)		/* doesn't account for text */
    461 	KINFO *k;
    462 	VARENT *ve;
    463 {
    464 	VAR *v;
    465 
    466 	v = ve->var;
    467 	(void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_vm.vm_rssize));
    468 }
    469 
    470 void
    471 cputime(k, ve)
    472 	KINFO *k;
    473 	VARENT *ve;
    474 {
    475 	VAR *v;
    476 	long secs;
    477 	long psecs;	/* "parts" of a second. first micro, then centi */
    478 	char obuff[128];
    479 
    480 	v = ve->var;
    481 	if (KI_PROC(k)->p_stat == SZOMB || !k->ki_u.u_valid) {
    482 		secs = 0;
    483 		psecs = 0;
    484 	} else {
    485 		/*
    486 		 * This counts time spent handling interrupts.  We could
    487 		 * fix this, but it is not 100% trivial (and interrupt
    488 		 * time fractions only work on the sparc anyway).	XXX
    489 		 */
    490 		secs = KI_PROC(k)->p_rtime.tv_sec;
    491 		psecs = KI_PROC(k)->p_rtime.tv_usec;
    492 		if (sumrusage) {
    493 			secs += k->ki_u.u_cru.ru_utime.tv_sec +
    494 				k->ki_u.u_cru.ru_stime.tv_sec;
    495 			psecs += k->ki_u.u_cru.ru_utime.tv_usec +
    496 				k->ki_u.u_cru.ru_stime.tv_usec;
    497 		}
    498 		/*
    499 		 * round and scale to 100's
    500 		 */
    501 		psecs = (psecs + 5000) / 10000;
    502 		secs += psecs / 100;
    503 		psecs = psecs % 100;
    504 	}
    505 	(void)snprintf(obuff, sizeof(obuff),
    506 	    "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
    507 	(void)printf("%*s", v->width, obuff);
    508 }
    509 
    510 double
    511 getpcpu(k)
    512 	KINFO *k;
    513 {
    514 	struct proc *p;
    515 	static int failure;
    516 
    517 	if (!nlistread)
    518 		failure = donlist();
    519 	if (failure)
    520 		return (0.0);
    521 
    522 	p = KI_PROC(k);
    523 #define	fxtofl(fixpt)	((double)(fixpt) / fscale)
    524 
    525 	/* XXX - I don't like this */
    526 	if (p->p_swtime == 0 || (p->p_flag & P_INMEM) == 0
    527 	    || p->p_stat == SZOMB)
    528 		return (0.0);
    529 	if (rawcpu)
    530 		return (100.0 * fxtofl(p->p_pctcpu));
    531 	return (100.0 * fxtofl(p->p_pctcpu) /
    532 		(1.0 - exp(p->p_swtime * log(fxtofl(ccpu)))));
    533 }
    534 
    535 void
    536 pcpu(k, ve)
    537 	KINFO *k;
    538 	VARENT *ve;
    539 {
    540 	VAR *v;
    541 
    542 	v = ve->var;
    543 	(void)printf("%*.1f", v->width, getpcpu(k));
    544 }
    545 
    546 double
    547 getpmem(k)
    548 	KINFO *k;
    549 {
    550 	static int failure;
    551 	struct proc *p;
    552 	struct eproc *e;
    553 	double fracmem;
    554 	int szptudot;
    555 
    556 	if (!nlistread)
    557 		failure = donlist();
    558 	if (failure)
    559 		return (0.0);
    560 
    561 	p = KI_PROC(k);
    562 	e = KI_EPROC(k);
    563 	if ((p->p_flag & P_INMEM) == 0)
    564 		return (0.0);
    565 	/* XXX want pmap ptpages, segtab, etc. (per architecture) */
    566 	szptudot = USPACE/getpagesize();
    567 	/* XXX don't have info about shared */
    568 	fracmem = ((float)e->e_vm.vm_rssize + szptudot)/CLSIZE/mempages;
    569 	return (100.0 * fracmem);
    570 }
    571 
    572 void
    573 pmem(k, ve)
    574 	KINFO *k;
    575 	VARENT *ve;
    576 {
    577 	VAR *v;
    578 
    579 	v = ve->var;
    580 	(void)printf("%*.1f", v->width, getpmem(k));
    581 }
    582 
    583 void
    584 pagein(k, ve)
    585 	KINFO *k;
    586 	VARENT *ve;
    587 {
    588 	VAR *v;
    589 
    590 	v = ve->var;
    591 	(void)printf("%*ld", v->width,
    592 	    k->ki_u.u_valid ? k->ki_u.u_ru.ru_majflt : 0);
    593 }
    594 
    595 void
    596 maxrss(k, ve)
    597 	KINFO *k;
    598 	VARENT *ve;
    599 {
    600 	VAR *v;
    601 
    602 	v = ve->var;
    603 	(void)printf("%*s", v->width, "-");
    604 }
    605 
    606 void
    607 tsize(k, ve)
    608 	KINFO *k;
    609 	VARENT *ve;
    610 {
    611 	VAR *v;
    612 
    613 	v = ve->var;
    614 	(void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_vm.vm_tsize));
    615 }
    616 
    617 /*
    618  * Generic output routines.  Print fields from various prototype
    619  * structures.
    620  */
    621 static void
    622 printval(bp, v)
    623 	char *bp;
    624 	VAR *v;
    625 {
    626 	static char ofmt[32] = "%";
    627 	char *fcp, *cp;
    628 	enum type type;
    629 
    630 	cp = ofmt + 1;
    631 	fcp = v->fmt;
    632 	if (v->flag & LJUST)
    633 		*cp++ = '-';
    634 	*cp++ = '*';
    635 	while ((*cp++ = *fcp++) != '\0')
    636 		continue;
    637 
    638 	/*
    639 	 * Note that the "INF127" check is nonsensical for types
    640 	 * that are or can be signed.
    641 	 */
    642 #define	GET(type)		(*(type *)bp)
    643 #define	CHK_INF127(n)		(((n) > 127) && (v->flag & INF127) ? 127 : (n))
    644 
    645 	switch (v->type) {
    646 	case INT32:
    647 		if (sizeof(int32_t) == sizeof(int))
    648 			type = INT;
    649 		else if (sizeof(int32_t) == sizeof(long))
    650 			type = LONG;
    651 		else
    652 			errx(1, "unknown conversion for type %d", v->type);
    653 		break;
    654 	case UINT32:
    655 		if (sizeof(u_int32_t) == sizeof(u_int))
    656 			type = UINT;
    657 		else if (sizeof(u_int32_t) == sizeof(u_long))
    658 			type = ULONG;
    659 		else
    660 			errx(1, "unknown conversion for type %d", v->type);
    661 		break;
    662 	default:
    663 		type = v->type;
    664 		break;
    665 	}
    666 
    667 	switch (type) {
    668 	case CHAR:
    669 		(void)printf(ofmt, v->width, GET(char));
    670 		break;
    671 	case UCHAR:
    672 		(void)printf(ofmt, v->width, CHK_INF127(GET(u_char)));
    673 		break;
    674 	case SHORT:
    675 		(void)printf(ofmt, v->width, GET(short));
    676 		break;
    677 	case USHORT:
    678 		(void)printf(ofmt, v->width, CHK_INF127(GET(u_short)));
    679 		break;
    680 	case INT:
    681 		(void)printf(ofmt, v->width, GET(int));
    682 		break;
    683 	case UINT:
    684 		(void)printf(ofmt, v->width, CHK_INF127(GET(u_int)));
    685 		break;
    686 	case LONG:
    687 		(void)printf(ofmt, v->width, GET(long));
    688 		break;
    689 	case ULONG:
    690 		(void)printf(ofmt, v->width, CHK_INF127(GET(u_long)));
    691 		break;
    692 	case KPTR:
    693 		(void)printf(ofmt, v->width, GET(u_long));
    694 		break;
    695 	default:
    696 		errx(1, "unknown type %d", v->type);
    697 	}
    698 #undef GET
    699 #undef CHK_INF127
    700 }
    701 
    702 void
    703 pvar(k, ve)
    704 	KINFO *k;
    705 	VARENT *ve;
    706 {
    707 	VAR *v;
    708 
    709 	v = ve->var;
    710 	printval((char *)KI_PROC(k) + v->off, v);
    711 }
    712 
    713 void
    714 evar(k, ve)
    715 	KINFO *k;
    716 	VARENT *ve;
    717 {
    718 	VAR *v;
    719 
    720 	v = ve->var;
    721 	printval((char *)KI_EPROC(k) + v->off, v);
    722 }
    723 
    724 void
    725 uvar(k, ve)
    726 	KINFO *k;
    727 	VARENT *ve;
    728 {
    729 	VAR *v;
    730 
    731 	v = ve->var;
    732 	if (k->ki_u.u_valid)
    733 		printval((char *)&k->ki_u + v->off, v);
    734 	else
    735 		(void)printf("%*s", v->width, "-");
    736 }
    737 
    738 void
    739 rvar(k, ve)
    740 	KINFO *k;
    741 	VARENT *ve;
    742 {
    743 	VAR *v;
    744 
    745 	v = ve->var;
    746 	if (k->ki_u.u_valid)
    747 		printval((char *)&k->ki_u.u_ru + v->off, v);
    748 	else
    749 		(void)printf("%*s", v->width, "-");
    750 }
    751