1 /* $OpenBSD: print.c,v 1.89 2024/04/28 16:43:15 florian Exp $ */ 2 /* $NetBSD: print.c,v 1.27 1995/09/29 21:58:12 cgd Exp $ */ 3 4 /*- 5 * Copyright (c) 1990, 1993, 1994 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/param.h> /* PZERO NODEV */ 34 #include <sys/types.h> 35 #include <sys/signal.h> 36 #include <sys/proc.h> 37 #include <sys/stat.h> 38 39 #include <sys/sysctl.h> 40 #define PLEDGENAMES 41 #include <sys/pledge.h> 42 43 #include <err.h> 44 #include <grp.h> 45 #include <kvm.h> 46 #include <math.h> 47 #include <nlist.h> 48 #include <stddef.h> 49 #include <stdio.h> 50 #include <stdlib.h> 51 #include <string.h> 52 #include <unistd.h> 53 #include <limits.h> 54 #include <pwd.h> 55 56 #include "ps.h" 57 58 extern kvm_t *kd; 59 extern int needenv, needcomm, neednlist, commandonly; 60 61 int mbswprint(const char *, int, int); /* utf8.c */ 62 63 static char *cmdpart(char *); 64 65 #define min(a,b) ((a) < (b) ? (a) : (b)) 66 67 static char * 68 cmdpart(char *arg0) 69 { 70 char *cp; 71 72 return ((cp = strrchr(arg0, '/')) != NULL ? cp + 1 : arg0); 73 } 74 75 void 76 printheader(void) 77 { 78 VAR *v; 79 struct varent *vent; 80 81 if (!needheader) 82 return; 83 for (vent = vhead; vent; vent = vent->next) { 84 v = vent->var; 85 if (v->flag & LJUST) { 86 if (vent->next == NULL) /* last one */ 87 (void)printf("%s", v->header); 88 else 89 (void)printf("%-*s", v->width, v->header); 90 } else 91 (void)printf("%*s", v->width, v->header); 92 if (vent->next != NULL) 93 (void)putchar(' '); 94 } 95 (void)putchar('\n'); 96 } 97 98 static int 99 print_comm_name(const struct kinfo_proc *kp, int left, int trail) 100 { 101 left -= mbswprint(kp->p_comm, left, trail); 102 if (left > 1 && kp->p_name[0] != '\0') { 103 putchar('/'); 104 left--; 105 left -= mbswprint(kp->p_name, left, trail); 106 } 107 return left; 108 } 109 110 void 111 command(const struct pinfo *pi, VARENT *ve) 112 { 113 const struct kinfo_proc *kp = pi->ki; 114 VAR *v; 115 int left, wantspace = 0; 116 char **p; 117 118 /* 119 * Determine the available number of display columns. 120 * Always decrement and check after writing. 121 * No check is needed before mbswprint() 122 * and after writing the last data, though. 123 */ 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 = INT_MAX; 135 136 if (needenv && kd != NULL) { 137 char **envp = kvm_getenvv(kd, kp, termwidth); 138 if ((p = envp) != NULL) { 139 while (*p) { 140 if (wantspace) { 141 putchar(' '); 142 left--; 143 } 144 left -= mbswprint(*p, left, 0); 145 if (left == 0) 146 return; 147 p++; 148 wantspace = 1; 149 } 150 } 151 } 152 153 if (needcomm) { 154 if (pi->prefix) 155 left -= mbswprint(pi->prefix, left, 0); 156 if (!commandonly) { 157 char **argv = NULL; 158 159 if (kd != NULL) { 160 argv = kvm_getargv(kd, kp, termwidth); 161 if ((p = argv) != NULL) { 162 while (*p) { 163 if (wantspace) { 164 putchar(' '); 165 left--; 166 } 167 left -= mbswprint(*p, left, 0); 168 if (left == 0) 169 return; 170 p++; 171 wantspace = 1; 172 } 173 } 174 } 175 if (argv == NULL || argv[0] == NULL || 176 kp->p_name[0] != '\0' || 177 strcmp(cmdpart(argv[0]), kp->p_comm)) { 178 if (wantspace) { 179 putchar(' '); 180 if (--left == 0) 181 return; 182 } 183 putchar('('); 184 left--; 185 left = print_comm_name(kp, left, 0); 186 if (left == 0) 187 return; 188 putchar(')'); 189 left--; 190 } 191 } else { 192 if (wantspace) { 193 putchar(' '); 194 left--; 195 } 196 left = print_comm_name(kp, left, 0); 197 } 198 } 199 if (ve->next != NULL) 200 while (left-- > 0) 201 putchar(' '); 202 } 203 204 void 205 ucomm(const struct pinfo *pi, VARENT *ve) 206 { 207 const struct kinfo_proc *kp = pi->ki; 208 mbswprint(kp->p_comm, ve->var->width, ve->next != NULL); 209 } 210 211 void 212 curwd(const struct pinfo *pi, VARENT *ve) 213 { 214 const struct kinfo_proc *kp = pi->ki; 215 int name[] = { CTL_KERN, KERN_PROC_CWD, kp->p_pid }; 216 char path[PATH_MAX]; 217 size_t pathlen = sizeof path; 218 219 if (!kvm_sysctl_only || sysctl(name, 3, path, &pathlen, NULL, 0) != 0) 220 *path = '\0'; 221 222 mbswprint(path, ve->var->width, ve->next != NULL); 223 } 224 225 void 226 logname(const struct pinfo *pi, VARENT *ve) 227 { 228 const struct kinfo_proc *kp = pi->ki; 229 VAR *v; 230 231 v = ve->var; 232 if (kp->p_login[0]) { 233 int n = min(v->width, LOGIN_NAME_MAX); 234 mbswprint(kp->p_login, n, ve->next != NULL); 235 if (ve->next != NULL) 236 while (n++ < v->width) 237 putchar(' '); 238 } else 239 (void)printf("%-*s", v->width, "-"); 240 } 241 242 #define pgtok(a) (((unsigned long long)(a)*getpagesize())/1024) 243 244 void 245 printstate(const struct pinfo *pi, VARENT *ve) 246 { 247 const struct kinfo_proc *kp = pi->ki; 248 int flag; 249 char *cp, state = '\0'; 250 VAR *v; 251 char buf[16]; 252 253 v = ve->var; 254 flag = kp->p_flag; 255 cp = buf; 256 257 switch (kp->p_stat) { 258 259 case SSTOP: 260 *cp = 'T'; 261 break; 262 263 case SSLEEP: 264 if (flag & P_SINTR) /* interruptible (long) */ 265 *cp = kp->p_slptime >= maxslp ? 'I' : 'S'; 266 else 267 *cp = 'D'; 268 break; 269 270 case SRUN: 271 case SIDL: 272 case SONPROC: 273 state = *cp = 'R'; 274 break; 275 276 case SDEAD: 277 *cp = 'Z'; 278 break; 279 280 default: 281 *cp = '?'; 282 } 283 cp++; 284 285 if (kp->p_nice < NZERO) 286 *cp++ = '<'; 287 else if (kp->p_nice > NZERO) 288 *cp++ = 'N'; 289 if (kp->p_psflags & PS_TRACED) 290 *cp++ = 'X'; 291 if ((kp->p_psflags & (PS_EXITING | PS_ZOMBIE)) == PS_EXITING) 292 *cp++ = 'E'; 293 if (kp->p_psflags & PS_ISPWAIT) 294 *cp++ = 'V'; 295 if (flag & P_SYSTEM) 296 *cp++ = 'K'; 297 if ((flag & P_SYSTEM) == 0 && 298 kp->p_rlim_rss_cur / 1024 < pgtok(kp->p_vm_rssize)) 299 *cp++ = '>'; 300 if (kp->p_eflag & EPROC_SLEADER) 301 *cp++ = 's'; 302 if ((kp->p_psflags & PS_CONTROLT) && kp->p__pgid == kp->p_tpgid) 303 *cp++ = '+'; 304 if (kp->p_psflags & PS_PLEDGE) 305 *cp++ = 'p'; 306 if (kp->p_eflag & EPROC_UNVEIL) { 307 if (kp->p_eflag & EPROC_LKUNVEIL) 308 *cp++ = 'U'; 309 else 310 *cp++ = 'u'; 311 } 312 if (kp->p_psflags & PS_CHROOT) 313 *cp++ = 'c'; 314 *cp = '\0'; 315 316 if (state == 'R' && kp->p_cpuid != KI_NOCPU) { 317 char pbuf[16]; 318 319 snprintf(pbuf, sizeof pbuf, "/%llu", kp->p_cpuid); 320 *++cp = '\0'; 321 strlcat(buf, pbuf, sizeof buf); 322 cp = buf + strlen(buf); 323 } 324 325 (void)printf("%-*s", v->width, buf); 326 } 327 328 void 329 printpledge(const struct pinfo *pi, VARENT *ve) 330 { 331 const struct kinfo_proc *kp = pi->ki; 332 int i; 333 VAR *v; 334 char buf[1024]; 335 336 v = ve->var; 337 buf[0] = '\0'; 338 339 for (i = 0; pledgenames[i].bits != 0; i++) { 340 if (pledgenames[i].bits & kp->p_pledge) { 341 if (*buf != '\0') 342 strlcat(buf, ",", sizeof buf); 343 strlcat(buf, pledgenames[i].name, sizeof buf); 344 } 345 } 346 347 (void)printf("%-*s", v->width, buf); 348 } 349 350 void 351 pri(const struct pinfo *pi, VARENT *ve) 352 { 353 const struct kinfo_proc *kp = pi->ki; 354 VAR *v; 355 356 v = ve->var; 357 (void)printf("%*d", v->width, kp->p_priority - PZERO); 358 } 359 360 void 361 pnice(const struct pinfo *pi, VARENT *ve) 362 { 363 const struct kinfo_proc *kp = pi->ki; 364 VAR *v; 365 366 v = ve->var; 367 (void)printf("%*d", v->width, kp->p_nice - NZERO); 368 } 369 370 void 371 euname(const struct pinfo *pi, VARENT *ve) 372 { 373 const struct kinfo_proc *kp = pi->ki; 374 375 mbswprint(user_from_uid(kp->p_uid, 0), ve->var->width, 376 ve->next != NULL); 377 } 378 379 void 380 runame(const struct pinfo *pi, VARENT *ve) 381 { 382 const struct kinfo_proc *kp = pi->ki; 383 384 mbswprint(user_from_uid(kp->p_ruid, 0), ve->var->width, 385 ve->next != NULL); 386 } 387 388 void 389 gname(const struct pinfo *pi, VARENT *ve) 390 { 391 const struct kinfo_proc *kp = pi->ki; 392 393 mbswprint(group_from_gid(kp->p_gid, 0), ve->var->width, 394 ve->next != NULL); 395 } 396 397 void 398 rgname(const struct pinfo *pi, VARENT *ve) 399 { 400 const struct kinfo_proc *kp = pi->ki; 401 402 mbswprint(group_from_gid(kp->p_rgid, 0), ve->var->width, 403 ve->next != NULL); 404 } 405 406 void 407 supgid(const struct pinfo *pi, VARENT *ve) 408 { 409 const struct kinfo_proc *kp = pi->ki; 410 char buf[1024]; 411 char *p = buf; 412 ssize_t size = sizeof(buf); 413 int i, len; 414 415 for (i = 0; i < kp->p_ngroups; i++) { 416 len = snprintf(p, size, "%s%u", 417 p == buf ? "" : ",", 418 kp->p_groups[i]); 419 if (len < 0 || len >= size) 420 break; 421 p += len; 422 size -= len; 423 } 424 425 (void)printf("%-*s", ve->var->width, buf); 426 } 427 428 void 429 supgrp(const struct pinfo *pi, VARENT *ve) 430 { 431 const struct kinfo_proc *kp = pi->ki; 432 char buf[1024]; 433 char *p = buf; 434 ssize_t size = sizeof(buf); 435 int i, len; 436 437 for (i = 0; i < kp->p_ngroups; i++) { 438 len = snprintf(p, size, "%s%s", 439 p == buf ? "" : ",", 440 group_from_gid(kp->p_groups[i], 0)); 441 if (len < 0 || len >= size) 442 break; 443 p += len; 444 size -= len; 445 } 446 447 (void)printf("%-*s", ve->var->width, buf); 448 } 449 450 void 451 tdev(const struct pinfo *pi, VARENT *ve) 452 { 453 const struct kinfo_proc *kp = pi->ki; 454 VAR *v; 455 dev_t dev; 456 457 v = ve->var; 458 dev = kp->p_tdev; 459 if (dev == NODEV) 460 (void)printf("%*s", v->width, "??"); 461 else { 462 char buff[10+1+10+1]; 463 464 (void)snprintf(buff, sizeof(buff), 465 "%u/%u", major(dev), minor(dev)); 466 (void)printf("%*s", v->width, buff); 467 } 468 } 469 470 void 471 tname(const struct pinfo *pi, VARENT *ve) 472 { 473 const struct kinfo_proc *kp = pi->ki; 474 VAR *v; 475 dev_t dev; 476 char *ttname; 477 478 v = ve->var; 479 dev = kp->p_tdev; 480 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 481 (void)printf("%-*s", v->width, "??"); 482 else { 483 if (strncmp(ttname, "tty", 3) == 0) 484 ttname += 3; 485 (void)printf("%*.*s%c", v->width-1, v->width-1, ttname, 486 kp->p_eflag & EPROC_CTTY ? ' ' : '-'); 487 } 488 } 489 490 void 491 longtname(const struct pinfo *pi, VARENT *ve) 492 { 493 const struct kinfo_proc *kp = pi->ki; 494 VAR *v; 495 dev_t dev; 496 char *ttname; 497 498 v = ve->var; 499 dev = kp->p_tdev; 500 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 501 (void)printf("%-*s", v->width, "??"); 502 else 503 (void)printf("%-*s", v->width, ttname); 504 } 505 506 void 507 started(const struct pinfo *pi, VARENT *ve) 508 { 509 const struct kinfo_proc *kp = pi->ki; 510 VAR *v; 511 static time_t now; 512 time_t startt; 513 struct tm *tp; 514 char buf[100]; 515 516 v = ve->var; 517 if (!kp->p_uvalid) { 518 (void)printf("%-*s", v->width, "-"); 519 return; 520 } 521 522 #define SECSPERHOUR (60 * 60) 523 #define SECSPERDAY (24 * 60 * 60) 524 525 startt = kp->p_ustart_sec; 526 tp = localtime(&startt); 527 if (tp == NULL) { 528 (void)printf("%-*s", v->width, "-"); 529 return; 530 } 531 if (!now) 532 (void)time(&now); 533 if (now - kp->p_ustart_sec < 12 * SECSPERHOUR) { 534 (void)strftime(buf, sizeof(buf) - 1, "%l:%M%p", tp); 535 } else if (now - kp->p_ustart_sec < 7 * SECSPERDAY) { 536 (void)strftime(buf, sizeof(buf) - 1, "%a%I%p", tp); 537 } else 538 (void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp); 539 (void)printf("%-*s", v->width, buf); 540 } 541 542 void 543 lstarted(const struct pinfo *pi, VARENT *ve) 544 { 545 const struct kinfo_proc *kp = pi->ki; 546 VAR *v; 547 time_t startt; 548 char buf[100]; 549 550 v = ve->var; 551 if (!kp->p_uvalid) { 552 (void)printf("%-*s", v->width, "-"); 553 return; 554 } 555 startt = kp->p_ustart_sec; 556 (void)strftime(buf, sizeof(buf) -1, "%c", 557 localtime(&startt)); 558 (void)printf("%-*s", v->width, buf); 559 } 560 561 void elapsed(const struct pinfo *pi, VARENT *ve) 562 { 563 const struct kinfo_proc *kp = pi->ki; 564 VAR *v; 565 static time_t now; 566 time_t secs; 567 char buf[64]; 568 long days, hours, minutes, seconds; 569 570 v = ve->var; 571 if (!kp->p_uvalid) { 572 (void)printf("%*s", v->width, "-"); 573 return; 574 } 575 576 if (!now) 577 (void)time(&now); 578 secs = now - kp->p_ustart_sec; 579 580 if (secs < 0) { 581 (void)printf("%*s", v->width, "-"); 582 return; 583 } 584 585 days = secs / SECSPERDAY; 586 secs %= SECSPERDAY; 587 588 hours = secs / SECSPERHOUR; 589 secs %= SECSPERHOUR; 590 591 minutes = secs / 60; 592 seconds = secs % 60; 593 594 if (days > 0) 595 (void)snprintf(buf, sizeof(buf), "%ld-%02ld:%02ld:%02ld", 596 days, hours, minutes, seconds); 597 else if (hours > 0) 598 (void)snprintf(buf, sizeof(buf), "%02ld:%02ld:%02ld", 599 hours, minutes, seconds); 600 else 601 (void)snprintf(buf, sizeof(buf), "%02ld:%02ld", 602 minutes, seconds); 603 (void)printf("%*s", v->width, buf); 604 } 605 606 void 607 wchan(const struct pinfo *pi, VARENT *ve) 608 { 609 const struct kinfo_proc *kp = pi->ki; 610 VAR *v; 611 612 v = ve->var; 613 if (kp->p_wmesg[0]) { 614 (void)printf("%-*s", (int)v->width, kp->p_wmesg); 615 } else 616 (void)printf("%-*s", v->width, "-"); 617 } 618 619 void 620 vsize(const struct pinfo *pi, VARENT *ve) 621 { 622 const struct kinfo_proc *kp = pi->ki; 623 VAR *v; 624 625 v = ve->var; 626 (void)printf("%*llu", v->width, 627 pgtok(kp->p_vm_dsize + kp->p_vm_ssize + kp->p_vm_tsize)); 628 } 629 630 void 631 rssize(const struct pinfo *pi, VARENT *ve) 632 { 633 const struct kinfo_proc *kp = pi->ki; 634 VAR *v; 635 636 v = ve->var; 637 /* XXX don't have info about shared */ 638 (void)printf("%*llu", v->width, (kp->p_flag & P_SYSTEM) ? 0 : 639 pgtok(kp->p_vm_rssize)); 640 } 641 642 void 643 p_rssize(const struct pinfo *pi, VARENT *ve) 644 { 645 const struct kinfo_proc *kp = pi->ki; 646 VAR *v; 647 648 v = ve->var; 649 (void)printf("%*llu", v->width, (kp->p_flag & P_SYSTEM) ? 0 : 650 pgtok(kp->p_vm_rssize)); 651 } 652 653 void 654 cputime(const struct pinfo *pi, VARENT *ve) 655 { 656 const struct kinfo_proc *kp = pi->ki; 657 VAR *v; 658 long secs; 659 long psecs; /* "parts" of a second. first micro, then centi */ 660 char obuff[128]; 661 662 v = ve->var; 663 if (kp->p_stat == SDEAD || !kp->p_uvalid) { 664 secs = 0; 665 psecs = 0; 666 } else { 667 /* 668 * This counts time spent handling interrupts. XXX 669 */ 670 secs = kp->p_rtime_sec; 671 psecs = kp->p_rtime_usec; 672 if (sumrusage) { 673 secs += kp->p_uctime_sec; 674 psecs += kp->p_uctime_usec; 675 } 676 /* 677 * round and scale to 100's 678 */ 679 psecs = (psecs + 5000) / 10000; 680 secs += psecs / 100; 681 psecs = psecs % 100; 682 } 683 (void)snprintf(obuff, sizeof(obuff), 684 "%3ld:%02ld.%02ld", secs/60, secs%60, psecs); 685 (void)printf("%*s", v->width, obuff); 686 } 687 688 double 689 getpcpu(const struct kinfo_proc *kp) 690 { 691 if (fscale == 0) 692 return (0.0); 693 694 #define fxtofl(fixpt) ((double)(fixpt) / fscale) 695 696 return (100.0 * fxtofl(kp->p_pctcpu)); 697 } 698 699 void 700 pcpu(const struct pinfo *pi, VARENT *ve) 701 { 702 VAR *v; 703 704 v = ve->var; 705 (void)printf("%*.1f", v->width, getpcpu(pi->ki)); 706 } 707 708 double 709 getpmem(const struct kinfo_proc *kp) 710 { 711 double fracmem; 712 713 if (mempages == 0) 714 return (0.0); 715 716 if (kp->p_flag & P_SYSTEM) 717 return (0.0); 718 /* XXX don't have info about shared */ 719 fracmem = ((float)kp->p_vm_rssize)/mempages; 720 return (100.0 * fracmem); 721 } 722 723 void 724 pmem(const struct pinfo *pi, VARENT *ve) 725 { 726 VAR *v; 727 728 v = ve->var; 729 (void)printf("%*.1f", v->width, getpmem(pi->ki)); 730 } 731 732 void 733 pagein(const struct pinfo *pi, VARENT *ve) 734 { 735 const struct kinfo_proc *kp = pi->ki; 736 VAR *v; 737 738 v = ve->var; 739 (void)printf("%*llu", v->width, 740 kp->p_uvalid ? kp->p_uru_majflt : 0); 741 } 742 743 void 744 maxrss(const struct pinfo *pi, VARENT *ve) 745 { 746 const struct kinfo_proc *kp = pi->ki; 747 VAR *v; 748 749 v = ve->var; 750 (void)printf("%*llu", v->width, kp->p_rlim_rss_cur / 1024); 751 } 752 753 void 754 tsize(const struct pinfo *pi, VARENT *ve) 755 { 756 const struct kinfo_proc *kp = pi->ki; 757 VAR *v; 758 759 v = ve->var; 760 (void)printf("%*llu", v->width, pgtok(kp->p_vm_tsize)); 761 } 762 763 void 764 dsize(const struct pinfo *pi, VARENT *ve) 765 { 766 const struct kinfo_proc *kp = pi->ki; 767 VAR *v; 768 769 v = ve->var; 770 (void)printf("%*llu", v->width, pgtok(kp->p_vm_dsize)); 771 } 772 773 void 774 ssize(const struct pinfo *pi, VARENT *ve) 775 { 776 const struct kinfo_proc *kp = pi->ki; 777 VAR *v; 778 779 v = ve->var; 780 (void)printf("%*llu", v->width, pgtok(kp->p_vm_ssize)); 781 } 782 783 /* 784 * Generic output routines. Print fields from various prototype 785 * structures. 786 */ 787 static void 788 printval(char *bp, VAR *v) 789 { 790 char ofmt[32]; 791 792 snprintf(ofmt, sizeof(ofmt), "%%%s*%s", (v->flag & LJUST) ? "-" : "", 793 v->fmt); 794 795 /* 796 * Note that the "INF127" check is nonsensical for types 797 * that are or can be signed. 798 */ 799 #define GET(type) (*(type *)bp) 800 #define CHK_INF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n)) 801 802 switch (v->type) { 803 case INT8: 804 (void)printf(ofmt, v->width, GET(int8_t)); 805 break; 806 case UINT8: 807 (void)printf(ofmt, v->width, CHK_INF127(GET(u_int8_t))); 808 break; 809 case INT16: 810 (void)printf(ofmt, v->width, GET(int16_t)); 811 break; 812 case UINT16: 813 (void)printf(ofmt, v->width, CHK_INF127(GET(u_int16_t))); 814 break; 815 case INT32: 816 (void)printf(ofmt, v->width, GET(int32_t)); 817 break; 818 case UINT32: 819 (void)printf(ofmt, v->width, CHK_INF127(GET(u_int32_t))); 820 break; 821 case INT64: 822 (void)printf(ofmt, v->width, GET(int64_t)); 823 break; 824 case UINT64: 825 (void)printf(ofmt, v->width, CHK_INF127(GET(u_int64_t))); 826 break; 827 default: 828 errx(1, "unknown type %d", v->type); 829 } 830 #undef GET 831 #undef CHK_INF127 832 } 833 834 void 835 pvar(const struct pinfo *pi, VARENT *ve) 836 { 837 const struct kinfo_proc *kp = pi->ki; 838 VAR *v; 839 840 v = ve->var; 841 if ((v->flag & USER) && !kp->p_uvalid) 842 (void)printf("%*s", v->width, "-"); 843 else 844 printval((char *)kp + v->off, v); 845 } 846