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