print.c revision 331471
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 32static 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: stable/10/bin/ps/print.c 331471 2018-03-24 00:26:42Z jhb $"); 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 <jail.h> 53#include <langinfo.h> 54#include <locale.h> 55#include <math.h> 56#include <nlist.h> 57#include <pwd.h> 58#include <stddef.h> 59#include <stdint.h> 60#include <stdio.h> 61#include <stdlib.h> 62#include <string.h> 63#include <unistd.h> 64#include <vis.h> 65 66#include "ps.h" 67 68#define COMMAND_WIDTH 16 69#define ARGUMENTS_WIDTH 16 70 71#define ps_pgtok(a) (((a) * getpagesize()) / 1024) 72 73void 74printheader(void) 75{ 76 VAR *v; 77 struct varent *vent; 78 79 STAILQ_FOREACH(vent, &varlist, next_ve) 80 if (*vent->header != '\0') 81 break; 82 if (!vent) 83 return; 84 85 STAILQ_FOREACH(vent, &varlist, next_ve) { 86 v = vent->var; 87 if (v->flag & LJUST) { 88 if (STAILQ_NEXT(vent, next_ve) == NULL) /* last one */ 89 (void)printf("%s", vent->header); 90 else 91 (void)printf("%-*s", v->width, vent->header); 92 } else 93 (void)printf("%*s", v->width, vent->header); 94 if (STAILQ_NEXT(vent, next_ve) != NULL) 95 (void)putchar(' '); 96 } 97 (void)putchar('\n'); 98} 99 100char * 101arguments(KINFO *k, VARENT *ve) 102{ 103 char *vis_args; 104 105 if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) 106 errx(1, "malloc failed"); 107 strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); 108 109 if (STAILQ_NEXT(ve, next_ve) != NULL && strlen(vis_args) > ARGUMENTS_WIDTH) 110 vis_args[ARGUMENTS_WIDTH] = '\0'; 111 112 return (vis_args); 113} 114 115char * 116command(KINFO *k, VARENT *ve) 117{ 118 char *vis_args, *vis_env, *str; 119 120 if (cflag) { 121 /* If it is the last field, then don't pad */ 122 if (STAILQ_NEXT(ve, next_ve) == NULL) { 123 asprintf(&str, "%s%s%s%s%s", 124 k->ki_d.prefix ? k->ki_d.prefix : "", 125 k->ki_p->ki_comm, 126 (showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "", 127 (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : "", 128 (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_moretdname : ""); 129 } else 130 str = strdup(k->ki_p->ki_comm); 131 132 return (str); 133 } 134 if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) 135 errx(1, "malloc failed"); 136 strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); 137 138 if (STAILQ_NEXT(ve, next_ve) == NULL) { 139 /* last field */ 140 141 if (k->ki_env) { 142 if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) 143 == NULL) 144 errx(1, "malloc failed"); 145 strvis(vis_env, k->ki_env, 146 VIS_TAB | VIS_NL | VIS_NOSLASH); 147 } else 148 vis_env = NULL; 149 150 asprintf(&str, "%s%s%s%s", 151 k->ki_d.prefix ? k->ki_d.prefix : "", 152 vis_env ? vis_env : "", 153 vis_env ? " " : "", 154 vis_args); 155 156 if (vis_env != NULL) 157 free(vis_env); 158 free(vis_args); 159 } else { 160 /* ki_d.prefix & ki_env aren't shown for interim fields */ 161 str = vis_args; 162 163 if (strlen(str) > COMMAND_WIDTH) 164 str[COMMAND_WIDTH] = '\0'; 165 } 166 167 return (str); 168} 169 170char * 171ucomm(KINFO *k, VARENT *ve) 172{ 173 char *str; 174 175 if (STAILQ_NEXT(ve, next_ve) == NULL) { /* last field, don't pad */ 176 asprintf(&str, "%s%s%s%s%s", 177 k->ki_d.prefix ? k->ki_d.prefix : "", 178 k->ki_p->ki_comm, 179 (showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "", 180 (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : "", 181 (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_moretdname : ""); 182 } else { 183 if (showthreads && k->ki_p->ki_numthreads > 1) 184 asprintf(&str, "%s/%s%s", k->ki_p->ki_comm, 185 k->ki_p->ki_tdname, k->ki_p->ki_moretdname); 186 else 187 str = strdup(k->ki_p->ki_comm); 188 } 189 return (str); 190} 191 192char * 193tdnam(KINFO *k, VARENT *ve __unused) 194{ 195 char *str; 196 197 if (showthreads && k->ki_p->ki_numthreads > 1) 198 asprintf(&str, "%s%s", k->ki_p->ki_tdname, 199 k->ki_p->ki_moretdname); 200 else 201 str = strdup(" "); 202 203 return (str); 204} 205 206char * 207logname(KINFO *k, VARENT *ve __unused) 208{ 209 210 if (*k->ki_p->ki_login == '\0') 211 return (NULL); 212 return (strdup(k->ki_p->ki_login)); 213} 214 215char * 216state(KINFO *k, VARENT *ve __unused) 217{ 218 int flag, tdflags; 219 char *cp, *buf; 220 221 buf = malloc(16); 222 if (buf == NULL) 223 errx(1, "malloc failed"); 224 225 flag = k->ki_p->ki_flag; 226 tdflags = k->ki_p->ki_tdflags; /* XXXKSE */ 227 cp = buf; 228 229 switch (k->ki_p->ki_stat) { 230 231 case SSTOP: 232 *cp = 'T'; 233 break; 234 235 case SSLEEP: 236 if (tdflags & TDF_SINTR) /* interruptable (long) */ 237 *cp = k->ki_p->ki_slptime >= MAXSLP ? 'I' : 'S'; 238 else 239 *cp = 'D'; 240 break; 241 242 case SRUN: 243 case SIDL: 244 *cp = 'R'; 245 break; 246 247 case SWAIT: 248 *cp = 'W'; 249 break; 250 251 case SLOCK: 252 *cp = 'L'; 253 break; 254 255 case SZOMB: 256 *cp = 'Z'; 257 break; 258 259 default: 260 *cp = '?'; 261 } 262 cp++; 263 if (!(flag & P_INMEM)) 264 *cp++ = 'W'; 265 if (k->ki_p->ki_nice < NZERO) 266 *cp++ = '<'; 267 else if (k->ki_p->ki_nice > NZERO) 268 *cp++ = 'N'; 269 if (flag & P_TRACED) 270 *cp++ = 'X'; 271 if (flag & P_WEXIT && k->ki_p->ki_stat != SZOMB) 272 *cp++ = 'E'; 273 if (flag & P_PPWAIT) 274 *cp++ = 'V'; 275 if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0) 276 *cp++ = 'L'; 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 289char * 290pri(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 298char * 299upr(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 308char * 309uname(KINFO *k, VARENT *ve __unused) 310{ 311 312 return (strdup(user_from_uid(k->ki_p->ki_uid, 0))); 313} 314 315char * 316egroupname(KINFO *k, VARENT *ve __unused) 317{ 318 319 return (strdup(group_from_gid(k->ki_p->ki_groups[0], 0))); 320} 321 322char * 323rgroupname(KINFO *k, VARENT *ve __unused) 324{ 325 326 return (strdup(group_from_gid(k->ki_p->ki_rgid, 0))); 327} 328 329char * 330runame(KINFO *k, VARENT *ve __unused) 331{ 332 333 return (strdup(user_from_uid(k->ki_p->ki_ruid, 0))); 334} 335 336char * 337tdev(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 351char * 352tname(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 373char * 374longtname(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 386char * 387started(KINFO *k, VARENT *ve __unused) 388{ 389 time_t then; 390 struct tm *tp; 391 static int use_ampm = -1; 392 size_t buflen = 100; 393 char *buf; 394 395 if (!k->ki_valid) 396 return (NULL); 397 398 buf = malloc(buflen); 399 if (buf == NULL) 400 errx(1, "malloc failed"); 401 402 if (use_ampm < 0) 403 use_ampm = (*nl_langinfo(T_FMT_AMPM) != '\0'); 404 then = k->ki_p->ki_start.tv_sec; 405 tp = localtime(&then); 406 if (now - k->ki_p->ki_start.tv_sec < 24 * 3600) { 407 (void)strftime(buf, buflen, 408 use_ampm ? "%l:%M%p" : "%k:%M ", tp); 409 } else if (now - k->ki_p->ki_start.tv_sec < 7 * 86400) { 410 (void)strftime(buf, buflen, 411 use_ampm ? "%a%I%p" : "%a%H ", tp); 412 } else 413 (void)strftime(buf, buflen, "%e%b%y", tp); 414 return (buf); 415} 416 417char * 418lstarted(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 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 436char * 437lockname(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 452char * 453wchan(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 468char * 469nwchan(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 481char * 482mwchan(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 502char * 503vsize(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 511static char * 512printtime(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 534char * 535cputime(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 553char * 554systime(KINFO *k, VARENT *ve) 555{ 556 long secs, psecs; 557 558 secs = k->ki_p->ki_rusage.ru_stime.tv_sec; 559 psecs = k->ki_p->ki_rusage.ru_stime.tv_usec; 560 if (sumrusage) { 561 secs += k->ki_p->ki_childstime.tv_sec; 562 psecs += k->ki_p->ki_childstime.tv_usec; 563 } 564 return (printtime(k, ve, secs, psecs)); 565} 566 567char * 568usertime(KINFO *k, VARENT *ve) 569{ 570 long secs, psecs; 571 572 secs = k->ki_p->ki_rusage.ru_utime.tv_sec; 573 psecs = k->ki_p->ki_rusage.ru_utime.tv_usec; 574 if (sumrusage) { 575 secs += k->ki_p->ki_childutime.tv_sec; 576 psecs += k->ki_p->ki_childutime.tv_usec; 577 } 578 return (printtime(k, ve, secs, psecs)); 579} 580 581char * 582elapsed(KINFO *k, VARENT *ve __unused) 583{ 584 time_t val; 585 int days, hours, mins, secs; 586 char *str; 587 588 if (!k->ki_valid) 589 return (NULL); 590 val = now - k->ki_p->ki_start.tv_sec; 591 days = val / (24 * 60 * 60); 592 val %= 24 * 60 * 60; 593 hours = val / (60 * 60); 594 val %= 60 * 60; 595 mins = val / 60; 596 secs = val % 60; 597 if (days != 0) 598 asprintf(&str, "%3d-%02d:%02d:%02d", days, hours, mins, secs); 599 else if (hours != 0) 600 asprintf(&str, "%02d:%02d:%02d", hours, mins, secs); 601 else 602 asprintf(&str, "%02d:%02d", mins, secs); 603 604 return (str); 605} 606 607char * 608elapseds(KINFO *k, VARENT *ve __unused) 609{ 610 time_t val; 611 char *str; 612 613 if (!k->ki_valid) 614 return (NULL); 615 val = now - k->ki_p->ki_start.tv_sec; 616 asprintf(&str, "%jd", (intmax_t)val); 617 return (str); 618} 619 620double 621getpcpu(const KINFO *k) 622{ 623 static int failure; 624 625 if (!nlistread) 626 failure = donlist(); 627 if (failure) 628 return (0.0); 629 630#define fxtofl(fixpt) ((double)(fixpt) / fscale) 631 632 /* XXX - I don't like this */ 633 if (k->ki_p->ki_swtime == 0 || (k->ki_p->ki_flag & P_INMEM) == 0) 634 return (0.0); 635 if (rawcpu) 636 return (100.0 * fxtofl(k->ki_p->ki_pctcpu)); 637 return (100.0 * fxtofl(k->ki_p->ki_pctcpu) / 638 (1.0 - exp(k->ki_p->ki_swtime * log(fxtofl(ccpu))))); 639} 640 641char * 642pcpu(KINFO *k, VARENT *ve __unused) 643{ 644 char *str; 645 646 asprintf(&str, "%.1f", getpcpu(k)); 647 return (str); 648} 649 650static double 651getpmem(KINFO *k) 652{ 653 static int failure; 654 double fracmem; 655 656 if (!nlistread) 657 failure = donlist(); 658 if (failure) 659 return (0.0); 660 661 if ((k->ki_p->ki_flag & P_INMEM) == 0) 662 return (0.0); 663 /* XXX want pmap ptpages, segtab, etc. (per architecture) */ 664 /* XXX don't have info about shared */ 665 fracmem = ((float)k->ki_p->ki_rssize) / mempages; 666 return (100.0 * fracmem); 667} 668 669char * 670pmem(KINFO *k, VARENT *ve __unused) 671{ 672 char *str; 673 674 asprintf(&str, "%.1f", getpmem(k)); 675 return (str); 676} 677 678char * 679pagein(KINFO *k, VARENT *ve __unused) 680{ 681 char *str; 682 683 asprintf(&str, "%ld", k->ki_valid ? k->ki_p->ki_rusage.ru_majflt : 0); 684 return (str); 685} 686 687/* ARGSUSED */ 688char * 689maxrss(KINFO *k __unused, VARENT *ve __unused) 690{ 691 692 /* XXX not yet */ 693 return (NULL); 694} 695 696char * 697priorityr(KINFO *k, VARENT *ve __unused) 698{ 699 struct priority *lpri; 700 char *str; 701 unsigned class, level; 702 703 lpri = &k->ki_p->ki_pri; 704 class = lpri->pri_class; 705 level = lpri->pri_level; 706 switch (class) { 707 case PRI_ITHD: 708 asprintf(&str, "intr:%u", level); 709 break; 710 case PRI_REALTIME: 711 asprintf(&str, "real:%u", level); 712 break; 713 case PRI_TIMESHARE: 714 asprintf(&str, "normal"); 715 break; 716 case PRI_IDLE: 717 asprintf(&str, "idle:%u", level); 718 break; 719 default: 720 asprintf(&str, "%u:%u", class, level); 721 break; 722 } 723 return (str); 724} 725 726/* 727 * Generic output routines. Print fields from various prototype 728 * structures. 729 */ 730static char * 731printval(void *bp, VAR *v) 732{ 733 static char ofmt[32] = "%"; 734 const char *fcp; 735 char *cp, *str; 736 737 cp = ofmt + 1; 738 fcp = v->fmt; 739 while ((*cp++ = *fcp++)); 740 741#define CHKINF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n)) 742 743 switch (v->type) { 744 case CHAR: 745 (void)asprintf(&str, ofmt, *(char *)bp); 746 break; 747 case UCHAR: 748 (void)asprintf(&str, ofmt, *(u_char *)bp); 749 break; 750 case SHORT: 751 (void)asprintf(&str, ofmt, *(short *)bp); 752 break; 753 case USHORT: 754 (void)asprintf(&str, ofmt, *(u_short *)bp); 755 break; 756 case INT: 757 (void)asprintf(&str, ofmt, *(int *)bp); 758 break; 759 case UINT: 760 (void)asprintf(&str, ofmt, CHKINF127(*(u_int *)bp)); 761 break; 762 case LONG: 763 (void)asprintf(&str, ofmt, *(long *)bp); 764 break; 765 case ULONG: 766 (void)asprintf(&str, ofmt, *(u_long *)bp); 767 break; 768 case KPTR: 769 (void)asprintf(&str, ofmt, *(u_long *)bp); 770 break; 771 case PGTOK: 772 (void)asprintf(&str, ofmt, ps_pgtok(*(u_long *)bp)); 773 break; 774 default: 775 errx(1, "unknown type %d", v->type); 776 } 777 778 return (str); 779} 780 781char * 782kvar(KINFO *k, VARENT *ve) 783{ 784 VAR *v; 785 786 v = ve->var; 787 return (printval((char *)((char *)k->ki_p + v->off), v)); 788} 789 790char * 791rvar(KINFO *k, VARENT *ve) 792{ 793 VAR *v; 794 795 v = ve->var; 796 if (!k->ki_valid) 797 return (NULL); 798 return (printval((char *)((char *)(&k->ki_p->ki_rusage) + v->off), v)); 799} 800 801char * 802emulname(KINFO *k, VARENT *ve __unused) 803{ 804 805 return (strdup(k->ki_p->ki_emul)); 806} 807 808char * 809label(KINFO *k, VARENT *ve __unused) 810{ 811 char *string; 812 mac_t proclabel; 813 int error; 814 815 string = NULL; 816 if (mac_prepare_process_label(&proclabel) == -1) { 817 warn("mac_prepare_process_label"); 818 goto out; 819 } 820 error = mac_get_pid(k->ki_p->ki_pid, proclabel); 821 if (error == 0) { 822 if (mac_to_text(proclabel, &string) == -1) 823 string = NULL; 824 } 825 mac_free(proclabel); 826out: 827 return (string); 828} 829 830char * 831loginclass(KINFO *k, VARENT *ve __unused) 832{ 833 834 /* 835 * Don't display login class for system processes; 836 * login classes are used for resource limits, 837 * and limits don't apply to system processes. 838 */ 839 if (k->ki_p->ki_flag & P_SYSTEM) { 840 return (strdup("-")); 841 } 842 return (strdup(k->ki_p->ki_loginclass)); 843} 844 845char * 846jailname(KINFO *k, VARENT *ve __unused) 847{ 848 char *name; 849 850 if (k->ki_p->ki_jid == 0) 851 return (strdup("-")); 852 name = jail_getname(k->ki_p->ki_jid); 853 if (name == NULL) 854 return (strdup("-")); 855 return (name); 856} 857