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