1 /*- 2 * Copyright (c) 1990, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #if 0 31 #ifndef lint 32 static char sccsid[] = "@(#)print.c 8.6 (Berkeley) 4/16/94"; 33 #endif /* not lint */ 34 #endif 35 36 #include <sys/cdefs.h> 37 __FBSDID("$FreeBSD$"); 38 39 #include <sys/param.h> 40 #include <sys/time.h> 41 #include <sys/resource.h> 42 #include <sys/proc.h> 43 #include <sys/stat.h> 44 45 #include <sys/mac.h> 46 #include <sys/user.h> 47 #include <sys/sysctl.h> 48 #include <sys/vmmeter.h> 49 50 #include <err.h> 51 #include <grp.h> 52 #include <langinfo.h> 53 #include <locale.h> 54 #include <math.h> 55 #include <nlist.h> 56 #include <pwd.h> 57 #include <stddef.h> 58 #include <stdint.h> 59 #include <stdio.h> 60 #include <stdlib.h> 61 #include <string.h> 62 #include <unistd.h> 63 #include <vis.h> 64 65 #include "ps.h" 66 67 #define COMMAND_WIDTH 16 68 #define ARGUMENTS_WIDTH 16 69 70 #define ps_pgtok(a) (((a) * getpagesize()) / 1024) 71 72 void 73 printheader(void) 74 { 75 VAR *v; 76 struct varent *vent; 77 78 STAILQ_FOREACH(vent, &varlist, next_ve) 79 if (*vent->header != '\0') 80 break; 81 if (!vent) 82 return; 83 84 STAILQ_FOREACH(vent, &varlist, next_ve) { 85 v = vent->var; 86 if (v->flag & LJUST) { 87 if (STAILQ_NEXT(vent, next_ve) == NULL) /* last one */ 88 (void)printf("%s", vent->header); 89 else 90 (void)printf("%-*s", v->width, vent->header); 91 } else 92 (void)printf("%*s", v->width, vent->header); 93 if (STAILQ_NEXT(vent, next_ve) != NULL) 94 (void)putchar(' '); 95 } 96 (void)putchar('\n'); 97 } 98 99 char * 100 arguments(KINFO *k, VARENT *ve) 101 { 102 VAR *v; 103 char *vis_args; 104 105 v = ve->var; 106 if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) 107 errx(1, "malloc failed"); 108 strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); 109 110 if (STAILQ_NEXT(ve, next_ve) != NULL && strlen(vis_args) > ARGUMENTS_WIDTH) 111 vis_args[ARGUMENTS_WIDTH] = '\0'; 112 113 return (vis_args); 114 } 115 116 char * 117 command(KINFO *k, VARENT *ve) 118 { 119 VAR *v; 120 char *vis_args, *vis_env, *str; 121 122 v = ve->var; 123 if (cflag) { 124 /* If it is the last field, then don't pad */ 125 if (STAILQ_NEXT(ve, next_ve) == NULL) { 126 asprintf(&str, "%s%s%s%s", 127 k->ki_d.prefix ? k->ki_d.prefix : "", 128 k->ki_p->ki_comm, 129 (showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "", 130 (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : ""); 131 } else 132 str = strdup(k->ki_p->ki_comm); 133 134 return (str); 135 } 136 if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) 137 errx(1, "malloc failed"); 138 strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); 139 140 if (STAILQ_NEXT(ve, next_ve) == NULL) { 141 /* last field */ 142 143 if (k->ki_env) { 144 if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) 145 == NULL) 146 errx(1, "malloc failed"); 147 strvis(vis_env, k->ki_env, 148 VIS_TAB | VIS_NL | VIS_NOSLASH); 149 } else 150 vis_env = NULL; 151 152 asprintf(&str, "%s%s%s%s", 153 k->ki_d.prefix ? k->ki_d.prefix : "", 154 vis_env ? vis_env : "", 155 vis_env ? " " : "", 156 vis_args); 157 158 if (vis_env != NULL) 159 free(vis_env); 160 free(vis_args); 161 } else { 162 /* ki_d.prefix & ki_env aren't shown for interim fields */ 163 str = vis_args; 164 165 if (strlen(str) > COMMAND_WIDTH) 166 str[COMMAND_WIDTH] = '\0'; 167 } 168 169 return (str); 170 } 171 172 char * 173 ucomm(KINFO *k, VARENT *ve) 174 { 175 VAR *v; 176 char *str; 177 178 v = ve->var; 179 if (STAILQ_NEXT(ve, next_ve) == NULL) { /* last field, don't pad */ 180 asprintf(&str, "%s%s%s%s", 181 k->ki_d.prefix ? k->ki_d.prefix : "", 182 k->ki_p->ki_comm, 183 (showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "", 184 (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : ""); 185 } else { 186 if (showthreads && k->ki_p->ki_numthreads > 1) 187 asprintf(&str, "%s/%s", k->ki_p->ki_comm, k->ki_p->ki_tdname); 188 else 189 str = strdup(k->ki_p->ki_comm); 190 } 191 return (str); 192 } 193 194 char * 195 tdnam(KINFO *k, VARENT *ve) 196 { 197 VAR *v; 198 char *str; 199 200 v = ve->var; 201 if (showthreads && k->ki_p->ki_numthreads > 1) 202 str = strdup(k->ki_p->ki_tdname); 203 else 204 str = strdup(" "); 205 206 return (str); 207 } 208 209 char * 210 logname(KINFO *k, VARENT *ve) 211 { 212 VAR *v; 213 214 v = ve->var; 215 if (*k->ki_p->ki_login == '\0') 216 return (NULL); 217 return (strdup(k->ki_p->ki_login)); 218 } 219 220 char * 221 state(KINFO *k, VARENT *ve) 222 { 223 int flag, tdflags; 224 char *cp, *buf; 225 VAR *v; 226 227 buf = malloc(16); 228 if (buf == NULL) 229 errx(1, "malloc failed"); 230 231 v = ve->var; 232 flag = k->ki_p->ki_flag; 233 tdflags = k->ki_p->ki_tdflags; /* XXXKSE */ 234 cp = buf; 235 236 switch (k->ki_p->ki_stat) { 237 238 case SSTOP: 239 *cp = 'T'; 240 break; 241 242 case SSLEEP: 243 if (tdflags & TDF_SINTR) /* interruptable (long) */ 244 *cp = k->ki_p->ki_slptime >= MAXSLP ? 'I' : 'S'; 245 else 246 *cp = 'D'; 247 break; 248 249 case SRUN: 250 case SIDL: 251 *cp = 'R'; 252 break; 253 254 case SWAIT: 255 *cp = 'W'; 256 break; 257 258 case SLOCK: 259 *cp = 'L'; 260 break; 261 262 case SZOMB: 263 *cp = 'Z'; 264 break; 265 266 default: 267 *cp = '?'; 268 } 269 cp++; 270 if (!(flag & P_INMEM)) 271 *cp++ = 'W'; 272 if (k->ki_p->ki_nice < NZERO) 273 *cp++ = '<'; 274 else if (k->ki_p->ki_nice > NZERO) 275 *cp++ = 'N'; 276 if (flag & P_TRACED) 277 *cp++ = 'X'; 278 if (flag & P_WEXIT && k->ki_p->ki_stat != SZOMB) 279 *cp++ = 'E'; 280 if (flag & P_PPWAIT) 281 *cp++ = 'V'; 282 if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0) 283 *cp++ = 'L'; 284 if (k->ki_p->ki_kiflag & KI_SLEADER) 285 *cp++ = 's'; 286 if ((flag & P_CONTROLT) && k->ki_p->ki_pgid == k->ki_p->ki_tpgid) 287 *cp++ = '+'; 288 if (flag & P_JAILED) 289 *cp++ = 'J'; 290 *cp = '\0'; 291 return (buf); 292 } 293 294 #define scalepri(x) ((x) - PZERO) 295 296 char * 297 pri(KINFO *k, VARENT *ve) 298 { 299 VAR *v; 300 char *str; 301 302 v = ve->var; 303 asprintf(&str, "%d", scalepri(k->ki_p->ki_pri.pri_level)); 304 return (str); 305 } 306 307 char * 308 upr(KINFO *k, VARENT *ve) 309 { 310 VAR *v; 311 char *str; 312 313 v = ve->var; 314 asprintf(&str, "%d", scalepri(k->ki_p->ki_pri.pri_user)); 315 return (str); 316 } 317 #undef scalepri 318 319 char * 320 uname(KINFO *k, VARENT *ve) 321 { 322 VAR *v; 323 324 v = ve->var; 325 return (strdup(user_from_uid(k->ki_p->ki_uid, 0))); 326 } 327 328 char * 329 egroupname(KINFO *k, VARENT *ve) 330 { 331 VAR *v; 332 333 v = ve->var; 334 return (strdup(group_from_gid(k->ki_p->ki_groups[0], 0))); 335 } 336 337 char * 338 rgroupname(KINFO *k, VARENT *ve) 339 { 340 VAR *v; 341 342 v = ve->var; 343 return (strdup(group_from_gid(k->ki_p->ki_rgid, 0))); 344 } 345 346 char * 347 runame(KINFO *k, VARENT *ve) 348 { 349 VAR *v; 350 351 v = ve->var; 352 return (strdup(user_from_uid(k->ki_p->ki_ruid, 0))); 353 } 354 355 char * 356 tdev(KINFO *k, VARENT *ve) 357 { 358 VAR *v; 359 dev_t dev; 360 char *str; 361 362 v = ve->var; 363 dev = k->ki_p->ki_tdev; 364 if (dev == NODEV) 365 str = strdup("-"); 366 else 367 asprintf(&str, "%#jx", (uintmax_t)dev); 368 369 return (str); 370 } 371 372 char * 373 tname(KINFO *k, VARENT *ve) 374 { 375 VAR *v; 376 dev_t dev; 377 char *ttname, *str; 378 379 v = ve->var; 380 dev = k->ki_p->ki_tdev; 381 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 382 str = strdup("- "); 383 else { 384 if (strncmp(ttname, "tty", 3) == 0 || 385 strncmp(ttname, "cua", 3) == 0) 386 ttname += 3; 387 if (strncmp(ttname, "pts/", 4) == 0) 388 ttname += 4; 389 asprintf(&str, "%s%c", ttname, 390 k->ki_p->ki_kiflag & KI_CTTY ? ' ' : '-'); 391 } 392 393 return (str); 394 } 395 396 char * 397 longtname(KINFO *k, VARENT *ve) 398 { 399 VAR *v; 400 dev_t dev; 401 const char *ttname; 402 403 v = ve->var; 404 dev = k->ki_p->ki_tdev; 405 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 406 ttname = "-"; 407 408 return (strdup(ttname)); 409 } 410 411 char * 412 started(KINFO *k, VARENT *ve) 413 { 414 VAR *v; 415 time_t then; 416 struct tm *tp; 417 static int use_ampm = -1; 418 size_t buflen = 100; 419 char *buf; 420 421 buf = malloc(buflen); 422 if (buf == NULL) 423 errx(1, "malloc failed"); 424 425 v = ve->var; 426 if (!k->ki_valid) 427 return (NULL); 428 if (use_ampm < 0) 429 use_ampm = (*nl_langinfo(T_FMT_AMPM) != '\0'); 430 then = k->ki_p->ki_start.tv_sec; 431 tp = localtime(&then); 432 if (now - k->ki_p->ki_start.tv_sec < 24 * 3600) { 433 (void)strftime(buf, buflen, 434 use_ampm ? "%l:%M%p" : "%k:%M ", tp); 435 } else if (now - k->ki_p->ki_start.tv_sec < 7 * 86400) { 436 (void)strftime(buf, buflen, 437 use_ampm ? "%a%I%p" : "%a%H ", tp); 438 } else 439 (void)strftime(buf, buflen, "%e%b%y", tp); 440 return (buf); 441 } 442 443 char * 444 lstarted(KINFO *k, VARENT *ve) 445 { 446 VAR *v; 447 time_t then; 448 char *buf; 449 size_t buflen = 100; 450 451 buf = malloc(buflen); 452 if (buf == NULL) 453 errx(1, "malloc failed"); 454 455 v = ve->var; 456 if (!k->ki_valid) 457 return (NULL); 458 then = k->ki_p->ki_start.tv_sec; 459 (void)strftime(buf, buflen, "%c", localtime(&then)); 460 return (buf); 461 } 462 463 char * 464 lockname(KINFO *k, VARENT *ve) 465 { 466 VAR *v; 467 char *str; 468 469 v = ve->var; 470 if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { 471 if (k->ki_p->ki_lockname[0] != 0) 472 str = strdup(k->ki_p->ki_lockname); 473 else 474 str = strdup("???"); 475 } else 476 str = NULL; 477 478 return (str); 479 } 480 481 char * 482 wchan(KINFO *k, VARENT *ve) 483 { 484 VAR *v; 485 char *str; 486 487 v = ve->var; 488 if (k->ki_p->ki_wchan) { 489 if (k->ki_p->ki_wmesg[0] != 0) 490 str = strdup(k->ki_p->ki_wmesg); 491 else 492 asprintf(&str, "%lx", (long)k->ki_p->ki_wchan); 493 } else 494 str = NULL; 495 496 return (str); 497 } 498 499 char * 500 nwchan(KINFO *k, VARENT *ve) 501 { 502 VAR *v; 503 char *str; 504 505 v = ve->var; 506 if (k->ki_p->ki_wchan) 507 asprintf(&str, "%0lx", (long)k->ki_p->ki_wchan); 508 else 509 str = NULL; 510 511 return (str); 512 } 513 514 char * 515 mwchan(KINFO *k, VARENT *ve) 516 { 517 VAR *v; 518 char *str; 519 520 v = ve->var; 521 if (k->ki_p->ki_wchan) { 522 if (k->ki_p->ki_wmesg[0] != 0) 523 str = strdup(k->ki_p->ki_wmesg); 524 else 525 asprintf(&str, "%lx", (long)k->ki_p->ki_wchan); 526 } else if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { 527 if (k->ki_p->ki_lockname[0]) { 528 str = strdup(k->ki_p->ki_lockname); 529 } else 530 str = strdup("???"); 531 } else 532 str = NULL; 533 534 return (str); 535 } 536 537 char * 538 vsize(KINFO *k, VARENT *ve) 539 { 540 VAR *v; 541 char *str; 542 543 v = ve->var; 544 asprintf(&str, "%lu", (u_long)(k->ki_p->ki_size / 1024)); 545 return (str); 546 } 547 548 static char * 549 printtime(KINFO *k, VARENT *ve, long secs, long psecs) 550 /* psecs is "parts" of a second. first micro, then centi */ 551 { 552 VAR *v; 553 static char decimal_point; 554 char *str; 555 556 if (decimal_point == '\0') 557 decimal_point = localeconv()->decimal_point[0]; 558 v = ve->var; 559 if (!k->ki_valid) { 560 secs = 0; 561 psecs = 0; 562 } else { 563 /* round and scale to 100's */ 564 psecs = (psecs + 5000) / 10000; 565 secs += psecs / 100; 566 psecs = psecs % 100; 567 } 568 asprintf(&str, "%ld:%02ld%c%02ld", 569 secs / 60, secs % 60, decimal_point, psecs); 570 return (str); 571 } 572 573 char * 574 cputime(KINFO *k, VARENT *ve) 575 { 576 long secs, psecs; 577 578 /* 579 * This counts time spent handling interrupts. We could 580 * fix this, but it is not 100% trivial (and interrupt 581 * time fractions only work on the sparc anyway). XXX 582 */ 583 secs = k->ki_p->ki_runtime / 1000000; 584 psecs = k->ki_p->ki_runtime % 1000000; 585 if (sumrusage) { 586 secs += k->ki_p->ki_childtime.tv_sec; 587 psecs += k->ki_p->ki_childtime.tv_usec; 588 } 589 return (printtime(k, ve, secs, psecs)); 590 } 591 592 char * 593 systime(KINFO *k, VARENT *ve) 594 { 595 long secs, psecs; 596 597 secs = k->ki_p->ki_rusage.ru_stime.tv_sec; 598 psecs = k->ki_p->ki_rusage.ru_stime.tv_usec; 599 if (sumrusage) { 600 secs += k->ki_p->ki_childstime.tv_sec; 601 psecs += k->ki_p->ki_childstime.tv_usec; 602 } 603 return (printtime(k, ve, secs, psecs)); 604 } 605 606 char * 607 usertime(KINFO *k, VARENT *ve) 608 { 609 long secs, psecs; 610 611 secs = k->ki_p->ki_rusage.ru_utime.tv_sec; 612 psecs = k->ki_p->ki_rusage.ru_utime.tv_usec; 613 if (sumrusage) { 614 secs += k->ki_p->ki_childutime.tv_sec; 615 psecs += k->ki_p->ki_childutime.tv_usec; 616 } 617 return (printtime(k, ve, secs, psecs)); 618 } 619 620 char * 621 elapsed(KINFO *k, VARENT *ve) 622 { 623 VAR *v; 624 time_t val; 625 int days, hours, mins, secs; 626 char *str; 627 628 v = ve->var; 629 if (!k->ki_valid) 630 return (NULL); 631 val = now - k->ki_p->ki_start.tv_sec; 632 days = val / (24 * 60 * 60); 633 val %= 24 * 60 * 60; 634 hours = val / (60 * 60); 635 val %= 60 * 60; 636 mins = val / 60; 637 secs = val % 60; 638 if (days != 0) 639 asprintf(&str, "%3d-%02d:%02d:%02d", days, hours, mins, secs); 640 else if (hours != 0) 641 asprintf(&str, "%02d:%02d:%02d", hours, mins, secs); 642 else 643 asprintf(&str, "%02d:%02d", mins, secs); 644 645 return (str); 646 } 647 648 char * 649 elapseds(KINFO *k, VARENT *ve) 650 { 651 VAR *v; 652 time_t val; 653 char *str; 654 655 v = ve->var; 656 if (!k->ki_valid) 657 return (NULL); 658 val = now - k->ki_p->ki_start.tv_sec; 659 asprintf(&str, "%jd", (intmax_t)val); 660 return (str); 661 } 662 663 double 664 getpcpu(const KINFO *k) 665 { 666 static int failure; 667 668 if (!nlistread) 669 failure = donlist(); 670 if (failure) 671 return (0.0); 672 673 #define fxtofl(fixpt) ((double)(fixpt) / fscale) 674 675 /* XXX - I don't like this */ 676 if (k->ki_p->ki_swtime == 0 || (k->ki_p->ki_flag & P_INMEM) == 0) 677 return (0.0); 678 if (rawcpu) 679 return (100.0 * fxtofl(k->ki_p->ki_pctcpu)); 680 return (100.0 * fxtofl(k->ki_p->ki_pctcpu) / 681 (1.0 - exp(k->ki_p->ki_swtime * log(fxtofl(ccpu))))); 682 } 683 684 char * 685 pcpu(KINFO *k, VARENT *ve) 686 { 687 VAR *v; 688 char *str; 689 690 v = ve->var; 691 asprintf(&str, "%.1f", getpcpu(k)); 692 return (str); 693 } 694 695 static double 696 getpmem(KINFO *k) 697 { 698 static int failure; 699 double fracmem; 700 701 if (!nlistread) 702 failure = donlist(); 703 if (failure) 704 return (0.0); 705 706 if ((k->ki_p->ki_flag & P_INMEM) == 0) 707 return (0.0); 708 /* XXX want pmap ptpages, segtab, etc. (per architecture) */ 709 /* XXX don't have info about shared */ 710 fracmem = ((float)k->ki_p->ki_rssize) / mempages; 711 return (100.0 * fracmem); 712 } 713 714 char * 715 pmem(KINFO *k, VARENT *ve) 716 { 717 VAR *v; 718 char *str; 719 720 v = ve->var; 721 asprintf(&str, "%.1f", getpmem(k)); 722 return (str); 723 } 724 725 char * 726 pagein(KINFO *k, VARENT *ve) 727 { 728 VAR *v; 729 char *str; 730 731 v = ve->var; 732 asprintf(&str, "%ld", k->ki_valid ? k->ki_p->ki_rusage.ru_majflt : 0); 733 return (str); 734 } 735 736 /* ARGSUSED */ 737 char * 738 maxrss(KINFO *k __unused, VARENT *ve) 739 { 740 VAR *v; 741 742 v = ve->var; 743 /* XXX not yet */ 744 return (NULL); 745 } 746 747 char * 748 priorityr(KINFO *k, VARENT *ve) 749 { 750 VAR *v; 751 struct priority *lpri; 752 char *str; 753 unsigned class, level; 754 755 v = ve->var; 756 lpri = &k->ki_p->ki_pri; 757 class = lpri->pri_class; 758 level = lpri->pri_level; 759 switch (class) { 760 case PRI_ITHD: 761 asprintf(&str, "intr:%u", level); 762 break; 763 case PRI_REALTIME: 764 asprintf(&str, "real:%u", level); 765 break; 766 case PRI_TIMESHARE: 767 asprintf(&str, "normal"); 768 break; 769 case PRI_IDLE: 770 asprintf(&str, "idle:%u", level); 771 break; 772 default: 773 asprintf(&str, "%u:%u", class, level); 774 break; 775 } 776 return (str); 777 } 778 779 /* 780 * Generic output routines. Print fields from various prototype 781 * structures. 782 */ 783 static char * 784 printval(void *bp, VAR *v) 785 { 786 static char ofmt[32] = "%"; 787 const char *fcp; 788 char *cp, *str; 789 790 cp = ofmt + 1; 791 fcp = v->fmt; 792 while ((*cp++ = *fcp++)); 793 794 #define CHKINF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n)) 795 796 switch (v->type) { 797 case CHAR: 798 (void)asprintf(&str, ofmt, *(char *)bp); 799 break; 800 case UCHAR: 801 (void)asprintf(&str, ofmt, *(u_char *)bp); 802 break; 803 case SHORT: 804 (void)asprintf(&str, ofmt, *(short *)bp); 805 break; 806 case USHORT: 807 (void)asprintf(&str, ofmt, *(u_short *)bp); 808 break; 809 case INT: 810 (void)asprintf(&str, ofmt, *(int *)bp); 811 break; 812 case UINT: 813 (void)asprintf(&str, ofmt, CHKINF127(*(u_int *)bp)); 814 break; 815 case LONG: 816 (void)asprintf(&str, ofmt, *(long *)bp); 817 break; 818 case ULONG: 819 (void)asprintf(&str, ofmt, *(u_long *)bp); 820 break; 821 case KPTR: 822 (void)asprintf(&str, ofmt, *(u_long *)bp); 823 break; 824 case PGTOK: 825 (void)asprintf(&str, ofmt, ps_pgtok(*(u_long *)bp)); 826 break; 827 default: 828 errx(1, "unknown type %d", v->type); 829 } 830 831 return (str); 832 } 833 834 char * 835 kvar(KINFO *k, VARENT *ve) 836 { 837 VAR *v; 838 839 v = ve->var; 840 return (printval((char *)((char *)k->ki_p + v->off), v)); 841 } 842 843 char * 844 rvar(KINFO *k, VARENT *ve) 845 { 846 VAR *v; 847 848 v = ve->var; 849 if (!k->ki_valid) 850 return (NULL); 851 return (printval((char *)((char *)(&k->ki_p->ki_rusage) + v->off), v)); 852 } 853 854 char * 855 emulname(KINFO *k, VARENT *ve) 856 { 857 VAR *v; 858 859 v = ve->var; 860 if (k->ki_p->ki_emul == NULL) 861 return (NULL); 862 return (strdup(k->ki_p->ki_emul)); 863 } 864 865 char * 866 label(KINFO *k, VARENT *ve) 867 { 868 char *string; 869 VAR *v; 870 mac_t proclabel; 871 int error; 872 873 v = ve->var; 874 string = NULL; 875 if (mac_prepare_process_label(&proclabel) == -1) { 876 warn("mac_prepare_process_label"); 877 goto out; 878 } 879 error = mac_get_pid(k->ki_p->ki_pid, proclabel); 880 if (error == 0) { 881 if (mac_to_text(proclabel, &string) == -1) 882 string = NULL; 883 } 884 mac_free(proclabel); 885 out: 886 return (string); 887 } 888 889 char * 890 loginclass(KINFO *k, VARENT *ve) 891 { 892 VAR *v; 893 char *s; 894 895 v = ve->var; 896 /* 897 * Don't display login class for system processes; 898 * login classes are used for resource limits, 899 * and limits don't apply to system processes. 900 */ 901 if (k->ki_p->ki_flag & P_SYSTEM) { 902 return (strdup("-")); 903 } 904 s = k->ki_p->ki_loginclass; 905 if (s == NULL) 906 return (NULL); 907 return (strdup(s)); 908 } 909