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