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