print.c revision 1.35 1 /* $NetBSD: print.c,v 1.35 1998/02/05 03:51:16 gwr 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.35 1998/02/05 03:51:16 gwr 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
51 #ifdef P_PPWAIT
52 #define NEWVM
53 #endif
54
55 #ifdef NEWVM
56 #include <sys/ucred.h>
57 #include <sys/sysctl.h>
58 #include <vm/vm.h>
59 #else
60 #include <machine/pte.h>
61 #include <sys/vmparam.h>
62 #include <sys/vm.h>
63 #endif
64
65 #include <err.h>
66 #include <kvm.h>
67 #include <math.h>
68 #include <nlist.h>
69 #include <pwd.h>
70 #include <stddef.h>
71 #include <stdio.h>
72 #include <stdlib.h>
73 #include <string.h>
74 #include <tzfile.h>
75 #include <unistd.h>
76
77 #include "ps.h"
78
79 extern kvm_t *kd;
80 extern int needenv, needcomm, commandonly;
81
82 static char *cmdpart __P((char *));
83 static void printval __P((char *, VAR *));
84
85 #define min(a,b) ((a) <= (b) ? (a) : (b))
86 #define max(a,b) ((a) >= (b) ? (a) : (b))
87
88 static char *
89 cmdpart(arg0)
90 char *arg0;
91 {
92 char *cp;
93
94 return ((cp = strrchr(arg0, '/')) != NULL ? cp + 1 : arg0);
95 }
96
97 void
98 printheader()
99 {
100 VAR *v;
101 struct varent *vent;
102
103 for (vent = vhead; vent; vent = vent->next) {
104 v = vent->var;
105 if (v->flag & LJUST) {
106 if (vent->next == NULL) /* last one */
107 (void)printf("%s", v->header);
108 else
109 (void)printf("%-*s", v->width, v->header);
110 } else
111 (void)printf("%*s", v->width, v->header);
112 if (vent->next != NULL)
113 (void)putchar(' ');
114 }
115 (void)putchar('\n');
116 }
117
118 void
119 command(ki, ve)
120 KINFO *ki;
121 VARENT *ve;
122 {
123 VAR *v;
124 int left;
125 char **argv, **p;
126
127 v = ve->var;
128 if (ve->next != NULL || termwidth != UNLIMITED) {
129 if (ve->next == NULL) {
130 left = termwidth - (totwidth - v->width);
131 if (left < 1) /* already wrapped, just use std width */
132 left = v->width;
133 } else
134 left = v->width;
135 } else
136 left = -1;
137 if (needenv) {
138 argv = kvm_getenvv(kd, ki->ki_p, termwidth);
139 if ((p = argv) != NULL) {
140 while (*p) {
141 fmt_puts(*p, &left);
142 p++;
143 fmt_putc(' ', &left);
144 }
145 }
146 }
147 if (needcomm) {
148 if (!commandonly) {
149 argv = kvm_getargv(kd, ki->ki_p, termwidth);
150 if ((p = argv) != NULL) {
151 while (*p) {
152 fmt_puts(*p, &left);
153 p++;
154 fmt_putc(' ', &left);
155 }
156 }
157 if (argv == 0 || argv[0] == 0 ||
158 strcmp(cmdpart(argv[0]), KI_PROC(ki)->p_comm)) {
159 fmt_putc('(', &left);
160 fmt_puts(KI_PROC(ki)->p_comm, &left);
161 fmt_putc(')', &left);
162 }
163 } else {
164 fmt_puts(KI_PROC(ki)->p_comm, &left);
165 }
166 }
167 if (ve->next && left > 0)
168 printf("%*s", left, "");
169 }
170
171 void
172 ucomm(k, ve)
173 KINFO *k;
174 VARENT *ve;
175 {
176 VAR *v;
177
178 v = ve->var;
179 (void)printf("%-*s", v->width, KI_PROC(k)->p_comm);
180 }
181
182 void
183 logname(k, ve)
184 KINFO *k;
185 VARENT *ve;
186 {
187 VAR *v;
188 int n;
189
190 v = ve->var;
191 #ifndef NEWVM
192 (void)printf("%-*s", v->width, KI_PROC(k)->p_logname);
193 #else
194 n = min(v->width, MAXLOGNAME);
195 (void)printf("%-*.*s", n, n, KI_EPROC(k)->e_login);
196 if (v->width > n)
197 (void)printf("%*s", v->width - n, "");
198 #endif
199 }
200
201 void
202 state(k, ve)
203 KINFO *k;
204 VARENT *ve;
205 {
206 struct proc *p;
207 int flag;
208 char *cp;
209 VAR *v;
210 char buf[16];
211
212 v = ve->var;
213 p = KI_PROC(k);
214 flag = p->p_flag;
215 cp = buf;
216
217 switch (p->p_stat) {
218
219 case SSTOP:
220 *cp = 'T';
221 break;
222
223 case SSLEEP:
224 if (flag & P_SINTR) /* interuptable (long) */
225 *cp = p->p_slptime >= MAXSLP ? 'I' : 'S';
226 else
227 *cp = 'D';
228 break;
229
230 case SRUN:
231 case SIDL:
232 *cp = 'R';
233 break;
234
235 case SZOMB:
236 *cp = 'Z';
237 break;
238
239 default:
240 *cp = '?';
241 }
242 cp++;
243 if (flag & P_INMEM) {
244 #ifndef NEWVM
245 if (p->p_rssize > p->p_maxrss)
246 *cp++ = '>';
247 #endif
248 } else
249 *cp++ = 'W';
250 if (p->p_nice < NZERO)
251 *cp++ = '<';
252 else if (p->p_nice > NZERO)
253 *cp++ = 'N';
254 #ifndef NEWVM
255 if (flag & SUANOM)
256 *cp++ = 'A';
257 else if (flag & SSEQL)
258 *cp++ = 'S';
259 #endif
260 if (flag & P_TRACED)
261 *cp++ = 'X';
262 if (flag & P_WEXIT && p->p_stat != SZOMB)
263 *cp++ = 'E';
264 #ifdef NEWVM
265 if (flag & P_PPWAIT)
266 #else
267 if (flag & SVFORK)
268 #endif
269 *cp++ = 'V';
270 #ifdef NEWVM
271 if ((flag & P_SYSTEM) || p->p_holdcnt)
272 #else
273 if (flag & (SSYS|SLOCK|SULOCK|SKEEP|SPHYSIO))
274 #endif
275 *cp++ = 'L';
276 if (KI_EPROC(k)->e_flag & EPROC_SLEADER)
277 *cp++ = 's';
278 if ((flag & P_CONTROLT) && KI_EPROC(k)->e_pgid == KI_EPROC(k)->e_tpgid)
279 *cp++ = '+';
280 *cp = '\0';
281 (void)printf("%-*s", v->width, buf);
282 }
283
284 void
285 pnice(k, ve)
286 KINFO *k;
287 VARENT *ve;
288 {
289 VAR *v;
290
291 v = ve->var;
292 (void)printf("%*d", v->width, KI_PROC(k)->p_nice - NZERO);
293 }
294
295 void
296 pri(k, ve)
297 KINFO *k;
298 VARENT *ve;
299 {
300 VAR *v;
301
302 v = ve->var;
303 (void)printf("%*d", v->width, KI_PROC(k)->p_priority - PZERO);
304 }
305
306 void
307 uname(k, ve)
308 KINFO *k;
309 VARENT *ve;
310 {
311 VAR *v;
312
313 v = ve->var;
314 #ifndef NEWVM
315 (void)printf("%-*s",
316 (int)v->width, user_from_uid(KI_PROC(k)->p_uid, 0));
317 #else
318 (void)printf("%-*s",
319 (int)v->width, user_from_uid(KI_EPROC(k)->e_ucred.cr_uid, 0));
320 #endif
321 }
322
323 void
324 runame(k, ve)
325 KINFO *k;
326 VARENT *ve;
327 {
328 VAR *v;
329
330 v = ve->var;
331 #ifndef NEWVM
332 (void)printf("%-*s",
333 (int)v->width, user_from_uid(KI_PROC(k)->p_ruid, 0));
334 #else
335 (void)printf("%-*s",
336 (int)v->width, user_from_uid(KI_EPROC(k)->e_pcred.p_ruid, 0));
337 #endif
338 }
339
340 void
341 tdev(k, ve)
342 KINFO *k;
343 VARENT *ve;
344 {
345 VAR *v;
346 dev_t dev;
347 char buff[16];
348
349 v = ve->var;
350 dev = KI_EPROC(k)->e_tdev;
351 if (dev == NODEV)
352 (void)printf("%*s", v->width, "??");
353 else {
354 (void)snprintf(buff, sizeof(buff),
355 "%d/%d", major(dev), minor(dev));
356 (void)printf("%*s", v->width, buff);
357 }
358 }
359
360 void
361 tname(k, ve)
362 KINFO *k;
363 VARENT *ve;
364 {
365 VAR *v;
366 dev_t dev;
367 char *ttname;
368
369 v = ve->var;
370 dev = KI_EPROC(k)->e_tdev;
371 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
372 (void)printf("%-*s", v->width, "??");
373 else {
374 if (strncmp(ttname, "tty", 3) == 0)
375 ttname += 3;
376 (void)printf("%*.*s%c", v->width-1, v->width-1, ttname,
377 KI_EPROC(k)->e_flag & EPROC_CTTY ? ' ' : '-');
378 }
379 }
380
381 void
382 longtname(k, ve)
383 KINFO *k;
384 VARENT *ve;
385 {
386 VAR *v;
387 dev_t dev;
388 char *ttname;
389
390 v = ve->var;
391 dev = KI_EPROC(k)->e_tdev;
392 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
393 (void)printf("%-*s", v->width, "??");
394 else
395 (void)printf("%-*s", v->width, ttname);
396 }
397
398 void
399 started(k, ve)
400 KINFO *k;
401 VARENT *ve;
402 {
403 VAR *v;
404 static time_t now;
405 time_t startt;
406 struct tm *tp;
407 char buf[100];
408
409 v = ve->var;
410 if (!k->ki_u.u_valid) {
411 (void)printf("%-*s", v->width, "-");
412 return;
413 }
414
415 startt = k->ki_u.u_start.tv_sec;
416 tp = localtime(&startt);
417 if (!now)
418 (void)time(&now);
419 if (now - k->ki_u.u_start.tv_sec < 24 * SECSPERHOUR) {
420 /* I *hate* SCCS... */
421 static char fmt[] = __CONCAT("%l:%", "M%p");
422 (void)strftime(buf, sizeof(buf) - 1, fmt, tp);
423 } else if (now - k->ki_u.u_start.tv_sec < 7 * SECSPERDAY) {
424 /* I *hate* SCCS... */
425 static char fmt[] = __CONCAT("%a%", "I%p");
426 (void)strftime(buf, sizeof(buf) - 1, fmt, tp);
427 } else
428 (void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
429 (void)printf("%-*s", v->width, buf);
430 }
431
432 void
433 lstarted(k, ve)
434 KINFO *k;
435 VARENT *ve;
436 {
437 VAR *v;
438 time_t startt;
439 char buf[100];
440
441 v = ve->var;
442 if (!k->ki_u.u_valid) {
443 (void)printf("%-*s", v->width, "-");
444 return;
445 }
446 startt = k->ki_u.u_start.tv_sec;
447 (void)strftime(buf, sizeof(buf) -1, "%c",
448 localtime(&startt));
449 (void)printf("%-*s", v->width, buf);
450 }
451
452 void
453 wchan(k, ve)
454 KINFO *k;
455 VARENT *ve;
456 {
457 VAR *v;
458 int n;
459
460 v = ve->var;
461 if (KI_PROC(k)->p_wchan) {
462 if (KI_PROC(k)->p_wmesg) {
463 n = min(v->width, WMESGLEN);
464 (void)printf("%-*.*s", n, n, KI_EPROC(k)->e_wmesg);
465 if (v->width > n)
466 (void)printf("%*s", v->width - n, "");
467 } else
468 (void)printf("%-*lx", v->width,
469 (long)KI_PROC(k)->p_wchan);
470 } else
471 (void)printf("%-*s", v->width, "-");
472 }
473
474 #define pgtok(a) (((a)*getpagesize())/1024)
475
476 void
477 vsize(k, ve)
478 KINFO *k;
479 VARENT *ve;
480 {
481 VAR *v;
482
483 v = ve->var;
484 (void)printf("%*d", v->width,
485 #ifndef NEWVM
486 pgtok(KI_PROC(k)->p_dsize +
487 KI_PROC(k)->p_ssize + KI_EPROC(k)->e_xsize));
488 #else
489 pgtok(KI_EPROC(k)->e_vm.vm_dsize + KI_EPROC(k)->e_vm.vm_ssize +
490 KI_EPROC(k)->e_vm.vm_tsize));
491 #endif
492 }
493
494 void
495 rssize(k, ve)
496 KINFO *k;
497 VARENT *ve;
498 {
499 VAR *v;
500
501 v = ve->var;
502 #ifndef NEWVM
503 (void)printf("%*d", v->width,
504 pgtok(KI_PROC(k)->p_rssize + (KI_EPROC(k)->e_xccount ?
505 (KI_EPROC(k)->e_xrssize / KI_EPROC(k)->e_xccount) : 0)));
506 #else
507 /* XXX don't have info about shared */
508 (void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_vm.vm_rssize));
509 #endif
510 }
511
512 void
513 p_rssize(k, ve) /* doesn't account for text */
514 KINFO *k;
515 VARENT *ve;
516 {
517 VAR *v;
518
519 v = ve->var;
520 #ifndef NEWVM
521 (void)printf("%*d", v->width, pgtok(KI_PROC(k)->p_rssize));
522 #else
523 (void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_vm.vm_rssize));
524 #endif
525 }
526
527 void
528 cputime(k, ve)
529 KINFO *k;
530 VARENT *ve;
531 {
532 VAR *v;
533 long secs;
534 long psecs; /* "parts" of a second. first micro, then centi */
535 char obuff[128];
536
537 v = ve->var;
538 if (KI_PROC(k)->p_stat == SZOMB || !k->ki_u.u_valid) {
539 secs = 0;
540 psecs = 0;
541 } else {
542 /*
543 * This counts time spent handling interrupts. We could
544 * fix this, but it is not 100% trivial (and interrupt
545 * time fractions only work on the sparc anyway). XXX
546 */
547 secs = KI_PROC(k)->p_rtime.tv_sec;
548 psecs = KI_PROC(k)->p_rtime.tv_usec;
549 if (sumrusage) {
550 secs += k->ki_u.u_cru.ru_utime.tv_sec +
551 k->ki_u.u_cru.ru_stime.tv_sec;
552 psecs += k->ki_u.u_cru.ru_utime.tv_usec +
553 k->ki_u.u_cru.ru_stime.tv_usec;
554 }
555 /*
556 * round and scale to 100's
557 */
558 psecs = (psecs + 5000) / 10000;
559 secs += psecs / 100;
560 psecs = psecs % 100;
561 }
562 (void)snprintf(obuff, sizeof(obuff),
563 "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
564 (void)printf("%*s", v->width, obuff);
565 }
566
567 double
568 getpcpu(k)
569 KINFO *k;
570 {
571 struct proc *p;
572 static int failure;
573
574 if (!nlistread)
575 failure = donlist();
576 if (failure)
577 return (0.0);
578
579 p = KI_PROC(k);
580 #define fxtofl(fixpt) ((double)(fixpt) / fscale)
581
582 /* XXX - I don't like this */
583 if (p->p_swtime == 0 || (p->p_flag & P_INMEM) == 0
584 || p->p_stat == SZOMB)
585 return (0.0);
586 if (rawcpu)
587 return (100.0 * fxtofl(p->p_pctcpu));
588 return (100.0 * fxtofl(p->p_pctcpu) /
589 (1.0 - exp(p->p_swtime * log(fxtofl(ccpu)))));
590 }
591
592 void
593 pcpu(k, ve)
594 KINFO *k;
595 VARENT *ve;
596 {
597 VAR *v;
598
599 v = ve->var;
600 (void)printf("%*.1f", v->width, getpcpu(k));
601 }
602
603 double
604 getpmem(k)
605 KINFO *k;
606 {
607 static int failure;
608 struct proc *p;
609 struct eproc *e;
610 double fracmem;
611 int szptudot;
612
613 if (!nlistread)
614 failure = donlist();
615 if (failure)
616 return (0.0);
617
618 p = KI_PROC(k);
619 e = KI_EPROC(k);
620 if ((p->p_flag & P_INMEM) == 0)
621 return (0.0);
622 #ifndef NEWVM
623 szptudot = USPACE/getpagesize() +
624 clrnd(ctopt(p->p_dsize + p->p_ssize + e->e_xsize));
625 fracmem = ((float)p->p_rssize + szptudot)/CLSIZE/mempages;
626 if (p->p_textp && e->e_xccount)
627 fracmem += ((float)e->e_xrssize)/CLSIZE/e->e_xccount/mempages;
628 #else
629 /* XXX want pmap ptpages, segtab, etc. (per architecture) */
630 szptudot = USPACE/getpagesize();
631 /* XXX don't have info about shared */
632 fracmem = ((float)e->e_vm.vm_rssize + szptudot)/CLSIZE/mempages;
633 #endif
634 return (100.0 * fracmem);
635 }
636
637 void
638 pmem(k, ve)
639 KINFO *k;
640 VARENT *ve;
641 {
642 VAR *v;
643
644 v = ve->var;
645 (void)printf("%*.1f", v->width, getpmem(k));
646 }
647
648 void
649 pagein(k, ve)
650 KINFO *k;
651 VARENT *ve;
652 {
653 VAR *v;
654
655 v = ve->var;
656 (void)printf("%*ld", v->width,
657 k->ki_u.u_valid ? k->ki_u.u_ru.ru_majflt : 0);
658 }
659
660 void
661 maxrss(k, ve)
662 KINFO *k;
663 VARENT *ve;
664 {
665 VAR *v;
666
667 v = ve->var;
668 #ifndef NEWVM /* not yet */
669 if (KI_PROC(k)->p_maxrss != (RLIM_INFINITY/getpagesize()))
670 (void)printf("%*d", v->width, pgtok(KI_PROC(k)->p_maxrss));
671 else
672 #endif
673 (void)printf("%*s", v->width, "-");
674 }
675
676 void
677 tsize(k, ve)
678 KINFO *k;
679 VARENT *ve;
680 {
681 VAR *v;
682
683 v = ve->var;
684 #ifndef NEWVM
685 (void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_xsize));
686 #else
687 (void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_vm.vm_tsize));
688 #endif
689 }
690
691 #ifndef NEWVM
692 void
693 trss(k, ve)
694 KINFO *k;
695 VARENT *ve;
696 {
697 VAR *v;
698
699 v = ve->var;
700 (void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_xrssize));
701 }
702 #endif
703
704 /*
705 * Generic output routines. Print fields from various prototype
706 * structures.
707 */
708 static void
709 printval(bp, v)
710 char *bp;
711 VAR *v;
712 {
713 static char ofmt[32] = "%";
714 char *fcp, *cp;
715 enum type type;
716
717 cp = ofmt + 1;
718 fcp = v->fmt;
719 if (v->flag & LJUST)
720 *cp++ = '-';
721 *cp++ = '*';
722 while ((*cp++ = *fcp++) != '\0')
723 continue;
724
725 /*
726 * Note that the "INF127" check is nonsensical for types
727 * that are or can be signed.
728 */
729 #define GET(type) (*(type *)bp)
730 #define CHK_INF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n))
731
732 switch (v->type) {
733 case INT32:
734 if (sizeof(int32_t) == sizeof(int))
735 type = INT;
736 else if (sizeof(int32_t) == sizeof(long))
737 type = LONG;
738 else
739 errx(1, "unknown conversion for type %d", v->type);
740 break;
741 case UINT32:
742 if (sizeof(u_int32_t) == sizeof(u_int))
743 type = UINT;
744 else if (sizeof(u_int32_t) == sizeof(u_long))
745 type = ULONG;
746 else
747 errx(1, "unknown conversion for type %d", v->type);
748 break;
749 default:
750 type = v->type;
751 break;
752 }
753
754 switch (type) {
755 case CHAR:
756 (void)printf(ofmt, v->width, GET(char));
757 break;
758 case UCHAR:
759 (void)printf(ofmt, v->width, CHK_INF127(GET(u_char)));
760 break;
761 case SHORT:
762 (void)printf(ofmt, v->width, GET(short));
763 break;
764 case USHORT:
765 (void)printf(ofmt, v->width, CHK_INF127(GET(u_short)));
766 break;
767 case INT:
768 (void)printf(ofmt, v->width, GET(int));
769 break;
770 case UINT:
771 (void)printf(ofmt, v->width, CHK_INF127(GET(u_int)));
772 break;
773 case LONG:
774 (void)printf(ofmt, v->width, GET(long));
775 break;
776 case ULONG:
777 (void)printf(ofmt, v->width, CHK_INF127(GET(u_long)));
778 break;
779 case KPTR:
780 (void)printf(ofmt, v->width, GET(u_long));
781 break;
782 default:
783 errx(1, "unknown type %d", v->type);
784 }
785 #undef GET
786 #undef CHK_INF127
787 }
788
789 void
790 pvar(k, ve)
791 KINFO *k;
792 VARENT *ve;
793 {
794 VAR *v;
795
796 v = ve->var;
797 printval((char *)KI_PROC(k) + v->off, v);
798 }
799
800 void
801 evar(k, ve)
802 KINFO *k;
803 VARENT *ve;
804 {
805 VAR *v;
806
807 v = ve->var;
808 printval((char *)KI_EPROC(k) + v->off, v);
809 }
810
811 void
812 uvar(k, ve)
813 KINFO *k;
814 VARENT *ve;
815 {
816 VAR *v;
817
818 v = ve->var;
819 if (k->ki_u.u_valid)
820 printval((char *)&k->ki_u + v->off, v);
821 else
822 (void)printf("%*s", v->width, "-");
823 }
824
825 void
826 rvar(k, ve)
827 KINFO *k;
828 VARENT *ve;
829 {
830 VAR *v;
831
832 v = ve->var;
833 if (k->ki_u.u_valid)
834 printval((char *)&k->ki_u.u_ru + v->off, v);
835 else
836 (void)printf("%*s", v->width, "-");
837 }
838