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