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