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 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #if 0 35 #ifndef lint 36 static char sccsid[] = "@(#)print.c 8.6 (Berkeley) 4/16/94"; 37 #endif /* not lint */ 38 #endif 39 40 #include <sys/cdefs.h> 41 __FBSDID("$FreeBSD$"); 42 43 #include <sys/param.h> 44 #include <sys/time.h> 45 #include <sys/resource.h> 46 #include <sys/proc.h> 47 #include <sys/stat.h> 48 49 #include <sys/mac.h> 50 #include <sys/user.h> 51 #include <sys/sysctl.h> 52 53 #include <err.h> 54 #include <grp.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 <stdio.h> 62 #include <stdlib.h> 63 #include <string.h> 64 #include <unistd.h> 65 #include <vis.h> 66 67 #include "ps.h" 68 69 #define ps_pgtok(a) (((a) * getpagesize()) / 1024) 70 71 void 72 printheader(void) 73 { 74 VAR *v; 75 struct varent *vent; 76 int allempty; 77 78 allempty = 1; 79 for (vent = vhead; vent; vent = vent->next) 80 if (*vent->header != '\0') { 81 allempty = 0; 82 break; 83 } 84 if (allempty) 85 return; 86 for (vent = vhead; vent; vent = vent->next) { 87 v = vent->var; 88 if (v->flag & LJUST) { 89 if (vent->next == NULL) /* last one */ 90 (void)printf("%s", vent->header); 91 else 92 (void)printf("%-*s", v->width, vent->header); 93 } else 94 (void)printf("%*s", v->width, vent->header); 95 if (vent->next != NULL) 96 (void)putchar(' '); 97 } 98 (void)putchar('\n'); 99 } 100 101 void 102 arguments(KINFO *k, VARENT *ve) 103 { 104 VAR *v; 105 int left; 106 char *cp, *vis_args; 107 108 v = ve->var; 109 if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) 110 errx(1, "malloc failed"); 111 strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); 112 if (ve->next == NULL) { 113 /* last field */ 114 if (termwidth == UNLIMITED) { 115 (void)printf("%s", vis_args); 116 } else { 117 left = termwidth - (totwidth - v->width); 118 if (left < 1) /* already wrapped, just use std width */ 119 left = v->width; 120 for (cp = vis_args; --left >= 0 && *cp != '\0';) 121 (void)putchar(*cp++); 122 } 123 } else { 124 (void)printf("%-*.*s", v->width, v->width, vis_args); 125 } 126 free(vis_args); 127 } 128 129 void 130 command(KINFO *k, VARENT *ve) 131 { 132 VAR *v; 133 int left; 134 char *cp, *vis_env, *vis_args; 135 136 v = ve->var; 137 if (cflag) { 138 if (ve->next == NULL) /* last field, don't pad */ 139 (void)printf("%s", k->ki_p->ki_comm); 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 if (k->ki_env) { 148 if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) == NULL) 149 errx(1, "malloc failed"); 150 strvis(vis_env, k->ki_env, VIS_TAB | VIS_NL | VIS_NOSLASH); 151 } else 152 vis_env = NULL; 153 154 if (ve->next == NULL) { 155 /* last field */ 156 if (termwidth == UNLIMITED) { 157 if (vis_env) 158 (void)printf("%s ", vis_env); 159 (void)printf("%s", vis_args); 160 } else { 161 left = termwidth - (totwidth - v->width); 162 if (left < 1) /* already wrapped, just use std width */ 163 left = v->width; 164 if ((cp = vis_env) != NULL) { 165 while (--left >= 0 && *cp) 166 (void)putchar(*cp++); 167 if (--left >= 0) 168 putchar(' '); 169 } 170 for (cp = vis_args; --left >= 0 && *cp != '\0';) 171 (void)putchar(*cp++); 172 } 173 } else 174 /* XXX env? */ 175 (void)printf("%-*.*s", v->width, v->width, vis_args); 176 free(vis_args); 177 if (vis_env != NULL) 178 free(vis_env); 179 } 180 181 void 182 ucomm(KINFO *k, VARENT *ve) 183 { 184 VAR *v; 185 186 v = ve->var; 187 (void)printf("%-*s", v->width, k->ki_p->ki_comm); 188 } 189 190 void 191 logname(KINFO *k, VARENT *ve) 192 { 193 VAR *v; 194 char *s; 195 196 v = ve->var; 197 (void)printf("%-*s", v->width, (s = k->ki_p->ki_login, *s) ? s : "-"); 198 } 199 200 void 201 state(KINFO *k, VARENT *ve) 202 { 203 int flag, sflag, tdflags; 204 char *cp; 205 VAR *v; 206 char buf[16]; 207 208 v = ve->var; 209 flag = k->ki_p->ki_flag; 210 sflag = k->ki_p->ki_sflag; 211 tdflags = k->ki_p->ki_tdflags; /* XXXKSE */ 212 cp = buf; 213 214 switch (k->ki_p->ki_stat) { 215 216 case SSTOP: 217 *cp = 'T'; 218 break; 219 220 case SSLEEP: 221 if (tdflags & TDF_SINTR) /* interruptable (long) */ 222 *cp = k->ki_p->ki_slptime >= MAXSLP ? 'I' : 'S'; 223 else 224 *cp = 'D'; 225 break; 226 227 case SRUN: 228 case SIDL: 229 *cp = 'R'; 230 break; 231 232 case SWAIT: 233 *cp = 'W'; 234 break; 235 236 case SLOCK: 237 *cp = 'L'; 238 break; 239 240 case SZOMB: 241 *cp = 'Z'; 242 break; 243 244 default: 245 *cp = '?'; 246 } 247 cp++; 248 if (!(sflag & PS_INMEM)) 249 *cp++ = 'W'; 250 if (k->ki_p->ki_nice < NZERO) 251 *cp++ = '<'; 252 else if (k->ki_p->ki_nice > NZERO) 253 *cp++ = 'N'; 254 if (flag & P_TRACED) 255 *cp++ = 'X'; 256 if (flag & P_WEXIT && k->ki_p->ki_stat != SZOMB) 257 *cp++ = 'E'; 258 if (flag & P_PPWAIT) 259 *cp++ = 'V'; 260 if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0) 261 *cp++ = 'L'; 262 if (k->ki_p->ki_kiflag & KI_SLEADER) 263 *cp++ = 's'; 264 if ((flag & P_CONTROLT) && k->ki_p->ki_pgid == k->ki_p->ki_tpgid) 265 *cp++ = '+'; 266 if (flag & P_JAILED) 267 *cp++ = 'J'; 268 *cp = '\0'; 269 (void)printf("%-*s", v->width, buf); 270 } 271 272 void 273 pri(KINFO *k, VARENT *ve) 274 { 275 VAR *v; 276 277 v = ve->var; 278 (void)printf("%*d", v->width, k->ki_p->ki_pri.pri_level - PZERO); 279 } 280 281 void 282 uname(KINFO *k, VARENT *ve) 283 { 284 VAR *v; 285 286 v = ve->var; 287 (void)printf("%-*s", v->width, user_from_uid(k->ki_p->ki_uid, 0)); 288 } 289 290 int 291 s_uname(KINFO *k) 292 { 293 return (strlen(user_from_uid(k->ki_p->ki_uid, 0))); 294 } 295 296 void 297 rgroupname(KINFO *k, VARENT *ve) 298 { 299 VAR *v; 300 301 v = ve->var; 302 (void)printf("%-*s", v->width, group_from_gid(k->ki_p->ki_rgid, 0)); 303 } 304 305 int 306 s_rgroupname(KINFO *k) 307 { 308 return (strlen(group_from_gid(k->ki_p->ki_rgid, 0))); 309 } 310 311 void 312 runame(KINFO *k, VARENT *ve) 313 { 314 VAR *v; 315 316 v = ve->var; 317 (void)printf("%-*s", v->width, user_from_uid(k->ki_p->ki_ruid, 0)); 318 } 319 320 int 321 s_runame(KINFO *k) 322 { 323 return (strlen(user_from_uid(k->ki_p->ki_ruid, 0))); 324 } 325 326 327 void 328 tdev(KINFO *k, VARENT *ve) 329 { 330 VAR *v; 331 dev_t dev; 332 char buff[16]; 333 334 v = ve->var; 335 dev = k->ki_p->ki_tdev; 336 if (dev == NODEV) 337 (void)printf("%*s", v->width, "??"); 338 else { 339 (void)snprintf(buff, sizeof(buff), 340 "%d/%d", major(dev), minor(dev)); 341 (void)printf("%*s", v->width, buff); 342 } 343 } 344 345 void 346 tname(KINFO *k, VARENT *ve) 347 { 348 VAR *v; 349 dev_t dev; 350 char *ttname; 351 352 v = ve->var; 353 dev = k->ki_p->ki_tdev; 354 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 355 (void)printf("%*s ", v->width - 1, "??"); 356 else { 357 if (strncmp(ttname, "tty", 3) == 0 || 358 strncmp(ttname, "cua", 3) == 0) 359 ttname += 3; 360 (void)printf("%*.*s%c", v->width - 1, v->width - 1, ttname, 361 k->ki_p->ki_kiflag & KI_CTTY ? ' ' : '-'); 362 } 363 } 364 365 void 366 longtname(KINFO *k, VARENT *ve) 367 { 368 VAR *v; 369 dev_t dev; 370 char *ttname; 371 372 v = ve->var; 373 dev = k->ki_p->ki_tdev; 374 if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 375 (void)printf("%-*s", v->width, "??"); 376 else 377 (void)printf("%-*s", v->width, ttname); 378 } 379 380 void 381 started(KINFO *k, VARENT *ve) 382 { 383 VAR *v; 384 time_t then; 385 struct tm *tp; 386 static int use_ampm = -1; 387 char buf[100]; 388 389 v = ve->var; 390 if (!k->ki_valid) { 391 (void)printf("%-*s", v->width, "-"); 392 return; 393 } 394 if (use_ampm < 0) 395 use_ampm = (*nl_langinfo(T_FMT_AMPM) != '\0'); 396 then = k->ki_p->ki_start.tv_sec; 397 tp = localtime(&then); 398 if (now - k->ki_p->ki_start.tv_sec < 24 * 3600) { 399 (void)strftime(buf, sizeof(buf), 400 use_ampm ? "%l:%M%p" : "%k:%M ", tp); 401 } else if (now - k->ki_p->ki_start.tv_sec < 7 * 86400) { 402 (void)strftime(buf, sizeof(buf), 403 use_ampm ? "%a%I%p" : "%a%H ", tp); 404 } else 405 (void)strftime(buf, sizeof(buf), "%e%b%y", tp); 406 (void)printf("%-*s", v->width, buf); 407 } 408 409 void 410 lstarted(KINFO *k, VARENT *ve) 411 { 412 VAR *v; 413 time_t then; 414 char buf[100]; 415 416 v = ve->var; 417 if (!k->ki_valid) { 418 (void)printf("%-*s", v->width, "-"); 419 return; 420 } 421 then = k->ki_p->ki_start.tv_sec; 422 (void)strftime(buf, sizeof(buf), "%c", localtime(&then)); 423 (void)printf("%-*s", v->width, buf); 424 } 425 426 void 427 lockname(KINFO *k, VARENT *ve) 428 { 429 VAR *v; 430 431 v = ve->var; 432 if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { 433 if (k->ki_p->ki_lockname[0] != 0) 434 (void)printf("%-*.*s", v->width, v->width, 435 k->ki_p->ki_lockname); 436 else 437 (void)printf("%-*s", v->width, "???"); 438 } else 439 (void)printf("%-*s", v->width, "-"); 440 } 441 442 void 443 wchan(KINFO *k, VARENT *ve) 444 { 445 VAR *v; 446 447 v = ve->var; 448 if (k->ki_p->ki_wchan) { 449 if (k->ki_p->ki_wmesg[0] != 0) 450 (void)printf("%-*.*s", v->width, v->width, 451 k->ki_p->ki_wmesg); 452 else 453 (void)printf("%-*lx", v->width, 454 (long)k->ki_p->ki_wchan); 455 } else 456 (void)printf("%-*s", v->width, "-"); 457 } 458 459 void 460 mwchan(KINFO *k, VARENT *ve) 461 { 462 VAR *v; 463 464 v = ve->var; 465 if (k->ki_p->ki_wchan) { 466 if (k->ki_p->ki_wmesg[0] != 0) 467 (void)printf("%-*.*s", v->width, v->width, 468 k->ki_p->ki_wmesg); 469 else 470 (void)printf("%-*lx", v->width, 471 (long)k->ki_p->ki_wchan); 472 } else if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { 473 if (k->ki_p->ki_lockname[0]) { 474 (void)printf("%-*.*s", v->width, v->width, 475 k->ki_p->ki_lockname); 476 } else 477 (void)printf("%-*s", v->width, "???"); 478 } else 479 (void)printf("%-*s", v->width, "-"); 480 } 481 482 void 483 vsize(KINFO *k, VARENT *ve) 484 { 485 VAR *v; 486 487 v = ve->var; 488 (void)printf("%*lu", v->width, (u_long)(k->ki_p->ki_size / 1024)); 489 } 490 491 void 492 cputime(KINFO *k, VARENT *ve) 493 { 494 VAR *v; 495 long secs; 496 long psecs; /* "parts" of a second. first micro, then centi */ 497 char obuff[128]; 498 static char decimal_point; 499 500 if (decimal_point == '\0') 501 decimal_point = localeconv()->decimal_point[0]; 502 v = ve->var; 503 if (k->ki_p->ki_stat == SZOMB || !k->ki_valid) { 504 secs = 0; 505 psecs = 0; 506 } else { 507 /* 508 * This counts time spent handling interrupts. We could 509 * fix this, but it is not 100% trivial (and interrupt 510 * time fractions only work on the sparc anyway). XXX 511 */ 512 secs = k->ki_p->ki_runtime / 1000000; 513 psecs = k->ki_p->ki_runtime % 1000000; 514 if (sumrusage) { 515 secs += k->ki_p->ki_childtime.tv_sec; 516 psecs += k->ki_p->ki_childtime.tv_usec; 517 } 518 /* 519 * round and scale to 100's 520 */ 521 psecs = (psecs + 5000) / 10000; 522 secs += psecs / 100; 523 psecs = psecs % 100; 524 } 525 (void)snprintf(obuff, sizeof(obuff), "%3ld:%02ld%c%02ld", 526 secs / 60, secs % 60, decimal_point, psecs); 527 (void)printf("%*s", v->width, obuff); 528 } 529 530 void 531 elapsed(KINFO *k, VARENT *ve) 532 { 533 VAR *v; 534 time_t val; 535 int days, hours, mins, secs; 536 char obuff[128]; 537 538 v = ve->var; 539 val = now - k->ki_p->ki_start.tv_sec; 540 days = val / (24 * 60 * 60); 541 val %= 24 * 60 * 60; 542 hours = val / (60 * 60); 543 val %= 60 * 60; 544 mins = val / 60; 545 secs = val % 60; 546 if (days != 0) 547 (void)snprintf(obuff, sizeof(obuff), "%3d-%02d:%02d:%02d", 548 days, hours, mins, secs); 549 else if (hours != 0) 550 (void)snprintf(obuff, sizeof(obuff), "%02d:%02d:%02d", 551 hours, mins, secs); 552 else 553 (void)snprintf(obuff, sizeof(obuff), "%02d:%02d", mins, secs); 554 (void)printf("%*s", v->width, obuff); 555 } 556 557 double 558 getpcpu(const KINFO *k) 559 { 560 static int failure; 561 562 if (!nlistread) 563 failure = donlist(); 564 if (failure) 565 return (0.0); 566 567 #define fxtofl(fixpt) ((double)(fixpt) / fscale) 568 569 /* XXX - I don't like this */ 570 if (k->ki_p->ki_swtime == 0 || (k->ki_p->ki_sflag & PS_INMEM) == 0) 571 return (0.0); 572 if (rawcpu) 573 return (100.0 * fxtofl(k->ki_p->ki_pctcpu)); 574 return (100.0 * fxtofl(k->ki_p->ki_pctcpu) / 575 (1.0 - exp(k->ki_p->ki_swtime * log(fxtofl(ccpu))))); 576 } 577 578 void 579 pcpu(KINFO *k, VARENT *ve) 580 { 581 VAR *v; 582 583 v = ve->var; 584 (void)printf("%*.1f", v->width, getpcpu(k)); 585 } 586 587 static double 588 getpmem(KINFO *k) 589 { 590 static int failure; 591 double fracmem; 592 593 if (!nlistread) 594 failure = donlist(); 595 if (failure) 596 return (0.0); 597 598 if ((k->ki_p->ki_sflag & PS_INMEM) == 0) 599 return (0.0); 600 /* XXX want pmap ptpages, segtab, etc. (per architecture) */ 601 /* XXX don't have info about shared */ 602 fracmem = ((float)k->ki_p->ki_rssize) / mempages; 603 return (100.0 * fracmem); 604 } 605 606 void 607 pmem(KINFO *k, VARENT *ve) 608 { 609 VAR *v; 610 611 v = ve->var; 612 (void)printf("%*.1f", v->width, getpmem(k)); 613 } 614 615 void 616 pagein(KINFO *k, VARENT *ve) 617 { 618 VAR *v; 619 620 v = ve->var; 621 (void)printf("%*ld", v->width, 622 k->ki_valid ? k->ki_p->ki_rusage.ru_majflt : 0); 623 } 624 625 /* ARGSUSED */ 626 void 627 maxrss(KINFO *k __unused, VARENT *ve) 628 { 629 VAR *v; 630 631 v = ve->var; 632 /* XXX not yet */ 633 (void)printf("%*s", v->width, "-"); 634 } 635 636 void 637 priorityr(KINFO *k, VARENT *ve) 638 { 639 VAR *v; 640 struct priority *lpri; 641 char str[8]; 642 unsigned class, level; 643 644 v = ve->var; 645 lpri = (struct priority *) ((char *)k + v->off); 646 class = lpri->pri_class; 647 level = lpri->pri_level; 648 switch (class) { 649 case PRI_REALTIME: 650 snprintf(str, sizeof(str), "real:%u", level); 651 break; 652 case PRI_TIMESHARE: 653 strncpy(str, "normal", sizeof(str)); 654 break; 655 case PRI_IDLE: 656 snprintf(str, sizeof(str), "idle:%u", level); 657 break; 658 default: 659 snprintf(str, sizeof(str), "%u:%u", class, level); 660 break; 661 } 662 str[sizeof(str) - 1] = '\0'; 663 (void)printf("%*s", v->width, str); 664 } 665 666 /* 667 * Generic output routines. Print fields from various prototype 668 * structures. 669 */ 670 static void 671 printval(void *bp, VAR *v) 672 { 673 static char ofmt[32] = "%"; 674 const char *fcp; 675 char *cp; 676 677 cp = ofmt + 1; 678 fcp = v->fmt; 679 if (v->flag & LJUST) 680 *cp++ = '-'; 681 *cp++ = '*'; 682 while ((*cp++ = *fcp++)); 683 684 #define CHKINF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n)) 685 686 switch (v->type) { 687 case CHAR: 688 (void)printf(ofmt, v->width, *(char *)bp); 689 break; 690 case UCHAR: 691 (void)printf(ofmt, v->width, *(u_char *)bp); 692 break; 693 case SHORT: 694 (void)printf(ofmt, v->width, *(short *)bp); 695 break; 696 case USHORT: 697 (void)printf(ofmt, v->width, *(u_short *)bp); 698 break; 699 case INT: 700 (void)printf(ofmt, v->width, *(int *)bp); 701 break; 702 case UINT: 703 (void)printf(ofmt, v->width, CHKINF127(*(u_int *)bp)); 704 break; 705 case LONG: 706 (void)printf(ofmt, v->width, *(long *)bp); 707 break; 708 case ULONG: 709 (void)printf(ofmt, v->width, *(u_long *)bp); 710 break; 711 case KPTR: 712 (void)printf(ofmt, v->width, *(u_long *)bp); 713 break; 714 case PGTOK: 715 (void)printf(ofmt, v->width, ps_pgtok(*(u_long *)bp)); 716 break; 717 default: 718 errx(1, "unknown type %d", v->type); 719 } 720 } 721 722 void 723 kvar(KINFO *k, VARENT *ve) 724 { 725 VAR *v; 726 727 v = ve->var; 728 printval((char *)((char *)k->ki_p + v->off), v); 729 } 730 731 void 732 rvar(KINFO *k, VARENT *ve) 733 { 734 VAR *v; 735 736 v = ve->var; 737 if (k->ki_valid) 738 printval((char *)((char *)(&k->ki_p->ki_rusage) + v->off), v); 739 else 740 (void)printf("%*s", v->width, "-"); 741 } 742 743 void 744 label(KINFO *k, VARENT *ve) 745 { 746 char *string; 747 VAR *v; 748 mac_t proclabel; 749 int error; 750 751 v = ve->var; 752 string = NULL; 753 if (mac_prepare_process_label(&proclabel) == -1) { 754 perror("mac_prepare_process_label"); 755 goto out; 756 } 757 error = mac_get_pid(k->ki_p->ki_pid, proclabel); 758 if (error == 0) { 759 if (mac_to_text(proclabel, &string) == -1) 760 string = NULL; 761 } 762 mac_free(proclabel); 763 out: 764 if (string != NULL) { 765 (void)printf("%-*s", v->width, string); 766 free(string); 767 } else 768 (void)printf("%-*s", v->width, ""); 769 return; 770 } 771 772 int 773 s_label(KINFO *k) 774 { 775 char *string = NULL; 776 mac_t proclabel; 777 int error, size = 0; 778 779 if (mac_prepare_process_label(&proclabel) == -1) { 780 perror("mac_prepare_process_label"); 781 return (0); 782 } 783 error = mac_get_pid(k->ki_p->ki_pid, proclabel); 784 if (error == 0 && mac_to_text(proclabel, &string) == 0) { 785 size = strlen(string); 786 free(string); 787 } 788 mac_free(proclabel); 789 return (size); 790 } 791