1 /* $NetBSD: print.c,v 1.123 2014/11/15 01:58:34 joerg Exp $ */
4 * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1990, 1993, 1994
34 * The Regents of the University of California. All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 #include <sys/cdefs.h>
64 static char sccsid
[] = "@(#)print.c 8.6 (Berkeley) 4/16/94";
66 __RCSID("$NetBSD: print.c,v 1.123 2014/11/15 01:58:34 joerg Exp $");
70 #include <sys/param.h>
72 #include <sys/resource.h>
76 #include <sys/ucred.h>
77 #include <sys/sysctl.h>
95 static char *cmdpart(char *);
96 static void printval(void *, VAR
*, enum mode
);
97 static int titlecmp(char *, char **);
99 static void doubleprintorsetwidth(VAR
*, double, int, enum mode
);
100 static void intprintorsetwidth(VAR
*, int, enum mode
);
101 static void strprintorsetwidth(VAR
*, const char *, enum mode
);
105 #define min(a,b) ((a) <= (b) ? (a) : (b))
113 for (lim
= 10; v
>= lim
; lim
= nlim
) {
127 return ((cp
= strrchr(arg0
, '/')) != NULL
? cp
+ 1 : arg0
);
136 static int firsttime
= 1;
137 static int noheader
= 0;
140 * If all the columns have user-specified null headers,
141 * don't print the blank header line at all.
144 SIMPLEQ_FOREACH(vent
, &displaylist
, next
) {
145 if (vent
->var
->header
[0])
157 SIMPLEQ_FOREACH(vent
, &displaylist
, next
) {
160 len
= strlen(v
->header
);
163 totwidth
+= v
->width
+ 1; /* +1 for space */
165 if (v
->flag
& LJUST
) {
166 if (SIMPLEQ_NEXT(vent
, next
) == NULL
) /* last one */
167 (void)printf("%s", v
->header
);
169 (void)printf("%-*s", v
->width
,
172 (void)printf("%*s", v
->width
, v
->header
);
173 if (SIMPLEQ_NEXT(vent
, next
) != NULL
)
179 totwidth
--; /* take off last space */
184 * Return 1 if the command name in the argument vector (u-area) does
185 * not match the command name (p_comm)
188 titlecmp(char *name
, char **argv
)
194 /* no argument vector == no match; system processes/threads do that */
195 if (argv
== 0 || argv
[0] == 0)
198 title
= cmdpart(argv
[0]);
200 /* the basename matches */
201 if (!strcmp(name
, title
))
204 /* handle login shells, by skipping the leading - */
205 if (title
[0] == '-' && !strcmp(name
, title
+ 1))
208 namelen
= strlen(name
);
210 /* handle daemons that report activity as daemonname: activity */
212 !strncmp(name
, title
, namelen
) &&
213 title
[namelen
+ 0] == ':' &&
214 title
[namelen
+ 1] == ' ')
221 doubleprintorsetwidth(VAR
*v
, double val
, int prec
, enum mode mode
)
225 if (mode
== WIDTHMODE
) {
226 if (val
< 0.0 && val
< v
->longestnd
) {
227 fmtlen
= (int)log10(-val
) + prec
+ 2;
229 if (fmtlen
> v
->width
)
231 } else if (val
> 0.0 && val
> v
->longestpd
) {
232 fmtlen
= (int)log10(val
) + prec
+ 1;
234 if (fmtlen
> v
->width
)
238 (void)printf("%*.*f", v
->width
, prec
, val
);
243 intprintorsetwidth(VAR
*v
, int val
, enum mode mode
)
247 if (mode
== WIDTHMODE
) {
248 if (val
< 0 && val
< v
->longestn
) {
250 fmtlen
= iwidth(-val
) + 1;
251 if (fmtlen
> v
->width
)
253 } else if (val
> 0 && val
> v
->longestp
) {
255 fmtlen
= iwidth(val
);
256 if (fmtlen
> v
->width
)
260 (void)printf("%*d", v
->width
, val
);
264 strprintorsetwidth(VAR
*v
, const char *str
, enum mode mode
)
268 if (mode
== WIDTHMODE
) {
274 (void)printf("%-*.*s", v
->width
, v
->width
, str
);
276 (void)printf("%*.*s", v
->width
, v
->width
, str
);
281 command(void *arg
, VARENT
*ve
, enum mode mode
)
283 struct kinfo_proc2
*ki
;
286 char **argv
, **p
, *name
;
288 if (mode
== WIDTHMODE
)
293 if (SIMPLEQ_NEXT(ve
, next
) != NULL
|| termwidth
!= UNLIMITED
) {
294 if (SIMPLEQ_NEXT(ve
, next
) == NULL
) {
295 left
= termwidth
- (totwidth
- v
->width
);
296 if (left
< 1) /* already wrapped, just use std width */
303 argv
= kvm_getenvv2(kd
, ki
, termwidth
);
304 if ((p
= argv
) != NULL
) {
308 fmt_putc(' ', &left
);
315 argv
= kvm_getargv2(kd
, ki
, termwidth
);
316 if ((p
= argv
) != NULL
) {
320 fmt_putc(' ', &left
);
324 if (!(v
->flag
& ARGV0
) &&
325 titlecmp(name
, argv
)) {
327 * append the real command name within
328 * parentheses, if the command name
329 * does not match the one in the
332 fmt_putc('(', &left
);
333 fmt_puts(name
, &left
);
334 fmt_putc(')', &left
);
338 * Commands that don't set an argv vector
339 * are printed with square brackets if they
340 * are system commands. Otherwise they are
341 * printed within parentheses.
343 if (ki
->p_flag
& P_SYSTEM
) {
344 fmt_putc('[', &left
);
345 fmt_puts(name
, &left
);
346 fmt_putc(']', &left
);
348 fmt_putc('(', &left
);
349 fmt_puts(name
, &left
);
350 fmt_putc(')', &left
);
354 fmt_puts(name
, &left
);
357 if (SIMPLEQ_NEXT(ve
, next
) != NULL
&& left
> 0)
358 (void)printf("%*s", left
, "");
362 groups(void *arg
, VARENT
*ve
, enum mode mode
)
364 struct kinfo_proc2
*ki
;
369 if (mode
== WIDTHMODE
)
374 if (SIMPLEQ_NEXT(ve
, next
) != NULL
|| termwidth
!= UNLIMITED
) {
375 if (SIMPLEQ_NEXT(ve
, next
) == NULL
) {
376 left
= termwidth
- (totwidth
- v
->width
);
377 if (left
< 1) /* already wrapped, just use std width */
384 if (ki
->p_ngroups
== 0)
385 fmt_putc('-', &left
);
387 for (i
= 0; i
< ki
->p_ngroups
; i
++) {
388 (void)snprintf(buf
, sizeof(buf
), "%d", ki
->p_groups
[i
]);
390 fmt_putc(' ', &left
);
391 for (p
= &buf
[0]; *p
; p
++)
395 if (SIMPLEQ_NEXT(ve
, next
) != NULL
&& left
> 0)
396 (void)printf("%*s", left
, "");
400 groupnames(void *arg
, VARENT
*ve
, enum mode mode
)
402 struct kinfo_proc2
*ki
;
407 if (mode
== WIDTHMODE
)
412 if (SIMPLEQ_NEXT(ve
, next
) != NULL
|| termwidth
!= UNLIMITED
) {
413 if (SIMPLEQ_NEXT(ve
, next
) == NULL
) {
414 left
= termwidth
- (totwidth
- v
->width
);
415 if (left
< 1) /* already wrapped, just use std width */
422 if (ki
->p_ngroups
== 0)
423 fmt_putc('-', &left
);
425 for (i
= 0; i
< ki
->p_ngroups
; i
++) {
427 fmt_putc(' ', &left
);
428 for (p
= group_from_gid(ki
->p_groups
[i
], 0); *p
; p
++)
432 if (SIMPLEQ_NEXT(ve
, next
) != NULL
&& left
> 0)
433 (void)printf("%*s", left
, "");
437 ucomm(void *arg
, VARENT
*ve
, enum mode mode
)
439 struct kinfo_proc2
*k
;
444 strprintorsetwidth(v
, k
->p_comm
, mode
);
448 emul(void *arg
, VARENT
*ve
, enum mode mode
)
450 struct kinfo_proc2
*k
;
455 strprintorsetwidth(v
, k
->p_ename
, mode
);
459 logname(void *arg
, VARENT
*ve
, enum mode mode
)
461 struct kinfo_proc2
*k
;
466 strprintorsetwidth(v
, k
->p_login
, mode
);
470 state(void *arg
, VARENT
*ve
, enum mode mode
)
472 struct kinfo_proc2
*k
;
485 * NOTE: There are historical letters, which are no longer used:
487 * - W: indicated that process is swapped out.
488 * - L: indicated non-zero l_holdcnt (i.e. that process was
489 * prevented from swapping-out.
491 * These letters should not be used for new states to avoid
492 * conflicts with old applications which might depend on them.
501 if (flag
& L_SINTR
) /* interruptable (long) */
502 *cp
= (int)k
->p_slptime
>= maxslp
? 'I' : 'S';
529 if (k
->p_nice
< NZERO
)
531 else if (k
->p_nice
> NZERO
)
535 if (flag
& P_WEXIT
&& !is_zombie
)
541 if (k
->p_eflag
& EPROC_SLEADER
)
545 else if (k
->p_nlwps
> 1)
547 if ((flag
& P_CONTROLT
) && k
->p__pgid
== k
->p_tpgid
)
550 strprintorsetwidth(v
, buf
, mode
);
554 lstate(void *arg
, VARENT
*ve
, enum mode mode
)
574 if (flag
& L_SINTR
) /* interruptible (long) */
575 *cp
= (int)k
->l_slptime
>= maxslp
? 'I' : 'S';
606 if (flag
& L_DETACHED
)
609 strprintorsetwidth(v
, buf
, mode
);
613 pnice(void *arg
, VARENT
*ve
, enum mode mode
)
615 struct kinfo_proc2
*k
;
620 intprintorsetwidth(v
, k
->p_nice
- NZERO
, mode
);
624 pri(void *arg
, VARENT
*ve
, enum mode mode
)
631 intprintorsetwidth(v
, l
->l_priority
, mode
);
635 uname(void *arg
, VARENT
*ve
, enum mode mode
)
637 struct kinfo_proc2
*k
;
642 strprintorsetwidth(v
, user_from_uid(k
->p_uid
, 0), mode
);
646 runame(void *arg
, VARENT
*ve
, enum mode mode
)
648 struct kinfo_proc2
*k
;
653 strprintorsetwidth(v
, user_from_uid(k
->p_ruid
, 0), mode
);
657 svuname(void *arg
, VARENT
*ve
, enum mode mode
)
659 struct kinfo_proc2
*k
;
664 strprintorsetwidth(v
, user_from_uid(k
->p_svuid
, 0), mode
);
668 gname(void *arg
, VARENT
*ve
, enum mode mode
)
670 struct kinfo_proc2
*k
;
675 strprintorsetwidth(v
, group_from_gid(k
->p_gid
, 0), mode
);
679 rgname(void *arg
, VARENT
*ve
, enum mode mode
)
681 struct kinfo_proc2
*k
;
686 strprintorsetwidth(v
, group_from_gid(k
->p_rgid
, 0), mode
);
690 svgname(void *arg
, VARENT
*ve
, enum mode mode
)
692 struct kinfo_proc2
*k
;
697 strprintorsetwidth(v
, group_from_gid(k
->p_svgid
, 0), mode
);
701 tdev(void *arg
, VARENT
*ve
, enum mode mode
)
703 struct kinfo_proc2
*k
;
712 if (mode
== PRINTMODE
)
713 (void)printf("%*s", v
->width
, "?");
718 (void)snprintf(buff
, sizeof(buff
),
719 "%lld/%lld", (long long)major(dev
), (long long)minor(dev
));
720 strprintorsetwidth(v
, buff
, mode
);
725 tname(void *arg
, VARENT
*ve
, enum mode mode
)
727 struct kinfo_proc2
*k
;
736 if (dev
== NODEV
|| (ttname
= devname(dev
, S_IFCHR
)) == NULL
) {
737 if (mode
== PRINTMODE
)
738 (void)printf("%-*s", v
->width
, "?");
744 /* Actually shorten TTY names. "console" is *really* long. */
745 if (strcmp(ttname
, "console") == 0)
747 else if (strncmp(ttname
, "tty", 3) == 0 && ttname
[3] != '\0')
749 else if (strncmp(ttname
, "pts/", 4) == 0 && ttname
[4] != '\0')
750 ttname
+= 4; /* this is what FreeBSD does */
752 noctty
= !(k
->p_eflag
& EPROC_CTTY
) ? 1 : 0;
753 if (mode
== WIDTHMODE
) {
756 fmtlen
= strlen(ttname
) + noctty
;
757 if (v
->width
< fmtlen
)
761 (void)printf("%-*s-", v
->width
- 1, ttname
);
763 (void)printf("%-*s", v
->width
, ttname
);
769 longtname(void *arg
, VARENT
*ve
, enum mode mode
)
771 struct kinfo_proc2
*k
;
779 if (dev
== NODEV
|| (ttname
= devname(dev
, S_IFCHR
)) == NULL
) {
780 if (mode
== PRINTMODE
)
781 (void)printf("%-*s", v
->width
, "?");
786 strprintorsetwidth(v
, ttname
, mode
);
791 started(void *arg
, VARENT
*ve
, enum mode mode
)
793 struct kinfo_proc2
*k
;
802 if (mode
== PRINTMODE
)
803 (void)printf("%*s", v
->width
, "-");
807 startt
= k
->p_ustart_sec
;
808 tp
= localtime(&startt
);
811 if (now
- k
->p_ustart_sec
< SECSPERDAY
)
812 /* I *hate* SCCS... */
813 (void)strftime(buf
, sizeof(buf
) - 1, "%l:%" "M%p", tp
);
814 else if (now
- k
->p_ustart_sec
< DAYSPERWEEK
* SECSPERDAY
)
815 /* I *hate* SCCS... */
816 (void)strftime(buf
, sizeof(buf
) - 1, "%a%" "I%p", tp
);
818 (void)strftime(buf
, sizeof(buf
) - 1, "%e%b%y", tp
);
819 /* %e and %l can start with a space. */
823 strprintorsetwidth(v
, cp
, mode
);
827 lstarted(void *arg
, VARENT
*ve
, enum mode mode
)
829 struct kinfo_proc2
*k
;
838 * Minimum width is less than header - we don't
839 * need to check it every time.
841 if (mode
== PRINTMODE
)
842 (void)printf("%*s", v
->width
, "-");
845 startt
= k
->p_ustart_sec
;
847 /* assume all times are the same length */
848 if (mode
!= WIDTHMODE
|| v
->width
== 0) {
849 (void)strftime(buf
, sizeof(buf
) -1, "%c",
851 strprintorsetwidth(v
, buf
, mode
);
856 elapsed(void *arg
, VARENT
*ve
, enum mode mode
)
858 struct kinfo_proc2
*k
;
860 int32_t origseconds
, secs
, mins
, hours
, days
;
861 int fmtlen
, printed_something
;
865 if (k
->p_uvalid
== 0) {
870 origseconds
= now
- k
->p_ustart_sec
;
871 if (origseconds
< 0) {
873 * Don't try to be fancy if the machine's
874 * clock has been rewound to before the
882 mins
= secs
/ SECSPERMIN
;
884 hours
= mins
/ MINSPERHOUR
;
886 days
= hours
/ HOURSPERDAY
;
887 hours
%= HOURSPERDAY
;
889 if (mode
== WIDTHMODE
) {
890 if (origseconds
== 0)
891 /* non-zero so fmtlen is calculated at least once */
894 if (origseconds
> v
->longestp
) {
895 v
->longestp
= origseconds
;
898 /* +9 for "-hh:mm:ss" */
899 fmtlen
= iwidth(days
) + 9;
900 } else if (hours
> 0) {
902 fmtlen
= iwidth(hours
) + 6;
905 fmtlen
= iwidth(mins
) + 3;
908 if (fmtlen
> v
->width
)
912 printed_something
= 0;
916 (void)printf("%*d", fmtlen
- 9, days
);
917 printed_something
= 1;
918 } else if (fmtlen
> 9) {
919 (void)printf("%*s", fmtlen
- 9, "");
924 if (printed_something
) {
925 (void)printf("-%.*d", fmtlen
- 7, hours
);
926 printed_something
= 1;
927 } else if (hours
> 0) {
928 (void)printf("%*d", fmtlen
- 6, hours
);
929 printed_something
= 1;
930 } else if (fmtlen
> 6) {
931 (void)printf("%*s", fmtlen
- 6, "");
936 /* Don't need to set fmtlen or printed_something any more... */
937 if (printed_something
) {
938 (void)printf(":%.*d", fmtlen
- 4, mins
);
939 } else if (mins
> 0) {
940 (void)printf("%*d", fmtlen
- 3, mins
);
941 } else if (fmtlen
> 3) {
942 (void)printf("%*s", fmtlen
- 3, "0");
945 (void)printf(":%.2d", secs
);
950 wchan(void *arg
, VARENT
*ve
, enum mode mode
)
960 strprintorsetwidth(v
, l
->l_wmesg
, mode
);
961 v
->width
= min(v
->width
, KI_WMESGLEN
);
963 (void)asprintf(&buf
, "%-*" PRIx64
, v
->width
,
967 strprintorsetwidth(v
, buf
, mode
);
968 v
->width
= min(v
->width
, KI_WMESGLEN
);
972 if (mode
== PRINTMODE
)
973 (void)printf("%-*s", v
->width
, "-");
977 #define pgtok(a) (((a)*(size_t)getpagesize())/1024)
980 vsize(void *arg
, VARENT
*ve
, enum mode mode
)
982 struct kinfo_proc2
*k
;
987 intprintorsetwidth(v
, pgtok(k
->p_vm_msize
), mode
);
991 rssize(void *arg
, VARENT
*ve
, enum mode mode
)
993 struct kinfo_proc2
*k
;
998 /* XXX don't have info about shared */
999 intprintorsetwidth(v
, pgtok(k
->p_vm_rssize
), mode
);
1003 p_rssize(void *arg
, VARENT
*ve
, enum mode mode
) /* doesn't account for text */
1005 struct kinfo_proc2
*k
;
1010 intprintorsetwidth(v
, pgtok(k
->p_vm_rssize
), mode
);
1014 cpuid(void *arg
, VARENT
*ve
, enum mode mode
)
1016 struct kinfo_lwp
*l
;
1021 intprintorsetwidth(v
, l
->l_cpuid
, mode
);
1025 cputime1(int32_t secs
, int32_t psecs
, VAR
*v
, enum mode mode
)
1030 * round and scale to 100's
1032 psecs
= (psecs
+ 5000) / 10000;
1033 secs
+= psecs
/ 100;
1034 psecs
= psecs
% 100;
1036 if (mode
== WIDTHMODE
) {
1038 * Ugg, this is the only field where a value of 0 is longer
1039 * than the column title.
1040 * Use SECSPERMIN, because secs is divided by that when
1041 * passed to iwidth().
1046 if (secs
> v
->longestp
) {
1048 /* "+6" for the ":%02ld.%02ld" in the printf() below */
1049 fmtlen
= iwidth(secs
/ SECSPERMIN
) + 6;
1050 if (fmtlen
> v
->width
)
1054 (void)printf("%*ld:%02ld.%02ld", v
->width
- 6,
1055 (long)(secs
/ SECSPERMIN
), (long)(secs
% SECSPERMIN
),
1061 cputime(void *arg
, VARENT
*ve
, enum mode mode
)
1063 struct kinfo_proc2
*k
;
1066 int32_t psecs
; /* "parts" of a second. first micro, then centi */
1072 * This counts time spent handling interrupts. We could
1073 * fix this, but it is not 100% trivial (and interrupt
1074 * time fractions only work on the sparc anyway). XXX
1076 secs
= k
->p_rtime_sec
;
1077 psecs
= k
->p_rtime_usec
;
1079 secs
+= k
->p_uctime_sec
;
1080 psecs
+= k
->p_uctime_usec
;
1083 cputime1(secs
, psecs
, v
, mode
);
1087 lcputime(void *arg
, VARENT
*ve
, enum mode mode
)
1089 struct kinfo_lwp
*l
;
1092 int32_t psecs
; /* "parts" of a second. first micro, then centi */
1097 secs
= l
->l_rtime_sec
;
1098 psecs
= l
->l_rtime_usec
;
1100 cputime1(secs
, psecs
, v
, mode
);
1104 getpcpu(const struct kinfo_proc2
*k
)
1109 failure
= (kd
) ? donlist() : 1;
1113 #define fxtofl(fixpt) ((double)(fixpt) / fscale)
1115 if (k
->p_swtime
== 0 || k
->p_realstat
== SZOMB
)
1118 return (100.0 * fxtofl(k
->p_pctcpu
));
1119 return (100.0 * fxtofl(k
->p_pctcpu
) /
1120 (1.0 - exp(k
->p_swtime
* log(ccpu
))));
1124 pcpu(void *arg
, VARENT
*ve
, enum mode mode
)
1126 struct kinfo_proc2
*k
;
1133 doubleprintorsetwidth(v
, dbl
, (dbl
>= 99.95) ? 0 : 1, mode
);
1137 getpmem(const struct kinfo_proc2
*k
)
1144 failure
= (kd
) ? donlist() : 1;
1148 /* XXX want pmap ptpages, segtab, etc. (per architecture) */
1149 szptudot
= uspace
/getpagesize();
1150 /* XXX don't have info about shared */
1151 fracmem
= ((float)k
->p_vm_rssize
+ szptudot
)/mempages
;
1152 return (100.0 * fracmem
);
1156 pmem(void *arg
, VARENT
*ve
, enum mode mode
)
1158 struct kinfo_proc2
*k
;
1163 doubleprintorsetwidth(v
, getpmem(k
), 1, mode
);
1167 pagein(void *arg
, VARENT
*ve
, enum mode mode
)
1169 struct kinfo_proc2
*k
;
1174 intprintorsetwidth(v
, k
->p_uvalid
? k
->p_uru_majflt
: 0, mode
);
1178 maxrss(void *arg
, VARENT
*ve
, enum mode mode
)
1183 /* No need to check width! */
1184 if (mode
== PRINTMODE
)
1185 (void)printf("%*s", v
->width
, "-");
1189 tsize(void *arg
, VARENT
*ve
, enum mode mode
)
1191 struct kinfo_proc2
*k
;
1196 intprintorsetwidth(v
, pgtok(k
->p_vm_tsize
), mode
);
1200 * Generic output routines. Print fields from various prototype
1204 printval(void *bp
, VAR
*v
, enum mode mode
)
1206 static char ofmt
[32] = "%";
1207 int width
, vok
, fmtlen
;
1213 val
= 0; /* XXXGCC -Wuninitialized [hpcarm] */
1214 uval
= 0; /* XXXGCC -Wuninitialized [hpcarm] */
1217 * Note that the "INF127" check is nonsensical for types
1218 * that are or can be signed.
1220 #define GET(type) (*(type *)bp)
1221 #define CHK_INF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n))
1227 if (mode
== WIDTHMODE
) {
1235 uval
= CHK_INF127(GET(u_char
));
1243 uval
= CHK_INF127(GET(u_short
));
1256 uval
= CHK_INF127(GET(u_int
));
1264 uval
= CHK_INF127(GET(u_long
));
1268 uval
= GET(u_int64_t
);
1272 uval
= GET(u_int64_t
);
1281 uval
= CHK_INF127(GET(u_int64_t
));
1291 if (val
< 0 && val
< v
->longestn
) {
1293 fmtlen
= iwidth(-val
) + 1;
1294 if (fmtlen
> v
->width
)
1296 } else if (val
> 0 && val
> v
->longestp
) {
1298 fmtlen
= iwidth(val
);
1299 if (fmtlen
> v
->width
)
1304 if (uval
> v
->longestu
) {
1306 v
->width
= iwidth(uval
);
1315 if (fmtlen
> v
->width
)
1324 if (v
->flag
& LJUST
)
1327 while ((*cp
++ = *fcp
++) != '\0')
1332 (void)printf(ofmt
, width
, GET(char));
1335 (void)printf(ofmt
, width
, CHK_INF127(GET(u_char
)));
1338 (void)printf(ofmt
, width
, GET(short));
1341 (void)printf(ofmt
, width
, CHK_INF127(GET(u_short
)));
1344 (void)printf(ofmt
, width
, GET(int));
1347 (void)printf(ofmt
, width
, CHK_INF127(GET(u_int
)));
1350 (void)printf(ofmt
, width
, GET(long));
1353 (void)printf(ofmt
, width
, CHK_INF127(GET(u_long
)));
1356 (void)printf(ofmt
, width
, GET(u_int64_t
));
1359 (void)printf(ofmt
, width
, GET(u_int64_t
) & 0xffffff);
1362 (void)printf(ofmt
, width
, GET(int32_t));
1365 (void)printf(ofmt
, width
, CHK_INF127(GET(u_int32_t
)));
1369 sigset_t
*s
= (sigset_t
*)(void *)bp
;
1371 #define SIGSETSIZE (sizeof(s->__bits) / sizeof(s->__bits[0]))
1372 char buf
[SIGSETSIZE
* 8 + 1];
1374 for (i
= 0; i
< SIGSETSIZE
; i
++)
1375 (void)snprintf(&buf
[i
* 8], 9, "%.8x",
1376 s
->__bits
[(SIGSETSIZE
- 1) - i
]);
1378 /* Skip leading zeroes */
1379 for (i
= 0; buf
[i
] == '0'; i
++)
1384 strprintorsetwidth(v
, buf
+ i
, mode
);
1389 (void)printf(ofmt
, width
, GET(int64_t));
1392 (void)printf(ofmt
, width
, CHK_INF127(GET(u_int64_t
)));
1395 errx(1, "unknown type %d", v
->type
);
1402 pvar(void *arg
, VARENT
*ve
, enum mode mode
)
1407 if (v
->flag
& UAREA
&& !((struct kinfo_proc2
*)arg
)->p_uvalid
) {
1408 if (mode
== PRINTMODE
)
1409 (void)printf("%*s", v
->width
, "-");
1413 (void)printval((char *)arg
+ v
->off
, v
, mode
);
1417 putimeval(void *arg
, VARENT
*ve
, enum mode mode
)
1420 struct kinfo_proc2
*k
= arg
;
1421 ulong secs
= *(uint32_t *)((char *)arg
+ v
->off
);
1422 ulong usec
= *(uint32_t *)((char *)arg
+ v
->off
+ sizeof (uint32_t));
1426 if (mode
== PRINTMODE
)
1427 (void)printf("%*s", v
->width
, "-");
1431 if (mode
== WIDTHMODE
) {
1433 /* non-zero so fmtlen is calculated at least once */
1435 if (secs
> v
->longestu
) {
1439 fmtlen
= iwidth(secs
) + 6 + 1;
1442 fmtlen
= iwidth((secs
+ 1) / SECSPERHOUR
)
1443 + 2 + 1 + 2 + 1 + 2 + 1;
1444 if (fmtlen
> v
->width
)
1451 (void)printf( "%*lu.%.6lu", v
->width
- 6 - 1, secs
, usec
);
1455 if (usec
>= 1000000) {
1459 m
= secs
/ SECSPERMIN
;
1460 secs
-= m
* SECSPERMIN
;
1461 h
= m
/ MINSPERHOUR
;
1462 m
-= h
* MINSPERHOUR
;
1463 (void)printf( "%*u:%.2u:%.2lu.%.2lu", v
->width
- 9, h
, m
, secs
,
1469 lname(void *arg
, VARENT
*ve
, enum mode mode
)
1471 struct kinfo_lwp
*l
;
1476 if (l
->l_name
[0] != '\0') {
1477 strprintorsetwidth(v
, l
->l_name
, mode
);
1478 v
->width
= min(v
->width
, KI_LNAMELEN
);
1480 if (mode
== PRINTMODE
)
1481 (void)printf("%-*s", v
->width
, "-");