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