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