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