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_ocomm); 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 + OCOMMLEN + 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_ocomm); 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_ocomm); 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_ocomm); 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 rgroupname(KINFO *k, VARENT *ve) 345 { 346 VAR *v; 347 348 v = ve->var; 349 (void)printf("%-*s", v->width, group_from_gid(k->ki_p->ki_rgid, 0)); 350 } 351 352 int 353 s_rgroupname(KINFO *k) 354 { 355 return (strlen(group_from_gid(k->ki_p->ki_rgid, 0))); 356 } 357 358 void 359 runame(KINFO *k, VARENT *ve) 360 { 361 VAR *v; 362 363 v = ve->var; 364 (void)printf("%-*s", v->width, user_from_uid(k->ki_p->ki_ruid, 0)); 365 } 366 367 int 368 s_runame(KINFO *k) 369 { 370 return (strlen(user_from_uid(k->ki_p->ki_ruid, 0))); 371 } 372 373 374 void 375 tdev(KINFO *k, VARENT *ve) 376 { 377 VAR *v; 378 dev_t dev; 379 char buff[16]; 380 381 v = ve->var; 382 dev = k->ki_p->ki_tdev; 383 if (dev == NODEV) 384 (void)printf("%*s", v->width, "??"); 385 else { 386 (void)snprintf(buff, sizeof(buff), 387 "%d/%d", major(dev), minor(dev)); 388 (void)printf("%*s", v->width, buff); 389 } 390 } 391 392 void 393 tname(KINFO *k, VARENT *ve) 394 { 395 VAR *v; 396 dev_t dev; 397 char *ttname; 398 399 v = ve->var; 400 dev = k->ki_p->ki_tdev; 401 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 402 (void)printf("%*s ", v->width - 1, "??"); 403 else { 404 if (strncmp(ttname, "tty", 3) == 0 || 405 strncmp(ttname, "cua", 3) == 0) 406 ttname += 3; 407 if (strncmp(ttname, "pts/", 4) == 0) 408 ttname += 4; 409 (void)printf("%*.*s%c", v->width - 1, v->width - 1, ttname, 410 k->ki_p->ki_kiflag & KI_CTTY ? ' ' : '-'); 411 } 412 } 413 414 void 415 longtname(KINFO *k, VARENT *ve) 416 { 417 VAR *v; 418 dev_t dev; 419 char *ttname; 420 421 v = ve->var; 422 dev = k->ki_p->ki_tdev; 423 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 424 (void)printf("%-*s", v->width, "??"); 425 else 426 (void)printf("%-*s", v->width, ttname); 427 } 428 429 void 430 started(KINFO *k, VARENT *ve) 431 { 432 VAR *v; 433 time_t then; 434 struct tm *tp; 435 static int use_ampm = -1; 436 char buf[100]; 437 438 v = ve->var; 439 if (!k->ki_valid) { 440 (void)printf("%-*s", v->width, "-"); 441 return; 442 } 443 if (use_ampm < 0) 444 use_ampm = (*nl_langinfo(T_FMT_AMPM) != '\0'); 445 then = k->ki_p->ki_start.tv_sec; 446 tp = localtime(&then); 447 if (now - k->ki_p->ki_start.tv_sec < 24 * 3600) { 448 (void)strftime(buf, sizeof(buf), 449 use_ampm ? "%l:%M%p" : "%k:%M ", tp); 450 } else if (now - k->ki_p->ki_start.tv_sec < 7 * 86400) { 451 (void)strftime(buf, sizeof(buf), 452 use_ampm ? "%a%I%p" : "%a%H ", tp); 453 } else 454 (void)strftime(buf, sizeof(buf), "%e%b%y", tp); 455 (void)printf("%-*s", v->width, buf); 456 } 457 458 void 459 lstarted(KINFO *k, VARENT *ve) 460 { 461 VAR *v; 462 time_t then; 463 char buf[100]; 464 465 v = ve->var; 466 if (!k->ki_valid) { 467 (void)printf("%-*s", v->width, "-"); 468 return; 469 } 470 then = k->ki_p->ki_start.tv_sec; 471 (void)strftime(buf, sizeof(buf), "%c", localtime(&then)); 472 (void)printf("%-*s", v->width, buf); 473 } 474 475 void 476 lockname(KINFO *k, VARENT *ve) 477 { 478 VAR *v; 479 480 v = ve->var; 481 if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { 482 if (k->ki_p->ki_lockname[0] != 0) 483 (void)printf("%-*.*s", v->width, v->width, 484 k->ki_p->ki_lockname); 485 else 486 (void)printf("%-*s", v->width, "???"); 487 } else 488 (void)printf("%-*s", v->width, "-"); 489 } 490 491 void 492 wchan(KINFO *k, VARENT *ve) 493 { 494 VAR *v; 495 496 v = ve->var; 497 if (k->ki_p->ki_wchan) { 498 if (k->ki_p->ki_wmesg[0] != 0) 499 (void)printf("%-*.*s", v->width, v->width, 500 k->ki_p->ki_wmesg); 501 else 502 (void)printf("%-*lx", v->width, 503 (long)k->ki_p->ki_wchan); 504 } else 505 (void)printf("%-*s", v->width, "-"); 506 } 507 508 void 509 nwchan(KINFO *k, VARENT *ve) 510 { 511 VAR *v; 512 513 v = ve->var; 514 if (k->ki_p->ki_wchan) { 515 (void)printf("%0*lx", v->width, 516 (long)k->ki_p->ki_wchan); 517 } else 518 (void)printf("%-*s", v->width, "-"); 519 } 520 521 void 522 mwchan(KINFO *k, VARENT *ve) 523 { 524 VAR *v; 525 526 v = ve->var; 527 if (k->ki_p->ki_wchan) { 528 if (k->ki_p->ki_wmesg[0] != 0) 529 (void)printf("%-*.*s", v->width, v->width, 530 k->ki_p->ki_wmesg); 531 else 532 (void)printf("%-*lx", v->width, 533 (long)k->ki_p->ki_wchan); 534 } else if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { 535 if (k->ki_p->ki_lockname[0]) { 536 (void)printf("%-*.*s", v->width, v->width, 537 k->ki_p->ki_lockname); 538 } else 539 (void)printf("%-*s", v->width, "???"); 540 } else 541 (void)printf("%-*s", v->width, "-"); 542 } 543 544 void 545 vsize(KINFO *k, VARENT *ve) 546 { 547 VAR *v; 548 549 v = ve->var; 550 (void)printf("%*lu", v->width, (u_long)(k->ki_p->ki_size / 1024)); 551 } 552 553 static void 554 printtime(KINFO *k, VARENT *ve, long secs, long psecs) 555 /* psecs is "parts" of a second. first micro, then centi */ 556 { 557 VAR *v; 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 /* round and scale to 100's */ 569 psecs = (psecs + 5000) / 10000; 570 secs += psecs / 100; 571 psecs = psecs % 100; 572 } 573 (void)snprintf(obuff, sizeof(obuff), "%ld:%02ld%c%02ld", 574 secs / 60, secs % 60, decimal_point, psecs); 575 (void)printf("%*s", v->width, obuff); 576 } 577 578 static int 579 sizetime(long secs) 580 { 581 582 if (secs < 60) 583 return (7); 584 return (log10(secs / 60) + 7); 585 } 586 587 void 588 cputime(KINFO *k, VARENT *ve) 589 { 590 long secs, psecs; 591 592 /* 593 * This counts time spent handling interrupts. We could 594 * fix this, but it is not 100% trivial (and interrupt 595 * time fractions only work on the sparc anyway). XXX 596 */ 597 secs = k->ki_p->ki_runtime / 1000000; 598 psecs = k->ki_p->ki_runtime % 1000000; 599 if (sumrusage) { 600 secs += k->ki_p->ki_childtime.tv_sec; 601 psecs += k->ki_p->ki_childtime.tv_usec; 602 } 603 printtime(k, ve, secs, psecs); 604 } 605 606 void 607 systime(KINFO *k, VARENT *ve) 608 { 609 long secs, psecs; 610 611 secs = k->ki_p->ki_rusage.ru_stime.tv_sec; 612 psecs = k->ki_p->ki_rusage.ru_stime.tv_usec; 613 if (sumrusage) { 614 secs += k->ki_p->ki_childstime.tv_sec; 615 psecs += k->ki_p->ki_childstime.tv_usec; 616 } 617 printtime(k, ve, secs, psecs); 618 } 619 620 void 621 usertime(KINFO *k, VARENT *ve) 622 { 623 long secs, psecs; 624 625 secs = k->ki_p->ki_rusage.ru_utime.tv_sec; 626 psecs = k->ki_p->ki_rusage.ru_utime.tv_usec; 627 if (sumrusage) { 628 secs += k->ki_p->ki_childutime.tv_sec; 629 psecs += k->ki_p->ki_childutime.tv_usec; 630 } 631 printtime(k, ve, secs, psecs); 632 } 633 634 void 635 elapsed(KINFO *k, VARENT *ve) 636 { 637 VAR *v; 638 time_t val; 639 int days, hours, mins, secs; 640 char obuff[128]; 641 642 v = ve->var; 643 if (!k->ki_valid) { 644 (void)printf("%-*s", v->width, "-"); 645 return; 646 } 647 val = now - k->ki_p->ki_start.tv_sec; 648 days = val / (24 * 60 * 60); 649 val %= 24 * 60 * 60; 650 hours = val / (60 * 60); 651 val %= 60 * 60; 652 mins = val / 60; 653 secs = val % 60; 654 if (days != 0) 655 (void)snprintf(obuff, sizeof(obuff), "%3d-%02d:%02d:%02d", 656 days, hours, mins, secs); 657 else if (hours != 0) 658 (void)snprintf(obuff, sizeof(obuff), "%02d:%02d:%02d", 659 hours, mins, secs); 660 else 661 (void)snprintf(obuff, sizeof(obuff), "%02d:%02d", mins, secs); 662 (void)printf("%*s", v->width, obuff); 663 } 664 665 void 666 elapseds(KINFO *k, VARENT *ve) 667 { 668 VAR *v; 669 time_t val; 670 671 v = ve->var; 672 if (!k->ki_valid) { 673 (void)printf("%-*s", v->width, "-"); 674 return; 675 } 676 val = now - k->ki_p->ki_start.tv_sec; 677 (void)printf("%*jd", v->width, (intmax_t)val); 678 } 679 680 double 681 getpcpu(const KINFO *k) 682 { 683 static int failure; 684 685 if (!nlistread) 686 failure = donlist(); 687 if (failure) 688 return (0.0); 689 690 #define fxtofl(fixpt) ((double)(fixpt) / fscale) 691 692 /* XXX - I don't like this */ 693 if (k->ki_p->ki_swtime == 0 || (k->ki_p->ki_flag & P_INMEM) == 0) 694 return (0.0); 695 if (rawcpu) 696 return (100.0 * fxtofl(k->ki_p->ki_pctcpu)); 697 return (100.0 * fxtofl(k->ki_p->ki_pctcpu) / 698 (1.0 - exp(k->ki_p->ki_swtime * log(fxtofl(ccpu))))); 699 } 700 701 void 702 pcpu(KINFO *k, VARENT *ve) 703 { 704 VAR *v; 705 706 v = ve->var; 707 (void)printf("%*.1f", v->width, getpcpu(k)); 708 } 709 710 static double 711 getpmem(KINFO *k) 712 { 713 static int failure; 714 double fracmem; 715 716 if (!nlistread) 717 failure = donlist(); 718 if (failure) 719 return (0.0); 720 721 if ((k->ki_p->ki_flag & P_INMEM) == 0) 722 return (0.0); 723 /* XXX want pmap ptpages, segtab, etc. (per architecture) */ 724 /* XXX don't have info about shared */ 725 fracmem = ((float)k->ki_p->ki_rssize) / mempages; 726 return (100.0 * fracmem); 727 } 728 729 void 730 pmem(KINFO *k, VARENT *ve) 731 { 732 VAR *v; 733 734 v = ve->var; 735 (void)printf("%*.1f", v->width, getpmem(k)); 736 } 737 738 void 739 pagein(KINFO *k, VARENT *ve) 740 { 741 VAR *v; 742 743 v = ve->var; 744 (void)printf("%*ld", v->width, 745 k->ki_valid ? k->ki_p->ki_rusage.ru_majflt : 0); 746 } 747 748 /* ARGSUSED */ 749 void 750 maxrss(KINFO *k __unused, VARENT *ve) 751 { 752 VAR *v; 753 754 v = ve->var; 755 /* XXX not yet */ 756 (void)printf("%*s", v->width, "-"); 757 } 758 759 void 760 priorityr(KINFO *k, VARENT *ve) 761 { 762 VAR *v; 763 struct priority *lpri; 764 char str[8]; 765 unsigned class, level; 766 767 v = ve->var; 768 lpri = &k->ki_p->ki_pri; 769 class = lpri->pri_class; 770 level = lpri->pri_level; 771 switch (class) { 772 case PRI_ITHD: 773 snprintf(str, sizeof(str), "intr:%u", level); 774 break; 775 case PRI_REALTIME: 776 snprintf(str, sizeof(str), "real:%u", level); 777 break; 778 case PRI_TIMESHARE: 779 strncpy(str, "normal", sizeof(str)); 780 break; 781 case PRI_IDLE: 782 snprintf(str, sizeof(str), "idle:%u", level); 783 break; 784 default: 785 snprintf(str, sizeof(str), "%u:%u", class, level); 786 break; 787 } 788 str[sizeof(str) - 1] = '\0'; 789 (void)printf("%*s", v->width, str); 790 } 791 792 /* 793 * Generic output routines. Print fields from various prototype 794 * structures. 795 */ 796 static void 797 printval(void *bp, VAR *v) 798 { 799 static char ofmt[32] = "%"; 800 const char *fcp; 801 char *cp; 802 803 cp = ofmt + 1; 804 fcp = v->fmt; 805 if (v->flag & LJUST) 806 *cp++ = '-'; 807 *cp++ = '*'; 808 while ((*cp++ = *fcp++)); 809 810 #define CHKINF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n)) 811 812 switch (v->type) { 813 case CHAR: 814 (void)printf(ofmt, v->width, *(char *)bp); 815 break; 816 case UCHAR: 817 (void)printf(ofmt, v->width, *(u_char *)bp); 818 break; 819 case SHORT: 820 (void)printf(ofmt, v->width, *(short *)bp); 821 break; 822 case USHORT: 823 (void)printf(ofmt, v->width, *(u_short *)bp); 824 break; 825 case INT: 826 (void)printf(ofmt, v->width, *(int *)bp); 827 break; 828 case UINT: 829 (void)printf(ofmt, v->width, CHKINF127(*(u_int *)bp)); 830 break; 831 case LONG: 832 (void)printf(ofmt, v->width, *(long *)bp); 833 break; 834 case ULONG: 835 (void)printf(ofmt, v->width, *(u_long *)bp); 836 break; 837 case KPTR: 838 (void)printf(ofmt, v->width, *(u_long *)bp); 839 break; 840 case PGTOK: 841 (void)printf(ofmt, v->width, ps_pgtok(*(u_long *)bp)); 842 break; 843 default: 844 errx(1, "unknown type %d", v->type); 845 } 846 } 847 848 void 849 kvar(KINFO *k, VARENT *ve) 850 { 851 VAR *v; 852 853 v = ve->var; 854 printval((char *)((char *)k->ki_p + v->off), v); 855 } 856 857 void 858 rvar(KINFO *k, VARENT *ve) 859 { 860 VAR *v; 861 862 v = ve->var; 863 if (k->ki_valid) 864 printval((char *)((char *)(&k->ki_p->ki_rusage) + v->off), v); 865 else 866 (void)printf("%*s", v->width, "-"); 867 } 868 869 void 870 emulname(KINFO *k, VARENT *ve) 871 { 872 VAR *v; 873 874 v = ve->var; 875 printf("%-*s", v->width, *k->ki_p->ki_emul ? k->ki_p->ki_emul : "-"); 876 } 877 878 void 879 label(KINFO *k, VARENT *ve) 880 { 881 char *string; 882 VAR *v; 883 mac_t proclabel; 884 int error; 885 886 v = ve->var; 887 string = NULL; 888 if (mac_prepare_process_label(&proclabel) == -1) { 889 warn("mac_prepare_process_label"); 890 goto out; 891 } 892 error = mac_get_pid(k->ki_p->ki_pid, proclabel); 893 if (error == 0) { 894 if (mac_to_text(proclabel, &string) == -1) 895 string = NULL; 896 } 897 mac_free(proclabel); 898 out: 899 if (string != NULL) { 900 (void)printf("%-*s", v->width, string); 901 free(string); 902 } else 903 (void)printf("%-*s", v->width, " -"); 904 return; 905 } 906 907 void 908 loginclass(KINFO *k, VARENT *ve) 909 { 910 VAR *v; 911 char *s; 912 913 v = ve->var; 914 /* 915 * Don't display login class for system processes; 916 * login classes are used for resource limits, 917 * and limits don't apply to system processes. 918 */ 919 if (k->ki_p->ki_flag & P_SYSTEM) { 920 (void)printf("%-*s", v->width, "-"); 921 return; 922 } 923 s = k->ki_p->ki_loginclass; 924 (void)printf("%-*s", v->width, *s ? s : "-"); 925 } 926 927 int 928 s_comm(KINFO *k) 929 { 930 char tmpbuff[COMMLEN + OCOMMLEN + 2]; 931 932 bzero(tmpbuff, sizeof(tmpbuff)); 933 if (showthreads && k->ki_p->ki_numthreads > 1) 934 sprintf(tmpbuff, "%s/%s", k->ki_p->ki_comm, 935 k->ki_p->ki_ocomm); 936 else 937 sprintf(tmpbuff, "%s", k->ki_p->ki_comm); 938 return (strlen(tmpbuff)); 939 } 940 941 int 942 s_cputime(KINFO *k) 943 { 944 long secs; 945 946 secs = k->ki_p->ki_runtime / 1000000; 947 if (sumrusage) 948 secs += k->ki_p->ki_childtime.tv_sec; 949 return (sizetime(secs)); 950 } 951 952 int 953 s_label(KINFO *k) 954 { 955 char *string = NULL; 956 mac_t proclabel; 957 int error, size = 0; 958 959 if (mac_prepare_process_label(&proclabel) == -1) { 960 warn("mac_prepare_process_label"); 961 return (0); 962 } 963 error = mac_get_pid(k->ki_p->ki_pid, proclabel); 964 if (error == 0 && mac_to_text(proclabel, &string) == 0) { 965 size = strlen(string); 966 free(string); 967 } 968 mac_free(proclabel); 969 return (size); 970 } 971 972 int 973 s_loginclass(KINFO *k) 974 { 975 char *s; 976 977 if (k->ki_p->ki_flag & P_SYSTEM) 978 return (1); 979 980 s = k->ki_p->ki_loginclass; 981 if (s == NULL) 982 return (1); 983 984 return (strlen(s)); 985 } 986 987 int 988 s_logname(KINFO *k) 989 { 990 char *s; 991 992 s = k->ki_p->ki_login; 993 if (s == NULL) 994 return (1); 995 996 return (strlen(s)); 997 } 998 999 int 1000 s_systime(KINFO *k) 1001 { 1002 long secs; 1003 1004 secs = k->ki_p->ki_rusage.ru_stime.tv_sec; 1005 if (sumrusage) 1006 secs += k->ki_p->ki_childstime.tv_sec; 1007 return (sizetime(secs)); 1008 } 1009 1010 int 1011 s_usertime(KINFO *k) 1012 { 1013 long secs; 1014 1015 secs = k->ki_p->ki_rusage.ru_utime.tv_sec; 1016 if (sumrusage) 1017 secs += k->ki_p->ki_childutime.tv_sec; 1018 return (sizetime(secs)); 1019 } 1020