print.c revision 1.86 1 1.86 simonb /* $NetBSD: print.c,v 1.86 2004/03/27 14:09:10 simonb Exp $ */
2 1.18 cgd
3 1.55 simonb /*
4 1.55 simonb * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 1.55 simonb * All rights reserved.
6 1.55 simonb *
7 1.55 simonb * This code is derived from software contributed to The NetBSD Foundation
8 1.55 simonb * by Simon Burge.
9 1.55 simonb *
10 1.55 simonb * Redistribution and use in source and binary forms, with or without
11 1.55 simonb * modification, are permitted provided that the following conditions
12 1.55 simonb * are met:
13 1.55 simonb * 1. Redistributions of source code must retain the above copyright
14 1.55 simonb * notice, this list of conditions and the following disclaimer.
15 1.55 simonb * 2. Redistributions in binary form must reproduce the above copyright
16 1.55 simonb * notice, this list of conditions and the following disclaimer in the
17 1.55 simonb * documentation and/or other materials provided with the distribution.
18 1.55 simonb * 3. All advertising materials mentioning features or use of this software
19 1.55 simonb * must display the following acknowledgement:
20 1.55 simonb * This product includes software developed by the NetBSD
21 1.55 simonb * Foundation, Inc. and its contributors.
22 1.55 simonb * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.55 simonb * contributors may be used to endorse or promote products derived
24 1.55 simonb * from this software without specific prior written permission.
25 1.55 simonb *
26 1.55 simonb * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.55 simonb * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.55 simonb * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.55 simonb * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.55 simonb * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.55 simonb * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.55 simonb * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.55 simonb * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.55 simonb * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.55 simonb * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.55 simonb * POSSIBILITY OF SUCH DAMAGE.
37 1.55 simonb */
38 1.55 simonb
39 1.55 simonb /*
40 1.12 cgd * Copyright (c) 1990, 1993, 1994
41 1.12 cgd * The Regents of the University of California. All rights reserved.
42 1.1 cgd *
43 1.1 cgd * Redistribution and use in source and binary forms, with or without
44 1.1 cgd * modification, are permitted provided that the following conditions
45 1.1 cgd * are met:
46 1.1 cgd * 1. Redistributions of source code must retain the above copyright
47 1.1 cgd * notice, this list of conditions and the following disclaimer.
48 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
49 1.1 cgd * notice, this list of conditions and the following disclaimer in the
50 1.1 cgd * documentation and/or other materials provided with the distribution.
51 1.79 agc * 3. Neither the name of the University nor the names of its contributors
52 1.1 cgd * may be used to endorse or promote products derived from this software
53 1.1 cgd * without specific prior written permission.
54 1.1 cgd *
55 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 1.1 cgd * SUCH DAMAGE.
66 1.1 cgd */
67 1.1 cgd
68 1.33 christos #include <sys/cdefs.h>
69 1.1 cgd #ifndef lint
70 1.18 cgd #if 0
71 1.12 cgd static char sccsid[] = "@(#)print.c 8.6 (Berkeley) 4/16/94";
72 1.18 cgd #else
73 1.86 simonb __RCSID("$NetBSD: print.c,v 1.86 2004/03/27 14:09:10 simonb Exp $");
74 1.18 cgd #endif
75 1.1 cgd #endif /* not lint */
76 1.1 cgd
77 1.1 cgd #include <sys/param.h>
78 1.1 cgd #include <sys/time.h>
79 1.1 cgd #include <sys/resource.h>
80 1.76 thorpej #include <sys/lwp.h>
81 1.1 cgd #include <sys/proc.h>
82 1.1 cgd #include <sys/stat.h>
83 1.12 cgd #include <sys/ucred.h>
84 1.12 cgd #include <sys/sysctl.h>
85 1.1 cgd
86 1.12 cgd #include <err.h>
87 1.77 atatat #include <grp.h>
88 1.21 mycroft #include <kvm.h>
89 1.12 cgd #include <math.h>
90 1.12 cgd #include <nlist.h>
91 1.28 explorer #include <pwd.h>
92 1.12 cgd #include <stddef.h>
93 1.12 cgd #include <stdio.h>
94 1.12 cgd #include <stdlib.h>
95 1.12 cgd #include <string.h>
96 1.37 kleink #include <time.h>
97 1.12 cgd #include <tzfile.h>
98 1.16 cgd #include <unistd.h>
99 1.12 cgd
100 1.12 cgd #include "ps.h"
101 1.21 mycroft
102 1.82 simonb static char *cmdpart(char *);
103 1.82 simonb static void printval(void *, VAR *, int);
104 1.82 simonb static int titlecmp(char *, char **);
105 1.82 simonb
106 1.82 simonb static void doubleprintorsetwidth(VAR *, double, int, int);
107 1.82 simonb static void intprintorsetwidth(VAR *, int, int);
108 1.82 simonb static void strprintorsetwidth(VAR *, const char *, int);
109 1.53 simonb
110 1.32 mycroft #define min(a,b) ((a) <= (b) ? (a) : (b))
111 1.78 dsl
112 1.78 dsl static int
113 1.78 dsl iwidth(u_int64_t v)
114 1.78 dsl {
115 1.78 dsl u_int64_t nlim, lim;
116 1.78 dsl int w = 1;
117 1.78 dsl
118 1.78 dsl for (lim = 10; v >= lim; lim = nlim) {
119 1.78 dsl nlim = lim * 10;
120 1.78 dsl w++;
121 1.78 dsl if (nlim < lim)
122 1.78 dsl break;
123 1.78 dsl }
124 1.78 dsl return w;
125 1.78 dsl }
126 1.32 mycroft
127 1.21 mycroft static char *
128 1.82 simonb cmdpart(char *arg0)
129 1.21 mycroft {
130 1.21 mycroft char *cp;
131 1.21 mycroft
132 1.21 mycroft return ((cp = strrchr(arg0, '/')) != NULL ? cp + 1 : arg0);
133 1.21 mycroft }
134 1.21 mycroft
135 1.12 cgd void
136 1.82 simonb printheader(void)
137 1.1 cgd {
138 1.53 simonb int len;
139 1.12 cgd VAR *v;
140 1.12 cgd struct varent *vent;
141 1.53 simonb static int firsttime = 1;
142 1.1 cgd
143 1.1 cgd for (vent = vhead; vent; vent = vent->next) {
144 1.1 cgd v = vent->var;
145 1.55 simonb if (firsttime) {
146 1.53 simonb len = strlen(v->header);
147 1.53 simonb if (len > v->width)
148 1.53 simonb v->width = len;
149 1.53 simonb totwidth += v->width + 1; /* +1 for space */
150 1.53 simonb }
151 1.1 cgd if (v->flag & LJUST) {
152 1.1 cgd if (vent->next == NULL) /* last one */
153 1.12 cgd (void)printf("%s", v->header);
154 1.1 cgd else
155 1.53 simonb (void)printf("%-*s", v->width,
156 1.53 simonb v->header);
157 1.1 cgd } else
158 1.12 cgd (void)printf("%*s", v->width, v->header);
159 1.1 cgd if (vent->next != NULL)
160 1.12 cgd (void)putchar(' ');
161 1.1 cgd }
162 1.12 cgd (void)putchar('\n');
163 1.55 simonb if (firsttime) {
164 1.53 simonb firsttime = 0;
165 1.55 simonb totwidth--; /* take off last space */
166 1.55 simonb }
167 1.21 mycroft }
168 1.21 mycroft
169 1.82 simonb /*
170 1.65 christos * Return 1 if the the command name in the argument vector (u-area) does
171 1.65 christos * not match the command name (p_comm)
172 1.63 hubertf */
173 1.39 mycroft static int
174 1.82 simonb titlecmp(char *name, char **argv)
175 1.39 mycroft {
176 1.39 mycroft char *title;
177 1.39 mycroft int namelen;
178 1.39 mycroft
179 1.63 hubertf
180 1.64 christos /* no argument vector == no match; system processes/threads do that */
181 1.39 mycroft if (argv == 0 || argv[0] == 0)
182 1.39 mycroft return (1);
183 1.39 mycroft
184 1.39 mycroft title = cmdpart(argv[0]);
185 1.39 mycroft
186 1.64 christos /* the basename matches */
187 1.39 mycroft if (!strcmp(name, title))
188 1.39 mycroft return (0);
189 1.39 mycroft
190 1.64 christos /* handle login shells, by skipping the leading - */
191 1.84 simonb if (title[0] == '-' && !strcmp(name, title + 1))
192 1.39 mycroft return (0);
193 1.39 mycroft
194 1.39 mycroft namelen = strlen(name);
195 1.39 mycroft
196 1.64 christos /* handle daemons that report activity as daemonname: activity */
197 1.39 mycroft if (argv[1] == 0 &&
198 1.39 mycroft !strncmp(name, title, namelen) &&
199 1.55 simonb title[namelen + 0] == ':' &&
200 1.55 simonb title[namelen + 1] == ' ')
201 1.39 mycroft return (0);
202 1.39 mycroft
203 1.39 mycroft return (1);
204 1.39 mycroft }
205 1.39 mycroft
206 1.53 simonb static void
207 1.82 simonb doubleprintorsetwidth(VAR *v, double val, int prec, int mode)
208 1.53 simonb {
209 1.53 simonb int fmtlen;
210 1.53 simonb
211 1.53 simonb if (mode == WIDTHMODE) {
212 1.53 simonb if (val < 0.0 && val < v->longestnd) {
213 1.53 simonb fmtlen = (int)log10(-val) + prec + 2;
214 1.53 simonb v->longestnd = val;
215 1.53 simonb if (fmtlen > v->width)
216 1.53 simonb v->width = fmtlen;
217 1.53 simonb } else if (val > 0.0 && val > v->longestpd) {
218 1.53 simonb fmtlen = (int)log10(val) + prec + 1;
219 1.53 simonb v->longestpd = val;
220 1.53 simonb if (fmtlen > v->width)
221 1.53 simonb v->width = fmtlen;
222 1.53 simonb }
223 1.53 simonb } else {
224 1.84 simonb (void)printf("%*.*f", v->width, prec, val);
225 1.53 simonb }
226 1.53 simonb }
227 1.53 simonb
228 1.53 simonb static void
229 1.82 simonb intprintorsetwidth(VAR *v, int val, int mode)
230 1.53 simonb {
231 1.53 simonb int fmtlen;
232 1.53 simonb
233 1.53 simonb if (mode == WIDTHMODE) {
234 1.53 simonb if (val < 0 && val < v->longestn) {
235 1.53 simonb v->longestn = val;
236 1.78 dsl fmtlen = iwidth(-val) + 1;
237 1.53 simonb if (fmtlen > v->width)
238 1.53 simonb v->width = fmtlen;
239 1.53 simonb } else if (val > 0 && val > v->longestp) {
240 1.53 simonb v->longestp = val;
241 1.78 dsl fmtlen = iwidth(val);
242 1.53 simonb if (fmtlen > v->width)
243 1.53 simonb v->width = fmtlen;
244 1.53 simonb }
245 1.53 simonb } else
246 1.84 simonb (void)printf("%*d", v->width, val);
247 1.53 simonb }
248 1.53 simonb
249 1.53 simonb static void
250 1.82 simonb strprintorsetwidth(VAR *v, const char *str, int mode)
251 1.53 simonb {
252 1.53 simonb int len;
253 1.53 simonb
254 1.53 simonb if (mode == WIDTHMODE) {
255 1.53 simonb len = strlen(str);
256 1.53 simonb if (len > v->width)
257 1.53 simonb v->width = len;
258 1.53 simonb } else {
259 1.53 simonb if (v->flag & LJUST)
260 1.84 simonb (void)printf("%-*.*s", v->width, v->width, str);
261 1.53 simonb else
262 1.84 simonb (void)printf("%*.*s", v->width, v->width, str);
263 1.53 simonb }
264 1.53 simonb }
265 1.53 simonb
266 1.12 cgd void
267 1.82 simonb command(void *arg, VARENT *ve, int mode)
268 1.12 cgd {
269 1.76 thorpej struct kinfo_proc2 *ki;
270 1.1 cgd VAR *v;
271 1.12 cgd int left;
272 1.39 mycroft char **argv, **p, *name;
273 1.7 cgd
274 1.55 simonb if (mode == WIDTHMODE)
275 1.53 simonb return;
276 1.55 simonb
277 1.76 thorpej ki = arg;
278 1.53 simonb v = ve->var;
279 1.21 mycroft if (ve->next != NULL || termwidth != UNLIMITED) {
280 1.21 mycroft if (ve->next == NULL) {
281 1.55 simonb left = termwidth - (totwidth - v->width);
282 1.1 cgd if (left < 1) /* already wrapped, just use std width */
283 1.1 cgd left = v->width;
284 1.21 mycroft } else
285 1.21 mycroft left = v->width;
286 1.21 mycroft } else
287 1.21 mycroft left = -1;
288 1.51 simonb if (needenv && kd) {
289 1.51 simonb argv = kvm_getenvv2(kd, ki, termwidth);
290 1.33 christos if ((p = argv) != NULL) {
291 1.21 mycroft while (*p) {
292 1.21 mycroft fmt_puts(*p, &left);
293 1.21 mycroft p++;
294 1.21 mycroft fmt_putc(' ', &left);
295 1.4 cgd }
296 1.1 cgd }
297 1.21 mycroft }
298 1.21 mycroft if (needcomm) {
299 1.51 simonb name = ki->p_comm;
300 1.21 mycroft if (!commandonly) {
301 1.74 jdolecek argv = kvm_getargv2(kd, ki, termwidth);
302 1.33 christos if ((p = argv) != NULL) {
303 1.21 mycroft while (*p) {
304 1.21 mycroft fmt_puts(*p, &left);
305 1.21 mycroft p++;
306 1.21 mycroft fmt_putc(' ', &left);
307 1.21 mycroft }
308 1.67 christos if (titlecmp(name, argv)) {
309 1.67 christos /*
310 1.67 christos * append the real command name within
311 1.82 simonb * parentheses, if the command name
312 1.67 christos * does not match the one in the
313 1.67 christos * argument vector
314 1.67 christos */
315 1.67 christos fmt_putc('(', &left);
316 1.67 christos fmt_puts(name, &left);
317 1.67 christos fmt_putc(')', &left);
318 1.67 christos }
319 1.67 christos } else {
320 1.67 christos /*
321 1.67 christos * Commands that don't set an argv vector
322 1.69 lukem * are printed with square brackets if they
323 1.68 enami * are system commands. Otherwise they are
324 1.68 enami * printed within parentheses.
325 1.67 christos */
326 1.68 enami if (ki->p_flag & P_SYSTEM) {
327 1.68 enami fmt_putc('[', &left);
328 1.68 enami fmt_puts(name, &left);
329 1.68 enami fmt_putc(']', &left);
330 1.68 enami } else {
331 1.68 enami fmt_putc('(', &left);
332 1.68 enami fmt_puts(name, &left);
333 1.68 enami fmt_putc(')', &left);
334 1.68 enami }
335 1.45 jdolecek }
336 1.21 mycroft } else {
337 1.39 mycroft fmt_puts(name, &left);
338 1.21 mycroft }
339 1.21 mycroft }
340 1.23 mycroft if (ve->next && left > 0)
341 1.84 simonb (void)printf("%*s", left, "");
342 1.1 cgd }
343 1.1 cgd
344 1.12 cgd void
345 1.82 simonb groups(void *arg, VARENT *ve, int mode)
346 1.77 atatat {
347 1.77 atatat struct kinfo_proc2 *ki;
348 1.77 atatat VAR *v;
349 1.77 atatat int left, i;
350 1.77 atatat char buf[16], *p;
351 1.77 atatat
352 1.77 atatat if (mode == WIDTHMODE)
353 1.77 atatat return;
354 1.77 atatat
355 1.77 atatat ki = arg;
356 1.77 atatat v = ve->var;
357 1.77 atatat if (ve->next != NULL || termwidth != UNLIMITED) {
358 1.77 atatat if (ve->next == NULL) {
359 1.77 atatat left = termwidth - (totwidth - v->width);
360 1.77 atatat if (left < 1) /* already wrapped, just use std width */
361 1.77 atatat left = v->width;
362 1.77 atatat } else
363 1.77 atatat left = v->width;
364 1.77 atatat } else
365 1.77 atatat left = -1;
366 1.77 atatat
367 1.77 atatat if (ki->p_ngroups == 0) {
368 1.77 atatat fmt_putc('-', &left);
369 1.77 atatat return;
370 1.77 atatat }
371 1.77 atatat
372 1.77 atatat for (i = 0; i < ki->p_ngroups; i++) {
373 1.77 atatat (void)snprintf(buf, sizeof(buf), "%d", ki->p_groups[i]);
374 1.77 atatat if (i)
375 1.77 atatat fmt_putc(' ', &left);
376 1.77 atatat for (p = &buf[0]; *p; p++)
377 1.77 atatat fmt_putc(*p, &left);
378 1.77 atatat }
379 1.77 atatat
380 1.77 atatat if (ve->next && left > 0)
381 1.84 simonb (void)printf("%*s", left, "");
382 1.77 atatat }
383 1.77 atatat
384 1.77 atatat void
385 1.82 simonb groupnames(void *arg, VARENT *ve, int mode)
386 1.77 atatat {
387 1.77 atatat struct kinfo_proc2 *ki;
388 1.77 atatat VAR *v;
389 1.77 atatat int left, i;
390 1.77 atatat const char *p;
391 1.77 atatat
392 1.77 atatat if (mode == WIDTHMODE)
393 1.77 atatat return;
394 1.77 atatat
395 1.77 atatat ki = arg;
396 1.77 atatat v = ve->var;
397 1.77 atatat if (ve->next != NULL || termwidth != UNLIMITED) {
398 1.77 atatat if (ve->next == NULL) {
399 1.77 atatat left = termwidth - (totwidth - v->width);
400 1.77 atatat if (left < 1) /* already wrapped, just use std width */
401 1.77 atatat left = v->width;
402 1.77 atatat } else
403 1.77 atatat left = v->width;
404 1.77 atatat } else
405 1.77 atatat left = -1;
406 1.77 atatat
407 1.77 atatat if (ki->p_ngroups == 0) {
408 1.77 atatat fmt_putc('-', &left);
409 1.77 atatat return;
410 1.77 atatat }
411 1.77 atatat
412 1.77 atatat for (i = 0; i < ki->p_ngroups; i++) {
413 1.77 atatat if (i)
414 1.77 atatat fmt_putc(' ', &left);
415 1.77 atatat for (p = group_from_gid(ki->p_groups[i], 0); *p; p++)
416 1.77 atatat fmt_putc(*p, &left);
417 1.77 atatat }
418 1.77 atatat
419 1.77 atatat if (ve->next && left > 0)
420 1.84 simonb (void)printf("%*s", left, "");
421 1.77 atatat }
422 1.77 atatat
423 1.77 atatat void
424 1.82 simonb ucomm(void *arg, VARENT *ve, int mode)
425 1.12 cgd {
426 1.76 thorpej struct kinfo_proc2 *k;
427 1.1 cgd VAR *v;
428 1.12 cgd
429 1.76 thorpej k = arg;
430 1.12 cgd v = ve->var;
431 1.53 simonb strprintorsetwidth(v, k->p_comm, mode);
432 1.1 cgd }
433 1.1 cgd
434 1.12 cgd void
435 1.82 simonb logname(void *arg, VARENT *ve, int mode)
436 1.12 cgd {
437 1.76 thorpej struct kinfo_proc2 *k;
438 1.1 cgd VAR *v;
439 1.12 cgd
440 1.76 thorpej k = arg;
441 1.12 cgd v = ve->var;
442 1.53 simonb strprintorsetwidth(v, k->p_login, mode);
443 1.1 cgd }
444 1.1 cgd
445 1.12 cgd void
446 1.82 simonb state(void *arg, VARENT *ve, int mode)
447 1.12 cgd {
448 1.76 thorpej struct kinfo_proc2 *k;
449 1.51 simonb int flag, is_zombie;
450 1.12 cgd char *cp;
451 1.1 cgd VAR *v;
452 1.1 cgd char buf[16];
453 1.12 cgd
454 1.76 thorpej k = arg;
455 1.51 simonb is_zombie = 0;
456 1.12 cgd v = ve->var;
457 1.51 simonb flag = k->p_flag;
458 1.12 cgd cp = buf;
459 1.1 cgd
460 1.51 simonb switch (k->p_stat) {
461 1.1 cgd
462 1.76 thorpej case LSSTOP:
463 1.1 cgd *cp = 'T';
464 1.1 cgd break;
465 1.1 cgd
466 1.76 thorpej case LSSLEEP:
467 1.76 thorpej if (flag & L_SINTR) /* interruptable (long) */
468 1.66 matt *cp = k->p_slptime >= maxslp ? 'I' : 'S';
469 1.1 cgd else
470 1.10 cgd *cp = 'D';
471 1.1 cgd break;
472 1.1 cgd
473 1.76 thorpej case LSRUN:
474 1.76 thorpej case LSIDL:
475 1.76 thorpej case LSONPROC:
476 1.1 cgd *cp = 'R';
477 1.1 cgd break;
478 1.1 cgd
479 1.76 thorpej case LSZOMB:
480 1.76 thorpej case LSDEAD:
481 1.1 cgd *cp = 'Z';
482 1.51 simonb is_zombie = 1;
483 1.1 cgd break;
484 1.1 cgd
485 1.76 thorpej case LSSUSPENDED:
486 1.76 thorpej *cp = 'U';
487 1.76 thorpej break;
488 1.76 thorpej
489 1.1 cgd default:
490 1.1 cgd *cp = '?';
491 1.1 cgd }
492 1.1 cgd cp++;
493 1.76 thorpej if (flag & L_INMEM) {
494 1.1 cgd } else
495 1.1 cgd *cp++ = 'W';
496 1.51 simonb if (k->p_nice < NZERO)
497 1.1 cgd *cp++ = '<';
498 1.51 simonb else if (k->p_nice > NZERO)
499 1.1 cgd *cp++ = 'N';
500 1.10 cgd if (flag & P_TRACED)
501 1.1 cgd *cp++ = 'X';
502 1.73 christos if (flag & P_SYSTRACE)
503 1.73 christos *cp++ = 'x';
504 1.51 simonb if (flag & P_WEXIT && !is_zombie)
505 1.1 cgd *cp++ = 'E';
506 1.10 cgd if (flag & P_PPWAIT)
507 1.1 cgd *cp++ = 'V';
508 1.57 simonb if (flag & P_SYSTEM)
509 1.57 simonb *cp++ = 'K';
510 1.57 simonb /* system process might have this too, don't need to double up */
511 1.57 simonb else if (k->p_holdcnt)
512 1.1 cgd *cp++ = 'L';
513 1.51 simonb if (k->p_eflag & EPROC_SLEADER)
514 1.1 cgd *cp++ = 's';
515 1.76 thorpej if (flag & P_SA)
516 1.76 thorpej *cp++ = 'a';
517 1.76 thorpej else if (k->p_nlwps > 1)
518 1.76 thorpej *cp++ = 'l';
519 1.51 simonb if ((flag & P_CONTROLT) && k->p__pgid == k->p_tpgid)
520 1.1 cgd *cp++ = '+';
521 1.1 cgd *cp = '\0';
522 1.53 simonb strprintorsetwidth(v, buf, mode);
523 1.1 cgd }
524 1.1 cgd
525 1.12 cgd void
526 1.82 simonb lstate(void *arg, VARENT *ve, int mode)
527 1.76 thorpej {
528 1.76 thorpej struct kinfo_lwp *k;
529 1.76 thorpej int flag, is_zombie;
530 1.76 thorpej char *cp;
531 1.76 thorpej VAR *v;
532 1.76 thorpej char buf[16];
533 1.76 thorpej
534 1.76 thorpej k = arg;
535 1.76 thorpej is_zombie = 0;
536 1.76 thorpej v = ve->var;
537 1.76 thorpej flag = k->l_flag;
538 1.76 thorpej cp = buf;
539 1.76 thorpej
540 1.76 thorpej switch (k->l_stat) {
541 1.76 thorpej
542 1.76 thorpej case LSSTOP:
543 1.76 thorpej *cp = 'T';
544 1.76 thorpej break;
545 1.76 thorpej
546 1.76 thorpej case LSSLEEP:
547 1.81 wiz if (flag & L_SINTR) /* interruptible (long) */
548 1.76 thorpej *cp = k->l_slptime >= maxslp ? 'I' : 'S';
549 1.76 thorpej else
550 1.76 thorpej *cp = 'D';
551 1.76 thorpej break;
552 1.76 thorpej
553 1.76 thorpej case LSRUN:
554 1.76 thorpej case LSIDL:
555 1.76 thorpej case LSONPROC:
556 1.76 thorpej *cp = 'R';
557 1.76 thorpej break;
558 1.76 thorpej
559 1.76 thorpej case LSZOMB:
560 1.76 thorpej case LSDEAD:
561 1.76 thorpej *cp = 'Z';
562 1.76 thorpej is_zombie = 1;
563 1.76 thorpej break;
564 1.76 thorpej
565 1.76 thorpej case LSSUSPENDED:
566 1.76 thorpej *cp = 'U';
567 1.76 thorpej break;
568 1.76 thorpej
569 1.76 thorpej default:
570 1.76 thorpej *cp = '?';
571 1.76 thorpej }
572 1.76 thorpej cp++;
573 1.76 thorpej if (flag & L_INMEM) {
574 1.76 thorpej } else
575 1.76 thorpej *cp++ = 'W';
576 1.76 thorpej if (k->l_holdcnt)
577 1.76 thorpej *cp++ = 'L';
578 1.76 thorpej if (flag & L_DETACHED)
579 1.76 thorpej *cp++ = '-';
580 1.76 thorpej *cp = '\0';
581 1.76 thorpej strprintorsetwidth(v, buf, mode);
582 1.76 thorpej }
583 1.76 thorpej
584 1.76 thorpej void
585 1.82 simonb pnice(void *arg, VARENT *ve, int mode)
586 1.30 ws {
587 1.76 thorpej struct kinfo_proc2 *k;
588 1.30 ws VAR *v;
589 1.30 ws
590 1.76 thorpej k = arg;
591 1.30 ws v = ve->var;
592 1.53 simonb intprintorsetwidth(v, k->p_nice - NZERO, mode);
593 1.30 ws }
594 1.30 ws
595 1.30 ws void
596 1.82 simonb pri(void *arg, VARENT *ve, int mode)
597 1.12 cgd {
598 1.76 thorpej struct kinfo_lwp *l;
599 1.1 cgd VAR *v;
600 1.82 simonb
601 1.76 thorpej l = arg;
602 1.12 cgd v = ve->var;
603 1.76 thorpej intprintorsetwidth(v, l->l_priority - PZERO, mode);
604 1.1 cgd }
605 1.1 cgd
606 1.12 cgd void
607 1.82 simonb uname(void *arg, VARENT *ve, int mode)
608 1.12 cgd {
609 1.76 thorpej struct kinfo_proc2 *k;
610 1.1 cgd VAR *v;
611 1.12 cgd
612 1.76 thorpej k = arg;
613 1.12 cgd v = ve->var;
614 1.53 simonb strprintorsetwidth(v, user_from_uid(k->p_uid, 0), mode);
615 1.1 cgd }
616 1.1 cgd
617 1.12 cgd void
618 1.82 simonb runame(void *arg, VARENT *ve, int mode)
619 1.12 cgd {
620 1.76 thorpej struct kinfo_proc2 *k;
621 1.1 cgd VAR *v;
622 1.12 cgd
623 1.76 thorpej k = arg;
624 1.12 cgd v = ve->var;
625 1.53 simonb strprintorsetwidth(v, user_from_uid(k->p_ruid, 0), mode);
626 1.77 atatat }
627 1.77 atatat
628 1.77 atatat void
629 1.82 simonb svuname(void *arg, VARENT *ve, int mode)
630 1.77 atatat {
631 1.77 atatat struct kinfo_proc2 *k;
632 1.77 atatat VAR *v;
633 1.77 atatat
634 1.77 atatat k = arg;
635 1.77 atatat v = ve->var;
636 1.77 atatat strprintorsetwidth(v, user_from_uid(k->p_svuid, 0), mode);
637 1.77 atatat }
638 1.77 atatat
639 1.77 atatat void
640 1.82 simonb gname(void *arg, VARENT *ve, int mode)
641 1.77 atatat {
642 1.77 atatat struct kinfo_proc2 *k;
643 1.77 atatat VAR *v;
644 1.77 atatat
645 1.77 atatat k = arg;
646 1.77 atatat v = ve->var;
647 1.77 atatat strprintorsetwidth(v, group_from_gid(k->p_gid, 0), mode);
648 1.77 atatat }
649 1.77 atatat
650 1.77 atatat void
651 1.82 simonb rgname(void *arg, VARENT *ve, int mode)
652 1.77 atatat {
653 1.77 atatat struct kinfo_proc2 *k;
654 1.77 atatat VAR *v;
655 1.77 atatat
656 1.77 atatat k = arg;
657 1.77 atatat v = ve->var;
658 1.77 atatat strprintorsetwidth(v, group_from_gid(k->p_rgid, 0), mode);
659 1.77 atatat }
660 1.77 atatat
661 1.77 atatat void
662 1.82 simonb svgname(void *arg, VARENT *ve, int mode)
663 1.77 atatat {
664 1.77 atatat struct kinfo_proc2 *k;
665 1.77 atatat VAR *v;
666 1.77 atatat
667 1.77 atatat k = arg;
668 1.77 atatat v = ve->var;
669 1.77 atatat strprintorsetwidth(v, group_from_gid(k->p_svgid, 0), mode);
670 1.1 cgd }
671 1.1 cgd
672 1.12 cgd void
673 1.82 simonb tdev(void *arg, VARENT *ve, int mode)
674 1.12 cgd {
675 1.76 thorpej struct kinfo_proc2 *k;
676 1.1 cgd VAR *v;
677 1.12 cgd dev_t dev;
678 1.12 cgd char buff[16];
679 1.1 cgd
680 1.76 thorpej k = arg;
681 1.12 cgd v = ve->var;
682 1.51 simonb dev = k->p_tdev;
683 1.53 simonb if (dev == NODEV) {
684 1.53 simonb if (mode == PRINTMODE)
685 1.53 simonb (void)printf("%*s", v->width, "??");
686 1.78 dsl else
687 1.78 dsl if (v->width < 2)
688 1.78 dsl v->width = 2;
689 1.53 simonb } else {
690 1.12 cgd (void)snprintf(buff, sizeof(buff),
691 1.12 cgd "%d/%d", major(dev), minor(dev));
692 1.53 simonb strprintorsetwidth(v, buff, mode);
693 1.1 cgd }
694 1.1 cgd }
695 1.1 cgd
696 1.12 cgd void
697 1.82 simonb tname(void *arg, VARENT *ve, int mode)
698 1.12 cgd {
699 1.76 thorpej struct kinfo_proc2 *k;
700 1.1 cgd VAR *v;
701 1.1 cgd dev_t dev;
702 1.38 mycroft const char *ttname;
703 1.53 simonb int noctty;
704 1.82 simonb
705 1.76 thorpej k = arg;
706 1.12 cgd v = ve->var;
707 1.51 simonb dev = k->p_tdev;
708 1.53 simonb if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) {
709 1.53 simonb if (mode == PRINTMODE)
710 1.53 simonb (void)printf("%-*s", v->width, "??");
711 1.78 dsl else
712 1.78 dsl if (v->width < 2)
713 1.78 dsl v->width = 2;
714 1.53 simonb } else {
715 1.44 mrg if (strncmp(ttname, "tty", 3) == 0 ||
716 1.44 mrg strncmp(ttname, "dty", 3) == 0)
717 1.1 cgd ttname += 3;
718 1.53 simonb noctty = !(k->p_eflag & EPROC_CTTY) ? 1 : 0;
719 1.53 simonb if (mode == WIDTHMODE) {
720 1.53 simonb int fmtlen;
721 1.53 simonb
722 1.53 simonb fmtlen = strlen(ttname) + noctty;
723 1.53 simonb if (v->width < fmtlen)
724 1.54 simonb v->width = fmtlen;
725 1.53 simonb } else {
726 1.53 simonb if (noctty)
727 1.84 simonb (void)printf("%-*s-", v->width - 1, ttname);
728 1.53 simonb else
729 1.84 simonb (void)printf("%-*s", v->width, ttname);
730 1.53 simonb }
731 1.1 cgd }
732 1.1 cgd }
733 1.1 cgd
734 1.12 cgd void
735 1.82 simonb longtname(void *arg, VARENT *ve, int mode)
736 1.12 cgd {
737 1.76 thorpej struct kinfo_proc2 *k;
738 1.1 cgd VAR *v;
739 1.1 cgd dev_t dev;
740 1.38 mycroft const char *ttname;
741 1.1 cgd
742 1.76 thorpej k = arg;
743 1.12 cgd v = ve->var;
744 1.51 simonb dev = k->p_tdev;
745 1.53 simonb if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) {
746 1.53 simonb if (mode == PRINTMODE)
747 1.53 simonb (void)printf("%-*s", v->width, "??");
748 1.78 dsl else
749 1.78 dsl if (v->width < 2)
750 1.78 dsl v->width = 2;
751 1.78 dsl } else {
752 1.53 simonb strprintorsetwidth(v, ttname, mode);
753 1.53 simonb }
754 1.1 cgd }
755 1.1 cgd
756 1.12 cgd void
757 1.82 simonb started(void *arg, VARENT *ve, int mode)
758 1.12 cgd {
759 1.76 thorpej struct kinfo_proc2 *k;
760 1.1 cgd VAR *v;
761 1.1 cgd static time_t now;
762 1.24 cgd time_t startt;
763 1.1 cgd struct tm *tp;
764 1.53 simonb char buf[100], *cp;
765 1.1 cgd
766 1.76 thorpej k = arg;
767 1.12 cgd v = ve->var;
768 1.51 simonb if (!k->p_uvalid) {
769 1.53 simonb if (mode == PRINTMODE)
770 1.53 simonb (void)printf("%*s", v->width, "-");
771 1.1 cgd return;
772 1.1 cgd }
773 1.1 cgd
774 1.51 simonb startt = k->p_ustart_sec;
775 1.24 cgd tp = localtime(&startt);
776 1.1 cgd if (!now)
777 1.1 cgd (void)time(&now);
778 1.53 simonb if (now - k->p_ustart_sec < SECSPERDAY)
779 1.12 cgd /* I *hate* SCCS... */
780 1.53 simonb (void)strftime(buf, sizeof(buf) - 1, "%l:%" "M%p", tp);
781 1.53 simonb else if (now - k->p_ustart_sec < DAYSPERWEEK * SECSPERDAY)
782 1.12 cgd /* I *hate* SCCS... */
783 1.53 simonb (void)strftime(buf, sizeof(buf) - 1, "%a%" "I%p", tp);
784 1.53 simonb else
785 1.12 cgd (void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
786 1.53 simonb /* %e and %l can start with a space. */
787 1.53 simonb cp = buf;
788 1.53 simonb if (*cp == ' ')
789 1.53 simonb cp++;
790 1.53 simonb strprintorsetwidth(v, cp, mode);
791 1.1 cgd }
792 1.1 cgd
793 1.12 cgd void
794 1.82 simonb lstarted(void *arg, VARENT *ve, int mode)
795 1.82 simonb {
796 1.76 thorpej struct kinfo_proc2 *k;
797 1.1 cgd VAR *v;
798 1.24 cgd time_t startt;
799 1.1 cgd char buf[100];
800 1.1 cgd
801 1.76 thorpej k = arg;
802 1.12 cgd v = ve->var;
803 1.51 simonb if (!k->p_uvalid) {
804 1.53 simonb /*
805 1.53 simonb * Minimum width is less than header - we don't
806 1.53 simonb * need to check it every time.
807 1.53 simonb */
808 1.53 simonb if (mode == PRINTMODE)
809 1.53 simonb (void)printf("%*s", v->width, "-");
810 1.1 cgd return;
811 1.1 cgd }
812 1.51 simonb startt = k->p_ustart_sec;
813 1.53 simonb
814 1.53 simonb /* assume all times are the same length */
815 1.53 simonb if (mode != WIDTHMODE || v->width == 0) {
816 1.53 simonb (void)strftime(buf, sizeof(buf) -1, "%c",
817 1.53 simonb localtime(&startt));
818 1.53 simonb strprintorsetwidth(v, buf, mode);
819 1.53 simonb }
820 1.1 cgd }
821 1.1 cgd
822 1.12 cgd void
823 1.82 simonb wchan(void *arg, VARENT *ve, int mode)
824 1.12 cgd {
825 1.76 thorpej struct kinfo_lwp *l;
826 1.1 cgd VAR *v;
827 1.53 simonb char *buf;
828 1.12 cgd
829 1.76 thorpej l = arg;
830 1.12 cgd v = ve->var;
831 1.76 thorpej if (l->l_wchan) {
832 1.76 thorpej if (l->l_wmesg) {
833 1.76 thorpej strprintorsetwidth(v, l->l_wmesg, mode);
834 1.78 dsl v->width = min(v->width, KI_WMESGLEN);
835 1.53 simonb } else {
836 1.78 dsl (void)asprintf(&buf, "%-*" PRIx64, v->width,
837 1.78 dsl l->l_wchan);
838 1.53 simonb if (buf == NULL)
839 1.53 simonb err(1, "%s", "");
840 1.53 simonb strprintorsetwidth(v, buf, mode);
841 1.78 dsl v->width = min(v->width, KI_WMESGLEN);
842 1.53 simonb free(buf);
843 1.53 simonb }
844 1.53 simonb } else {
845 1.53 simonb if (mode == PRINTMODE)
846 1.53 simonb (void)printf("%-*s", v->width, "-");
847 1.53 simonb }
848 1.1 cgd }
849 1.1 cgd
850 1.86 simonb #define pgtok(a) (((a)*getpagesize())/1024)
851 1.1 cgd
852 1.12 cgd void
853 1.82 simonb vsize(void *arg, VARENT *ve, int mode)
854 1.12 cgd {
855 1.76 thorpej struct kinfo_proc2 *k;
856 1.1 cgd VAR *v;
857 1.12 cgd
858 1.76 thorpej k = arg;
859 1.12 cgd v = ve->var;
860 1.53 simonb intprintorsetwidth(v,
861 1.53 simonb pgtok(k->p_vm_dsize + k->p_vm_ssize + k->p_vm_tsize), mode);
862 1.1 cgd }
863 1.1 cgd
864 1.12 cgd void
865 1.82 simonb rssize(void *arg, VARENT *ve, int mode)
866 1.12 cgd {
867 1.76 thorpej struct kinfo_proc2 *k;
868 1.1 cgd VAR *v;
869 1.12 cgd
870 1.76 thorpej k = arg;
871 1.12 cgd v = ve->var;
872 1.1 cgd /* XXX don't have info about shared */
873 1.53 simonb intprintorsetwidth(v, pgtok(k->p_vm_rssize), mode);
874 1.1 cgd }
875 1.1 cgd
876 1.12 cgd void
877 1.82 simonb p_rssize(void *arg, VARENT *ve, int mode) /* doesn't account for text */
878 1.12 cgd {
879 1.76 thorpej struct kinfo_proc2 *k;
880 1.1 cgd VAR *v;
881 1.12 cgd
882 1.76 thorpej k = arg;
883 1.12 cgd v = ve->var;
884 1.53 simonb intprintorsetwidth(v, pgtok(k->p_vm_rssize), mode);
885 1.1 cgd }
886 1.1 cgd
887 1.12 cgd void
888 1.82 simonb cputime(void *arg, VARENT *ve, int mode)
889 1.12 cgd {
890 1.76 thorpej struct kinfo_proc2 *k;
891 1.1 cgd VAR *v;
892 1.71 martin int32_t secs;
893 1.71 martin int32_t psecs; /* "parts" of a second. first micro, then centi */
894 1.53 simonb int fmtlen;
895 1.1 cgd
896 1.76 thorpej k = arg;
897 1.12 cgd v = ve->var;
898 1.51 simonb if (P_ZOMBIE(k) || k->p_uvalid == 0) {
899 1.1 cgd secs = 0;
900 1.1 cgd psecs = 0;
901 1.1 cgd } else {
902 1.12 cgd /*
903 1.12 cgd * This counts time spent handling interrupts. We could
904 1.12 cgd * fix this, but it is not 100% trivial (and interrupt
905 1.12 cgd * time fractions only work on the sparc anyway). XXX
906 1.12 cgd */
907 1.51 simonb secs = k->p_rtime_sec;
908 1.51 simonb psecs = k->p_rtime_usec;
909 1.1 cgd if (sumrusage) {
910 1.51 simonb secs += k->p_uctime_sec;
911 1.51 simonb psecs += k->p_uctime_usec;
912 1.1 cgd }
913 1.1 cgd /*
914 1.1 cgd * round and scale to 100's
915 1.1 cgd */
916 1.1 cgd psecs = (psecs + 5000) / 10000;
917 1.1 cgd secs += psecs / 100;
918 1.1 cgd psecs = psecs % 100;
919 1.1 cgd }
920 1.53 simonb if (mode == WIDTHMODE) {
921 1.53 simonb /*
922 1.83 simonb * Ugg, this is the only field where a value of 0 is longer
923 1.78 dsl * than the column title.
924 1.53 simonb * Use SECSPERMIN, because secs is divided by that when
925 1.78 dsl * passed to iwidth().
926 1.53 simonb */
927 1.78 dsl if (secs == 0)
928 1.53 simonb secs = SECSPERMIN;
929 1.78 dsl
930 1.53 simonb if (secs > v->longestp) {
931 1.53 simonb v->longestp = secs;
932 1.78 dsl /* "+6" for the ":%02ld.%02ld" in the printf() below */
933 1.78 dsl fmtlen = iwidth(secs / SECSPERMIN) + 6;
934 1.53 simonb if (fmtlen > v->width)
935 1.53 simonb v->width = fmtlen;
936 1.53 simonb }
937 1.53 simonb } else {
938 1.84 simonb (void)printf("%*ld:%02ld.%02ld", v->width - 6,
939 1.84 simonb (long)(secs / SECSPERMIN), (long)(secs % SECSPERMIN),
940 1.84 simonb (long)psecs);
941 1.53 simonb }
942 1.1 cgd }
943 1.1 cgd
944 1.1 cgd double
945 1.1 cgd getpcpu(k)
946 1.51 simonb struct kinfo_proc2 *k;
947 1.1 cgd {
948 1.1 cgd static int failure;
949 1.1 cgd
950 1.1 cgd if (!nlistread)
951 1.45 jdolecek failure = (kd) ? donlist() : 1;
952 1.1 cgd if (failure)
953 1.1 cgd return (0.0);
954 1.1 cgd
955 1.1 cgd #define fxtofl(fixpt) ((double)(fixpt) / fscale)
956 1.1 cgd
957 1.1 cgd /* XXX - I don't like this */
958 1.76 thorpej if (k->p_swtime == 0 || (k->p_flag & L_INMEM) == 0 ||
959 1.80 jdolecek k->p_stat == SZOMB)
960 1.1 cgd return (0.0);
961 1.1 cgd if (rawcpu)
962 1.51 simonb return (100.0 * fxtofl(k->p_pctcpu));
963 1.51 simonb return (100.0 * fxtofl(k->p_pctcpu) /
964 1.51 simonb (1.0 - exp(k->p_swtime * log(ccpu))));
965 1.1 cgd }
966 1.1 cgd
967 1.12 cgd void
968 1.82 simonb pcpu(void *arg, VARENT *ve, int mode)
969 1.12 cgd {
970 1.76 thorpej struct kinfo_proc2 *k;
971 1.1 cgd VAR *v;
972 1.12 cgd
973 1.76 thorpej k = arg;
974 1.12 cgd v = ve->var;
975 1.53 simonb doubleprintorsetwidth(v, getpcpu(k), 1, mode);
976 1.1 cgd }
977 1.1 cgd
978 1.1 cgd double
979 1.1 cgd getpmem(k)
980 1.51 simonb struct kinfo_proc2 *k;
981 1.1 cgd {
982 1.1 cgd static int failure;
983 1.1 cgd double fracmem;
984 1.1 cgd int szptudot;
985 1.1 cgd
986 1.1 cgd if (!nlistread)
987 1.45 jdolecek failure = (kd) ? donlist() : 1;
988 1.1 cgd if (failure)
989 1.1 cgd return (0.0);
990 1.1 cgd
991 1.76 thorpej if ((k->p_flag & L_INMEM) == 0)
992 1.1 cgd return (0.0);
993 1.1 cgd /* XXX want pmap ptpages, segtab, etc. (per architecture) */
994 1.66 matt szptudot = uspace/getpagesize();
995 1.1 cgd /* XXX don't have info about shared */
996 1.51 simonb fracmem = ((float)k->p_vm_rssize + szptudot)/mempages;
997 1.1 cgd return (100.0 * fracmem);
998 1.1 cgd }
999 1.1 cgd
1000 1.12 cgd void
1001 1.82 simonb pmem(void *arg, VARENT *ve, int mode)
1002 1.12 cgd {
1003 1.76 thorpej struct kinfo_proc2 *k;
1004 1.1 cgd VAR *v;
1005 1.12 cgd
1006 1.76 thorpej k = arg;
1007 1.12 cgd v = ve->var;
1008 1.53 simonb doubleprintorsetwidth(v, getpmem(k), 1, mode);
1009 1.1 cgd }
1010 1.1 cgd
1011 1.12 cgd void
1012 1.82 simonb pagein(void *arg, VARENT *ve, int mode)
1013 1.12 cgd {
1014 1.76 thorpej struct kinfo_proc2 *k;
1015 1.1 cgd VAR *v;
1016 1.12 cgd
1017 1.76 thorpej k = arg;
1018 1.12 cgd v = ve->var;
1019 1.53 simonb intprintorsetwidth(v, k->p_uvalid ? k->p_uru_majflt : 0, mode);
1020 1.1 cgd }
1021 1.1 cgd
1022 1.12 cgd void
1023 1.82 simonb maxrss(void *arg, VARENT *ve, int mode)
1024 1.12 cgd {
1025 1.1 cgd VAR *v;
1026 1.12 cgd
1027 1.12 cgd v = ve->var;
1028 1.53 simonb /* No need to check width! */
1029 1.53 simonb if (mode == PRINTMODE)
1030 1.53 simonb (void)printf("%*s", v->width, "-");
1031 1.1 cgd }
1032 1.1 cgd
1033 1.12 cgd void
1034 1.82 simonb tsize(void *arg, VARENT *ve, int mode)
1035 1.12 cgd {
1036 1.76 thorpej struct kinfo_proc2 *k;
1037 1.1 cgd VAR *v;
1038 1.12 cgd
1039 1.76 thorpej k = arg;
1040 1.12 cgd v = ve->var;
1041 1.53 simonb intprintorsetwidth(v, pgtok(k->p_vm_tsize), mode);
1042 1.1 cgd }
1043 1.1 cgd
1044 1.1 cgd /*
1045 1.1 cgd * Generic output routines. Print fields from various prototype
1046 1.1 cgd * structures.
1047 1.1 cgd */
1048 1.12 cgd static void
1049 1.53 simonb printval(bp, v, mode)
1050 1.53 simonb void *bp;
1051 1.1 cgd VAR *v;
1052 1.53 simonb int mode;
1053 1.1 cgd {
1054 1.1 cgd static char ofmt[32] = "%";
1055 1.53 simonb int width, vok, fmtlen;
1056 1.78 dsl char *fcp, *cp;
1057 1.78 dsl int64_t val;
1058 1.78 dsl u_int64_t uval;
1059 1.53 simonb
1060 1.53 simonb /*
1061 1.53 simonb * Note that the "INF127" check is nonsensical for types
1062 1.53 simonb * that are or can be signed.
1063 1.53 simonb */
1064 1.53 simonb #define GET(type) (*(type *)bp)
1065 1.53 simonb #define CHK_INF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n))
1066 1.53 simonb
1067 1.53 simonb #define VSIGN 1
1068 1.53 simonb #define VUNSIGN 2
1069 1.53 simonb #define VPTR 3
1070 1.53 simonb
1071 1.53 simonb if (mode == WIDTHMODE) {
1072 1.53 simonb vok = 0;
1073 1.53 simonb switch (v->type) {
1074 1.53 simonb case CHAR:
1075 1.53 simonb val = GET(char);
1076 1.53 simonb vok = VSIGN;
1077 1.53 simonb break;
1078 1.53 simonb case UCHAR:
1079 1.53 simonb uval = CHK_INF127(GET(u_char));
1080 1.53 simonb vok = VUNSIGN;
1081 1.53 simonb break;
1082 1.53 simonb case SHORT:
1083 1.53 simonb val = GET(short);
1084 1.53 simonb vok = VSIGN;
1085 1.53 simonb break;
1086 1.53 simonb case USHORT:
1087 1.53 simonb uval = CHK_INF127(GET(u_short));
1088 1.53 simonb vok = VUNSIGN;
1089 1.53 simonb break;
1090 1.53 simonb case INT32:
1091 1.53 simonb val = GET(int32_t);
1092 1.53 simonb vok = VSIGN;
1093 1.53 simonb break;
1094 1.53 simonb case INT:
1095 1.53 simonb val = GET(int);
1096 1.53 simonb vok = VSIGN;
1097 1.53 simonb break;
1098 1.53 simonb case UINT:
1099 1.53 simonb case UINT32:
1100 1.53 simonb uval = CHK_INF127(GET(u_int));
1101 1.53 simonb vok = VUNSIGN;
1102 1.53 simonb break;
1103 1.53 simonb case LONG:
1104 1.53 simonb val = GET(long);
1105 1.53 simonb vok = VSIGN;
1106 1.53 simonb break;
1107 1.53 simonb case ULONG:
1108 1.53 simonb uval = CHK_INF127(GET(u_long));
1109 1.53 simonb vok = VUNSIGN;
1110 1.53 simonb break;
1111 1.53 simonb case KPTR:
1112 1.78 dsl uval = GET(u_int64_t);
1113 1.53 simonb vok = VPTR;
1114 1.53 simonb break;
1115 1.53 simonb case KPTR24:
1116 1.78 dsl uval = GET(u_int64_t);
1117 1.58 itojun uval &= 0xffffff;
1118 1.53 simonb vok = VPTR;
1119 1.53 simonb break;
1120 1.72 nathanw case INT64:
1121 1.78 dsl val = GET(int64_t);
1122 1.72 nathanw vok = VSIGN;
1123 1.72 nathanw break;
1124 1.72 nathanw case UINT64:
1125 1.78 dsl uval = CHK_INF127(GET(u_int64_t));
1126 1.72 nathanw vok = VUNSIGN;
1127 1.72 nathanw break;
1128 1.72 nathanw
1129 1.78 dsl case SIGLIST:
1130 1.53 simonb default:
1131 1.53 simonb /* nothing... */;
1132 1.53 simonb }
1133 1.53 simonb switch (vok) {
1134 1.53 simonb case VSIGN:
1135 1.78 dsl if (val < 0 && val < v->longestn) {
1136 1.53 simonb v->longestn = val;
1137 1.78 dsl fmtlen = iwidth(-val) + 1;
1138 1.53 simonb if (fmtlen > v->width)
1139 1.53 simonb v->width = fmtlen;
1140 1.53 simonb } else if (val > 0 && val > v->longestp) {
1141 1.53 simonb v->longestp = val;
1142 1.78 dsl fmtlen = iwidth(val);
1143 1.53 simonb if (fmtlen > v->width)
1144 1.53 simonb v->width = fmtlen;
1145 1.53 simonb }
1146 1.53 simonb return;
1147 1.53 simonb case VUNSIGN:
1148 1.53 simonb if (uval > v->longestu) {
1149 1.53 simonb v->longestu = uval;
1150 1.78 dsl v->width = iwidth(uval);
1151 1.53 simonb }
1152 1.53 simonb return;
1153 1.53 simonb case VPTR:
1154 1.53 simonb fmtlen = 0;
1155 1.53 simonb while (uval > 0) {
1156 1.53 simonb uval >>= 4;
1157 1.53 simonb fmtlen++;
1158 1.53 simonb }
1159 1.53 simonb if (fmtlen > v->width)
1160 1.53 simonb v->width = fmtlen;
1161 1.53 simonb return;
1162 1.53 simonb }
1163 1.53 simonb }
1164 1.1 cgd
1165 1.53 simonb width = v->width;
1166 1.12 cgd cp = ofmt + 1;
1167 1.12 cgd fcp = v->fmt;
1168 1.1 cgd if (v->flag & LJUST)
1169 1.1 cgd *cp++ = '-';
1170 1.1 cgd *cp++ = '*';
1171 1.33 christos while ((*cp++ = *fcp++) != '\0')
1172 1.33 christos continue;
1173 1.1 cgd
1174 1.1 cgd switch (v->type) {
1175 1.1 cgd case CHAR:
1176 1.53 simonb (void)printf(ofmt, width, GET(char));
1177 1.53 simonb return;
1178 1.1 cgd case UCHAR:
1179 1.53 simonb (void)printf(ofmt, width, CHK_INF127(GET(u_char)));
1180 1.53 simonb return;
1181 1.1 cgd case SHORT:
1182 1.53 simonb (void)printf(ofmt, width, GET(short));
1183 1.53 simonb return;
1184 1.1 cgd case USHORT:
1185 1.53 simonb (void)printf(ofmt, width, CHK_INF127(GET(u_short)));
1186 1.53 simonb return;
1187 1.19 cgd case INT:
1188 1.53 simonb (void)printf(ofmt, width, GET(int));
1189 1.53 simonb return;
1190 1.19 cgd case UINT:
1191 1.53 simonb (void)printf(ofmt, width, CHK_INF127(GET(u_int)));
1192 1.53 simonb return;
1193 1.1 cgd case LONG:
1194 1.53 simonb (void)printf(ofmt, width, GET(long));
1195 1.53 simonb return;
1196 1.1 cgd case ULONG:
1197 1.53 simonb (void)printf(ofmt, width, CHK_INF127(GET(u_long)));
1198 1.53 simonb return;
1199 1.1 cgd case KPTR:
1200 1.78 dsl (void)printf(ofmt, width, GET(u_int64_t));
1201 1.53 simonb return;
1202 1.41 mrg case KPTR24:
1203 1.78 dsl (void)printf(ofmt, width, GET(u_int64_t) & 0xffffff);
1204 1.78 dsl return;
1205 1.78 dsl case INT32:
1206 1.78 dsl (void)printf(ofmt, width, GET(int32_t));
1207 1.78 dsl return;
1208 1.78 dsl case UINT32:
1209 1.78 dsl (void)printf(ofmt, width, CHK_INF127(GET(u_int32_t)));
1210 1.53 simonb return;
1211 1.40 christos case SIGLIST:
1212 1.40 christos {
1213 1.40 christos sigset_t *s = (sigset_t *)(void *)bp;
1214 1.40 christos size_t i;
1215 1.86 simonb #define SIGSETSIZE (sizeof(s->__bits) / sizeof(s->__bits[0]))
1216 1.40 christos char buf[SIGSETSIZE * 8 + 1];
1217 1.40 christos
1218 1.40 christos for (i = 0; i < SIGSETSIZE; i++)
1219 1.40 christos (void)snprintf(&buf[i * 8], 9, "%.8x",
1220 1.40 christos s->__bits[(SIGSETSIZE - 1) - i]);
1221 1.40 christos
1222 1.40 christos /* Skip leading zeroes */
1223 1.78 dsl for (i = 0; buf[i] == '0'; i++)
1224 1.78 dsl continue;
1225 1.40 christos
1226 1.40 christos if (buf[i] == '\0')
1227 1.40 christos i--;
1228 1.78 dsl strprintorsetwidth(v, buf + i, mode);
1229 1.78 dsl #undef SIGSETSIZE
1230 1.40 christos }
1231 1.78 dsl return;
1232 1.72 nathanw case INT64:
1233 1.78 dsl (void)printf(ofmt, width, GET(int64_t));
1234 1.72 nathanw return;
1235 1.72 nathanw case UINT64:
1236 1.78 dsl (void)printf(ofmt, width, CHK_INF127(GET(u_int64_t)));
1237 1.72 nathanw return;
1238 1.1 cgd default:
1239 1.12 cgd errx(1, "unknown type %d", v->type);
1240 1.1 cgd }
1241 1.25 cgd #undef GET
1242 1.26 cgd #undef CHK_INF127
1243 1.12 cgd }
1244 1.12 cgd
1245 1.12 cgd void
1246 1.82 simonb pvar(void *arg, VARENT *ve, int mode)
1247 1.12 cgd {
1248 1.12 cgd VAR *v;
1249 1.12 cgd
1250 1.12 cgd v = ve->var;
1251 1.78 dsl if (v->flag & UAREA && !((struct kinfo_proc2 *)arg)->p_uvalid) {
1252 1.78 dsl if (mode == PRINTMODE)
1253 1.78 dsl (void)printf("%*s", v->width, "-");
1254 1.78 dsl return;
1255 1.78 dsl }
1256 1.78 dsl
1257 1.84 simonb (void)printval((char *)arg + v->off, v, mode);
1258 1.78 dsl }
1259 1.78 dsl
1260 1.78 dsl void
1261 1.82 simonb putimeval(void *arg, VARENT *ve, int mode)
1262 1.78 dsl {
1263 1.78 dsl VAR *v = ve->var;
1264 1.78 dsl struct kinfo_proc2 *k = arg;
1265 1.78 dsl ulong secs = *(uint32_t *)((char *)arg + v->off);
1266 1.78 dsl ulong usec = *(uint32_t *)((char *)arg + v->off + sizeof (uint32_t));
1267 1.78 dsl int fmtlen;
1268 1.78 dsl
1269 1.78 dsl if (!k->p_uvalid) {
1270 1.78 dsl if (mode == PRINTMODE)
1271 1.78 dsl (void)printf("%*s", v->width, "-");
1272 1.78 dsl return;
1273 1.78 dsl }
1274 1.78 dsl
1275 1.78 dsl if (mode == WIDTHMODE) {
1276 1.78 dsl if (!secs)
1277 1.78 dsl /* zero doesn't give correct width... */
1278 1.78 dsl secs = 1;
1279 1.78 dsl if (secs > v->longestu) {
1280 1.78 dsl v->longestu = secs;
1281 1.78 dsl if (secs <= 999)
1282 1.78 dsl /* sss.ssssss */
1283 1.78 dsl fmtlen = iwidth(secs) + 6 + 1;
1284 1.78 dsl else
1285 1.78 dsl /* hh:mm:ss.ss */
1286 1.85 simonb fmtlen = iwidth((secs + 1) / SECSPERHOUR)
1287 1.78 dsl + 2 + 1 + 2 + 1 + 2 + 1;
1288 1.78 dsl if (fmtlen > v->width)
1289 1.78 dsl v->width = fmtlen;
1290 1.78 dsl }
1291 1.78 dsl return;
1292 1.78 dsl }
1293 1.78 dsl
1294 1.78 dsl if (secs < 999)
1295 1.78 dsl (void)printf( "%*lu.%.6lu", v->width - 6 - 1, secs, usec);
1296 1.78 dsl else {
1297 1.78 dsl uint h, m;
1298 1.78 dsl usec += 5000;
1299 1.78 dsl if (usec >= 1000000) {
1300 1.78 dsl usec -= 1000000;
1301 1.78 dsl secs++;
1302 1.78 dsl }
1303 1.85 simonb m = secs / SECSPERMIN;
1304 1.85 simonb secs -= m * SECSPERMIN;
1305 1.85 simonb h = m / MINSPERHOUR;
1306 1.85 simonb m -= h * MINSPERHOUR;
1307 1.84 simonb (void)printf( "%*u:%.2u:%.2lu.%.2lu", v->width - 9, h, m, secs,
1308 1.84 simonb usec / 10000u );
1309 1.78 dsl }
1310 1.1 cgd }
1311