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