xref: /netbsd-src/bin/ps/print.c (revision 7c674e8e6e818717bee65b1f985c9e2a9f0126bd)
1*7c674e8eSandvar /*	$NetBSD: print.c,v 1.138 2022/01/26 11:48:53 andvar Exp $	*/
249f0ad86Scgd 
3d530ee00Ssimonb /*
48966ad6aSad  * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
5d530ee00Ssimonb  * All rights reserved.
6d530ee00Ssimonb  *
7d530ee00Ssimonb  * This code is derived from software contributed to The NetBSD Foundation
8d530ee00Ssimonb  * by Simon Burge.
9d530ee00Ssimonb  *
10d530ee00Ssimonb  * Redistribution and use in source and binary forms, with or without
11d530ee00Ssimonb  * modification, are permitted provided that the following conditions
12d530ee00Ssimonb  * are met:
13d530ee00Ssimonb  * 1. Redistributions of source code must retain the above copyright
14d530ee00Ssimonb  *    notice, this list of conditions and the following disclaimer.
15d530ee00Ssimonb  * 2. Redistributions in binary form must reproduce the above copyright
16d530ee00Ssimonb  *    notice, this list of conditions and the following disclaimer in the
17d530ee00Ssimonb  *    documentation and/or other materials provided with the distribution.
18d530ee00Ssimonb  *
19d530ee00Ssimonb  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20d530ee00Ssimonb  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21d530ee00Ssimonb  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22d530ee00Ssimonb  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23d530ee00Ssimonb  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24d530ee00Ssimonb  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25d530ee00Ssimonb  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26d530ee00Ssimonb  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27d530ee00Ssimonb  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28d530ee00Ssimonb  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29d530ee00Ssimonb  * POSSIBILITY OF SUCH DAMAGE.
30d530ee00Ssimonb  */
31d530ee00Ssimonb 
32d530ee00Ssimonb /*
334d1457ceScgd  * Copyright (c) 1990, 1993, 1994
344d1457ceScgd  *	The Regents of the University of California.  All rights reserved.
3561f28255Scgd  *
3661f28255Scgd  * Redistribution and use in source and binary forms, with or without
3761f28255Scgd  * modification, are permitted provided that the following conditions
3861f28255Scgd  * are met:
3961f28255Scgd  * 1. Redistributions of source code must retain the above copyright
4061f28255Scgd  *    notice, this list of conditions and the following disclaimer.
4161f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
4261f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
4361f28255Scgd  *    documentation and/or other materials provided with the distribution.
44b5b29542Sagc  * 3. Neither the name of the University nor the names of its contributors
4561f28255Scgd  *    may be used to endorse or promote products derived from this software
4661f28255Scgd  *    without specific prior written permission.
4761f28255Scgd  *
4861f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
4961f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5061f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5161f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
5261f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5361f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5461f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5561f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5661f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5761f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5861f28255Scgd  * SUCH DAMAGE.
5961f28255Scgd  */
6061f28255Scgd 
6178295c8bSchristos #include <sys/cdefs.h>
6261f28255Scgd #ifndef lint
6349f0ad86Scgd #if 0
644d1457ceScgd static char sccsid[] = "@(#)print.c	8.6 (Berkeley) 4/16/94";
6549f0ad86Scgd #else
66*7c674e8eSandvar __RCSID("$NetBSD: print.c,v 1.138 2022/01/26 11:48:53 andvar Exp $");
6749f0ad86Scgd #endif
6861f28255Scgd #endif /* not lint */
6961f28255Scgd 
7061f28255Scgd #include <sys/param.h>
7161f28255Scgd #include <sys/time.h>
7261f28255Scgd #include <sys/resource.h>
73c879b655Schristos #include <sys/sysctl.h>
743fdac2b8Sthorpej #include <sys/lwp.h>
7561f28255Scgd #include <sys/proc.h>
7661f28255Scgd #include <sys/stat.h>
7761f28255Scgd #include <sys/ucred.h>
784d1457ceScgd #include <sys/sysctl.h>
79c879b655Schristos #include <sys/acct.h>
809dc307c4Schristos #include <sys/ktrace.h>
8179ddb78aSmrg 
824d1457ceScgd #include <err.h>
8340f30459Satatat #include <grp.h>
843541700dSmycroft #include <kvm.h>
854d1457ceScgd #include <math.h>
864d1457ceScgd #include <nlist.h>
87e0b43395Sexplorer #include <pwd.h>
884d1457ceScgd #include <stddef.h>
894d1457ceScgd #include <stdio.h>
904d1457ceScgd #include <stdlib.h>
914d1457ceScgd #include <string.h>
9215fbf68cSkleink #include <time.h>
93c879b655Schristos #include <util.h>
944d1457ceScgd #include <tzfile.h>
955dad1439Scgd #include <unistd.h>
96c879b655Schristos #include <signal.h>
974d1457ceScgd 
984d1457ceScgd #include "ps.h"
994d1457ceScgd 
10053474900Ssimonb static char *cmdpart(char *);
1014e3b1a0bSdholland static void  printval(void *, VAR *, enum mode);
10253474900Ssimonb static int   titlecmp(char *, char **);
1033541700dSmycroft 
1044e3b1a0bSdholland static void  doubleprintorsetwidth(VAR *, double, int, enum mode);
1054e3b1a0bSdholland static void  intprintorsetwidth(VAR *, int, enum mode);
1064e3b1a0bSdholland static void  strprintorsetwidth(VAR *, const char *, enum mode);
107a98dd470Ssimonb 
10863e11689Ssimonb static time_t now;
10963e11689Ssimonb 
1107fb9269eSmycroft #define	min(a,b)	((a) <= (b) ? (a) : (b))
111f24cb256Sdsl 
11241a1344dSkamil /* pre-NetBSD 5.x support. */
11341a1344dSkamil #ifndef LSDEAD
11441a1344dSkamil #define LSDEAD 6
11541a1344dSkamil #endif
11641a1344dSkamil 
1170d5e2b23Schristos static void __attribute__((__format__(__strftime__, 3, 0)))
safe_strftime(char * buf,size_t bufsiz,const char * fmt,const struct tm * tp)1180d5e2b23Schristos safe_strftime(char *buf, size_t bufsiz, const char *fmt,
1190d5e2b23Schristos     const struct tm *tp)
1200d5e2b23Schristos {
1210d5e2b23Schristos 	if (tp == NULL || strftime(buf, bufsiz, fmt, tp) == 0)
1220d5e2b23Schristos 		strlcpy(buf, "-", sizeof(buf));
1230d5e2b23Schristos }
1240d5e2b23Schristos 
125f24cb256Sdsl static int
iwidth(u_int64_t v)126f24cb256Sdsl iwidth(u_int64_t v)
127f24cb256Sdsl {
128f24cb256Sdsl 	u_int64_t nlim, lim;
129f24cb256Sdsl 	int w = 1;
130f24cb256Sdsl 
131f24cb256Sdsl 	for (lim = 10; v >= lim; lim = nlim) {
132f24cb256Sdsl 		nlim = lim * 10;
133f24cb256Sdsl 		w++;
134f24cb256Sdsl 		if (nlim < lim)
135f24cb256Sdsl 			break;
136f24cb256Sdsl 	}
137f24cb256Sdsl 	return w;
138f24cb256Sdsl }
1397fb9269eSmycroft 
1403541700dSmycroft static char *
cmdpart(char * arg0)14153474900Ssimonb cmdpart(char *arg0)
1423541700dSmycroft {
1433541700dSmycroft 	char *cp;
1443541700dSmycroft 
1453541700dSmycroft 	return ((cp = strrchr(arg0, '/')) != NULL ? cp + 1 : arg0);
1463541700dSmycroft }
1473541700dSmycroft 
1484d1457ceScgd void
printheader(void)14953474900Ssimonb printheader(void)
15061f28255Scgd {
151a98dd470Ssimonb 	int len;
1524d1457ceScgd 	VAR *v;
1534d1457ceScgd 	struct varent *vent;
154a98dd470Ssimonb 	static int firsttime = 1;
155d9463bc1Sapb 	static int noheader = 0;
15661f28255Scgd 
157d9463bc1Sapb 	/*
158d9463bc1Sapb 	 * If all the columns have user-specified null headers,
159d9463bc1Sapb 	 * don't print the blank header line at all.
160d9463bc1Sapb 	 */
161d9463bc1Sapb 	if (firsttime) {
162d9463bc1Sapb 		SIMPLEQ_FOREACH(vent, &displaylist, next) {
163d9463bc1Sapb 			if (vent->var->header[0])
164d9463bc1Sapb 				break;
165d9463bc1Sapb 		}
166d9463bc1Sapb 		if (vent == NULL) {
167d9463bc1Sapb 			noheader = 1;
168d9463bc1Sapb 			firsttime = 0;
169d9463bc1Sapb 		}
170d9463bc1Sapb 
171d9463bc1Sapb 	}
172d9463bc1Sapb 	if (noheader)
173d9463bc1Sapb 		return;
174d9463bc1Sapb 
175d9463bc1Sapb 	SIMPLEQ_FOREACH(vent, &displaylist, next) {
17661f28255Scgd 		v = vent->var;
177d530ee00Ssimonb 		if (firsttime) {
178a98dd470Ssimonb 			len = strlen(v->header);
179a98dd470Ssimonb 			if (len > v->width)
180a98dd470Ssimonb 				v->width = len;
181a98dd470Ssimonb 			totwidth += v->width + 1;	/* +1 for space */
182a98dd470Ssimonb 		}
18361f28255Scgd 		if (v->flag & LJUST) {
184d9463bc1Sapb 			if (SIMPLEQ_NEXT(vent, next) == NULL)	/* last one */
18561f28255Scgd 				(void)printf("%s", v->header);
18661f28255Scgd 			else
187a98dd470Ssimonb 				(void)printf("%-*s", v->width,
188a98dd470Ssimonb 				    v->header);
18961f28255Scgd 		} else
19061f28255Scgd 			(void)printf("%*s", v->width, v->header);
191d9463bc1Sapb 		if (SIMPLEQ_NEXT(vent, next) != NULL)
19261f28255Scgd 			(void)putchar(' ');
19361f28255Scgd 	}
19461f28255Scgd 	(void)putchar('\n');
195d530ee00Ssimonb 	if (firsttime) {
196a98dd470Ssimonb 		firsttime = 0;
197d530ee00Ssimonb 		totwidth--;	/* take off last space */
198d530ee00Ssimonb 	}
19961f28255Scgd }
20061f28255Scgd 
2019bb3e62bShubertf /*
2029bc855a9Ssimonb  * Return 1 if the command name in the argument vector (u-area) does
203a396a72fSchristos  * not match the command name (p_comm)
2049bb3e62bShubertf  */
20537e6d2f3Smycroft static int
titlecmp(char * name,char ** argv)20653474900Ssimonb titlecmp(char *name, char **argv)
20737e6d2f3Smycroft {
20837e6d2f3Smycroft 	char *title;
20937e6d2f3Smycroft 	int namelen;
21037e6d2f3Smycroft 
2119bb3e62bShubertf 
2123141a5ccSchristos 	/* no argument vector == no match; system processes/threads do that */
21337e6d2f3Smycroft 	if (argv == 0 || argv[0] == 0)
21437e6d2f3Smycroft 		return (1);
21537e6d2f3Smycroft 
21637e6d2f3Smycroft 	title = cmdpart(argv[0]);
21737e6d2f3Smycroft 
2183141a5ccSchristos 	/* the basename matches */
21937e6d2f3Smycroft 	if (!strcmp(name, title))
22037e6d2f3Smycroft 		return (0);
22137e6d2f3Smycroft 
2223141a5ccSchristos 	/* handle login shells, by skipping the leading - */
22337e6d2f3Smycroft 	if (title[0] == '-' && !strcmp(name, title + 1))
22437e6d2f3Smycroft 		return (0);
22537e6d2f3Smycroft 
22637e6d2f3Smycroft 	namelen = strlen(name);
22737e6d2f3Smycroft 
2283141a5ccSchristos 	/* handle daemons that report activity as daemonname: activity */
22937e6d2f3Smycroft 	if (argv[1] == 0 &&
23037e6d2f3Smycroft 	    !strncmp(name, title, namelen) &&
23137e6d2f3Smycroft 	    title[namelen + 0] == ':' &&
23237e6d2f3Smycroft 	    title[namelen + 1] == ' ')
23337e6d2f3Smycroft 		return (0);
23437e6d2f3Smycroft 
23537e6d2f3Smycroft 	return (1);
23637e6d2f3Smycroft }
23737e6d2f3Smycroft 
238a98dd470Ssimonb static void
doubleprintorsetwidth(VAR * v,double val,int prec,enum mode mode)2394e3b1a0bSdholland doubleprintorsetwidth(VAR *v, double val, int prec, enum mode mode)
240a98dd470Ssimonb {
241a98dd470Ssimonb 	int fmtlen;
242a98dd470Ssimonb 
243a98dd470Ssimonb 	if (mode == WIDTHMODE) {
244a98dd470Ssimonb 		if (val < 0.0 && val < v->longestnd) {
245a98dd470Ssimonb 			fmtlen = (int)log10(-val) + prec + 2;
246a98dd470Ssimonb 			v->longestnd = val;
247a98dd470Ssimonb 			if (fmtlen > v->width)
248a98dd470Ssimonb 				v->width = fmtlen;
249a98dd470Ssimonb 		} else if (val > 0.0 && val > v->longestpd) {
250a98dd470Ssimonb 			fmtlen = (int)log10(val) + prec + 1;
251a98dd470Ssimonb 			v->longestpd = val;
252a98dd470Ssimonb 			if (fmtlen > v->width)
253a98dd470Ssimonb 				v->width = fmtlen;
254a98dd470Ssimonb 		}
255a98dd470Ssimonb 	} else {
256abb32017Ssimonb 		(void)printf("%*.*f", v->width, prec, val);
257a98dd470Ssimonb 	}
258a98dd470Ssimonb }
259a98dd470Ssimonb 
260a98dd470Ssimonb static void
intprintorsetwidth(VAR * v,int val,enum mode mode)2614e3b1a0bSdholland intprintorsetwidth(VAR *v, int val, enum mode mode)
262a98dd470Ssimonb {
263a98dd470Ssimonb 	int fmtlen;
264a98dd470Ssimonb 
265a98dd470Ssimonb 	if (mode == WIDTHMODE) {
266a98dd470Ssimonb 		if (val < 0 && val < v->longestn) {
267a98dd470Ssimonb 			v->longestn = val;
268f24cb256Sdsl 			fmtlen = iwidth(-val) + 1;
269a98dd470Ssimonb 			if (fmtlen > v->width)
270a98dd470Ssimonb 				v->width = fmtlen;
271a98dd470Ssimonb 		} else if (val > 0 && val > v->longestp) {
272a98dd470Ssimonb 			v->longestp = val;
273f24cb256Sdsl 			fmtlen = iwidth(val);
274a98dd470Ssimonb 			if (fmtlen > v->width)
275a98dd470Ssimonb 				v->width = fmtlen;
276a98dd470Ssimonb 		}
277a98dd470Ssimonb 	} else
278abb32017Ssimonb 		(void)printf("%*d", v->width, val);
279a98dd470Ssimonb }
280a98dd470Ssimonb 
281a98dd470Ssimonb static void
strprintorsetwidth(VAR * v,const char * str,enum mode mode)2824e3b1a0bSdholland strprintorsetwidth(VAR *v, const char *str, enum mode mode)
283a98dd470Ssimonb {
284a98dd470Ssimonb 	int len;
285a98dd470Ssimonb 
286a98dd470Ssimonb 	if (mode == WIDTHMODE) {
287a98dd470Ssimonb 		len = strlen(str);
288a98dd470Ssimonb 		if (len > v->width)
289a98dd470Ssimonb 			v->width = len;
290a98dd470Ssimonb 	} else {
291a98dd470Ssimonb 		if (v->flag & LJUST)
292abb32017Ssimonb 			(void)printf("%-*.*s", v->width, v->width, str);
293a98dd470Ssimonb 		else
294abb32017Ssimonb 			(void)printf("%*.*s", v->width, v->width, str);
295a98dd470Ssimonb 	}
296a98dd470Ssimonb }
297a98dd470Ssimonb 
2984d1457ceScgd void
command(struct pinfo * pi,VARENT * ve,enum mode mode)2995a6cfab1Schristos command(struct pinfo *pi, VARENT *ve, enum mode mode)
30061f28255Scgd {
3015a6cfab1Schristos 	struct kinfo_proc2 *ki = pi->ki;
3024d1457ceScgd 	VAR *v;
3034d1457ceScgd 	int left;
30437e6d2f3Smycroft 	char **argv, **p, *name;
30561f28255Scgd 
306d530ee00Ssimonb 	if (mode == WIDTHMODE)
307a98dd470Ssimonb 		return;
308d530ee00Ssimonb 
309a98dd470Ssimonb 	v = ve->var;
310d9463bc1Sapb 	if (SIMPLEQ_NEXT(ve, next) != NULL || termwidth != UNLIMITED) {
311d9463bc1Sapb 		if (SIMPLEQ_NEXT(ve, next) == NULL) {
312d530ee00Ssimonb 			left = termwidth - (totwidth - v->width);
31361f28255Scgd 			if (left < 1) /* already wrapped, just use std width */
31461f28255Scgd 				left = v->width;
31561f28255Scgd 		} else
3163541700dSmycroft 			left = v->width;
3173541700dSmycroft 	} else
3183541700dSmycroft 		left = -1;
319fd521aefSsimonb 	if (needenv && kd) {
320fd521aefSsimonb 		argv = kvm_getenvv2(kd, ki, termwidth);
32178295c8bSchristos 		if ((p = argv) != NULL) {
3223541700dSmycroft 			while (*p) {
3233541700dSmycroft 				fmt_puts(*p, &left);
3243541700dSmycroft 				p++;
3253541700dSmycroft 				fmt_putc(' ', &left);
3263541700dSmycroft 			}
3273541700dSmycroft 		}
3283541700dSmycroft 	}
3293541700dSmycroft 	if (needcomm) {
3305a6cfab1Schristos 		if (pi->prefix)
3315a6cfab1Schristos 			(void)fmt_puts(pi->prefix, &left);
332fd521aefSsimonb 		name = ki->p_comm;
3333541700dSmycroft 		if (!commandonly) {
334fd521aefSsimonb 			argv = kvm_getargv2(kd, ki, termwidth);
33578295c8bSchristos 			if ((p = argv) != NULL) {
3363541700dSmycroft 				while (*p) {
3373541700dSmycroft 					fmt_puts(*p, &left);
3383541700dSmycroft 					p++;
3393541700dSmycroft 					fmt_putc(' ', &left);
340891960dbSsimonb 					if (v->flag & ARGV0)
341891960dbSsimonb 						break;
3423541700dSmycroft 				}
343891960dbSsimonb 				if (!(v->flag & ARGV0) &&
344891960dbSsimonb 				    titlecmp(name, argv)) {
3459bb3e62bShubertf 					/*
3463141a5ccSchristos 					 * append the real command name within
347c91b59d1Schristos 					 * parentheses, if the command name
348c91b59d1Schristos 					 * does not match the one in the
349c91b59d1Schristos 					 * argument vector
3509bb3e62bShubertf 					 */
3513541700dSmycroft 					fmt_putc('(', &left);
35237e6d2f3Smycroft 					fmt_puts(name, &left);
3533541700dSmycroft 					fmt_putc(')', &left);
3543541700dSmycroft 				}
3553541700dSmycroft 			} else {
356c91b59d1Schristos 				/*
357c91b59d1Schristos 				 * Commands that don't set an argv vector
358725b2119Slukem 				 * are printed with square brackets if they
35948661b97Senami 				 * are system commands.  Otherwise they are
36048661b97Senami 				 * printed within parentheses.
361c91b59d1Schristos 				 */
362f5e7ca24Spavel 				if (ki->p_flag & P_SYSTEM) {
363c91b59d1Schristos 					fmt_putc('[', &left);
364c91b59d1Schristos 					fmt_puts(name, &left);
365c91b59d1Schristos 					fmt_putc(']', &left);
36648661b97Senami 				} else {
36748661b97Senami 					fmt_putc('(', &left);
36848661b97Senami 					fmt_puts(name, &left);
36948661b97Senami 					fmt_putc(')', &left);
37048661b97Senami 				}
371c91b59d1Schristos 			}
372c91b59d1Schristos 		} else {
37337e6d2f3Smycroft 			fmt_puts(name, &left);
3743541700dSmycroft 		}
3753541700dSmycroft 	}
376d9463bc1Sapb 	if (SIMPLEQ_NEXT(ve, next) != NULL && left > 0)
377abb32017Ssimonb 		(void)printf("%*s", left, "");
37861f28255Scgd }
37961f28255Scgd 
3804d1457ceScgd void
groups(struct pinfo * pi,VARENT * ve,enum mode mode)3815a6cfab1Schristos groups(struct pinfo *pi, VARENT *ve, enum mode mode)
38240f30459Satatat {
3835a6cfab1Schristos 	struct kinfo_proc2 *ki = pi->ki;
38440f30459Satatat 	VAR *v;
38540f30459Satatat 	int left, i;
38640f30459Satatat 	char buf[16], *p;
38740f30459Satatat 
38840f30459Satatat 	if (mode == WIDTHMODE)
38940f30459Satatat 		return;
39040f30459Satatat 
39140f30459Satatat 	v = ve->var;
392d9463bc1Sapb 	if (SIMPLEQ_NEXT(ve, next) != NULL || termwidth != UNLIMITED) {
393d9463bc1Sapb 		if (SIMPLEQ_NEXT(ve, next) == NULL) {
39440f30459Satatat 			left = termwidth - (totwidth - v->width);
39540f30459Satatat 			if (left < 1) /* already wrapped, just use std width */
39640f30459Satatat 				left = v->width;
39740f30459Satatat 		} else
39840f30459Satatat 			left = v->width;
39940f30459Satatat 	} else
40040f30459Satatat 		left = -1;
40140f30459Satatat 
4028b7f84e1Sdrochner 	if (ki->p_ngroups == 0)
40340f30459Satatat 		fmt_putc('-', &left);
40440f30459Satatat 
40540f30459Satatat 	for (i = 0; i < ki->p_ngroups; i++) {
40640f30459Satatat 		(void)snprintf(buf, sizeof(buf), "%d", ki->p_groups[i]);
40740f30459Satatat 		if (i)
40840f30459Satatat 			fmt_putc(' ', &left);
40940f30459Satatat 		for (p = &buf[0]; *p; p++)
41040f30459Satatat 			fmt_putc(*p, &left);
41140f30459Satatat 	}
41240f30459Satatat 
413d9463bc1Sapb 	if (SIMPLEQ_NEXT(ve, next) != NULL && left > 0)
414abb32017Ssimonb 		(void)printf("%*s", left, "");
41540f30459Satatat }
41640f30459Satatat 
41740f30459Satatat void
groupnames(struct pinfo * pi,VARENT * ve,enum mode mode)4185a6cfab1Schristos groupnames(struct pinfo *pi, VARENT *ve, enum mode mode)
41940f30459Satatat {
4205a6cfab1Schristos 	struct kinfo_proc2 *ki = pi->ki;
42140f30459Satatat 	VAR *v;
42240f30459Satatat 	int left, i;
42340f30459Satatat 	const char *p;
42440f30459Satatat 
42540f30459Satatat 	if (mode == WIDTHMODE)
42640f30459Satatat 		return;
42740f30459Satatat 
42840f30459Satatat 	v = ve->var;
429d9463bc1Sapb 	if (SIMPLEQ_NEXT(ve, next) != NULL || termwidth != UNLIMITED) {
430d9463bc1Sapb 		if (SIMPLEQ_NEXT(ve, next) == NULL) {
43140f30459Satatat 			left = termwidth - (totwidth - v->width);
43240f30459Satatat 			if (left < 1) /* already wrapped, just use std width */
43340f30459Satatat 				left = v->width;
43440f30459Satatat 		} else
43540f30459Satatat 			left = v->width;
43640f30459Satatat 	} else
43740f30459Satatat 		left = -1;
43840f30459Satatat 
439cbbbda3bSdrochner 	if (ki->p_ngroups == 0)
44040f30459Satatat 		fmt_putc('-', &left);
44140f30459Satatat 
44240f30459Satatat 	for (i = 0; i < ki->p_ngroups; i++) {
44340f30459Satatat 		if (i)
44440f30459Satatat 			fmt_putc(' ', &left);
44540f30459Satatat 		for (p = group_from_gid(ki->p_groups[i], 0); *p; p++)
44640f30459Satatat 			fmt_putc(*p, &left);
44740f30459Satatat 	}
44840f30459Satatat 
449d9463bc1Sapb 	if (SIMPLEQ_NEXT(ve, next) != NULL && left > 0)
450abb32017Ssimonb 		(void)printf("%*s", left, "");
45140f30459Satatat }
45240f30459Satatat 
45340f30459Satatat void
ucomm(struct pinfo * pi,VARENT * ve,enum mode mode)4545a6cfab1Schristos ucomm(struct pinfo *pi, VARENT *ve, enum mode mode)
45561f28255Scgd {
4565a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
4575a6cfab1Schristos 	char buf[MAXPATHLEN], *p;
4584d1457ceScgd 	VAR *v;
4594d1457ceScgd 
4604d1457ceScgd 	v = ve->var;
4615a6cfab1Schristos 	if (pi->prefix)
4625a6cfab1Schristos 		snprintf(p = buf, sizeof(buf), "%s%s", pi->prefix, k->p_comm);
4635a6cfab1Schristos 	else
4645a6cfab1Schristos 		p = k->p_comm;
4655a6cfab1Schristos 	strprintorsetwidth(v, p, mode);
46661f28255Scgd }
46761f28255Scgd 
4684d1457ceScgd void
emul(struct pinfo * pi,VARENT * ve,enum mode mode)4695a6cfab1Schristos emul(struct pinfo *pi, VARENT *ve, enum mode mode)
470d0a868f4Schristos {
4715a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
472d0a868f4Schristos 	VAR *v;
473d0a868f4Schristos 
474d0a868f4Schristos 	v = ve->var;
475d0a868f4Schristos 	strprintorsetwidth(v, k->p_ename, mode);
476d0a868f4Schristos }
477d0a868f4Schristos 
478d0a868f4Schristos void
logname(struct pinfo * pi,VARENT * ve,enum mode mode)4795a6cfab1Schristos logname(struct pinfo *pi, VARENT *ve, enum mode mode)
48061f28255Scgd {
4815a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
4824d1457ceScgd 	VAR *v;
4834d1457ceScgd 
4844d1457ceScgd 	v = ve->var;
485a98dd470Ssimonb 	strprintorsetwidth(v, k->p_login, mode);
48661f28255Scgd }
48761f28255Scgd 
4884d1457ceScgd void
state(struct pinfo * pi,VARENT * ve,enum mode mode)4895a6cfab1Schristos state(struct pinfo *pi, VARENT *ve, enum mode mode)
49061f28255Scgd {
4915a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
492fd521aefSsimonb 	int flag, is_zombie;
4934d1457ceScgd 	char *cp;
4944d1457ceScgd 	VAR *v;
49561f28255Scgd 	char buf[16];
4964d1457ceScgd 
497fd521aefSsimonb 	is_zombie = 0;
4984d1457ceScgd 	v = ve->var;
499fd521aefSsimonb 	flag = k->p_flag;
5004d1457ceScgd 	cp = buf;
50161f28255Scgd 
50240cf6f36Srmind 	/*
50340cf6f36Srmind 	 * NOTE: There are historical letters, which are no longer used:
50440cf6f36Srmind 	 *
50540cf6f36Srmind 	 * - W: indicated that process is swapped out.
50640cf6f36Srmind 	 * - L: indicated non-zero l_holdcnt (i.e. that process was
50740cf6f36Srmind 	 *   prevented from swapping-out.
50840cf6f36Srmind 	 *
50940cf6f36Srmind 	 * These letters should not be used for new states to avoid
51040cf6f36Srmind 	 * conflicts with old applications which might depend on them.
51140cf6f36Srmind 	 */
512fd521aefSsimonb 	switch (k->p_stat) {
51361f28255Scgd 
5143fdac2b8Sthorpej 	case LSSTOP:
51561f28255Scgd 		*cp = 'T';
51661f28255Scgd 		break;
51761f28255Scgd 
5183fdac2b8Sthorpej 	case LSSLEEP:
519f5e7ca24Spavel 		if (flag & L_SINTR)	/* interruptable (long) */
520990d25a9Slukem 			*cp = (int)k->p_slptime >= maxslp ? 'I' : 'S';
52161f28255Scgd 		else
52225718695Scgd 			*cp = 'D';
52361f28255Scgd 		break;
52461f28255Scgd 
5253fdac2b8Sthorpej 	case LSRUN:
5263fdac2b8Sthorpej 	case LSIDL:
52761f28255Scgd 		*cp = 'R';
52861f28255Scgd 		break;
52961f28255Scgd 
530cca36888Schristos 	case LSONPROC:
531cca36888Schristos 		*cp = 'O';
532cca36888Schristos 		break;
533cca36888Schristos 
5343fdac2b8Sthorpej 	case LSZOMB:
53561f28255Scgd 		*cp = 'Z';
536fd521aefSsimonb 		is_zombie = 1;
53761f28255Scgd 		break;
53861f28255Scgd 
5393fdac2b8Sthorpej 	case LSSUSPENDED:
5403fdac2b8Sthorpej 		*cp = 'U';
5413fdac2b8Sthorpej 		break;
5423fdac2b8Sthorpej 
54361f28255Scgd 	default:
54461f28255Scgd 		*cp = '?';
54561f28255Scgd 	}
54661f28255Scgd 	cp++;
547fd521aefSsimonb 	if (k->p_nice < NZERO)
54861f28255Scgd 		*cp++ = '<';
549fd521aefSsimonb 	else if (k->p_nice > NZERO)
55061f28255Scgd 		*cp++ = 'N';
551f5e7ca24Spavel 	if (flag & P_TRACED)
55261f28255Scgd 		*cp++ = 'X';
553f5e7ca24Spavel 	if (flag & P_WEXIT && !is_zombie)
55461f28255Scgd 		*cp++ = 'E';
555f5e7ca24Spavel 	if (flag & P_PPWAIT)
55661f28255Scgd 		*cp++ = 'V';
557f5e7ca24Spavel 	if (flag & P_SYSTEM)
5580a7d3a1fSsimonb 		*cp++ = 'K';
559fd521aefSsimonb 	if (k->p_eflag & EPROC_SLEADER)
56061f28255Scgd 		*cp++ = 's';
561f5e7ca24Spavel 	if (flag & P_SA)
5623fdac2b8Sthorpej 		*cp++ = 'a';
5633fdac2b8Sthorpej 	else if (k->p_nlwps > 1)
5643fdac2b8Sthorpej 		*cp++ = 'l';
565f5e7ca24Spavel 	if ((flag & P_CONTROLT) && k->p__pgid == k->p_tpgid)
56661f28255Scgd 		*cp++ = '+';
56761f28255Scgd 	*cp = '\0';
568a98dd470Ssimonb 	strprintorsetwidth(v, buf, mode);
56961f28255Scgd }
57061f28255Scgd 
5714d1457ceScgd void
lstate(struct pinfo * pi,VARENT * ve,enum mode mode)5725a6cfab1Schristos lstate(struct pinfo *pi, VARENT *ve, enum mode mode)
573fddfc1d3Sws {
5745a6cfab1Schristos 	struct kinfo_lwp *k = pi->li;
5756b6a89aaSwiz 	int flag;
5763fdac2b8Sthorpej 	char *cp;
5773fdac2b8Sthorpej 	VAR *v;
5783fdac2b8Sthorpej 	char buf[16];
5793fdac2b8Sthorpej 
5803fdac2b8Sthorpej 	v = ve->var;
5813fdac2b8Sthorpej 	flag = k->l_flag;
5823fdac2b8Sthorpej 	cp = buf;
5833fdac2b8Sthorpej 
5843fdac2b8Sthorpej 	switch (k->l_stat) {
5853fdac2b8Sthorpej 
5863fdac2b8Sthorpej 	case LSSTOP:
5873fdac2b8Sthorpej 		*cp = 'T';
5883fdac2b8Sthorpej 		break;
5893fdac2b8Sthorpej 
5903fdac2b8Sthorpej 	case LSSLEEP:
59185746c67Swiz 		if (flag & L_SINTR)	/* interruptible (long) */
592990d25a9Slukem 			*cp = (int)k->l_slptime >= maxslp ? 'I' : 'S';
5933fdac2b8Sthorpej 		else
5943fdac2b8Sthorpej 			*cp = 'D';
5953fdac2b8Sthorpej 		break;
5963fdac2b8Sthorpej 
5973fdac2b8Sthorpej 	case LSRUN:
5983fdac2b8Sthorpej 	case LSIDL:
5993fdac2b8Sthorpej 		*cp = 'R';
6003fdac2b8Sthorpej 		break;
6013fdac2b8Sthorpej 
602da9c1e1bSchristos 	case LSONPROC:
603da9c1e1bSchristos 		*cp = 'O';
604da9c1e1bSchristos 		break;
605da9c1e1bSchristos 
6063fdac2b8Sthorpej 	case LSZOMB:
607f5e7ca24Spavel 	case LSDEAD:
6083fdac2b8Sthorpej 		*cp = 'Z';
6093fdac2b8Sthorpej 		break;
6103fdac2b8Sthorpej 
6113fdac2b8Sthorpej 	case LSSUSPENDED:
6123fdac2b8Sthorpej 		*cp = 'U';
6133fdac2b8Sthorpej 		break;
6143fdac2b8Sthorpej 
6153fdac2b8Sthorpej 	default:
6163fdac2b8Sthorpej 		*cp = '?';
6173fdac2b8Sthorpej 	}
6183fdac2b8Sthorpej 	cp++;
619da9c1e1bSchristos 	if (flag & L_SYSTEM)
620055b26bbSchristos 		*cp++ = 'K';
621da9c1e1bSchristos 	if (flag & L_SA)
622da9c1e1bSchristos 		*cp++ = 'a';
623f5e7ca24Spavel 	if (flag & L_DETACHED)
6243fdac2b8Sthorpej 		*cp++ = '-';
6253fdac2b8Sthorpej 	*cp = '\0';
6263fdac2b8Sthorpej 	strprintorsetwidth(v, buf, mode);
6273fdac2b8Sthorpej }
6283fdac2b8Sthorpej 
6293fdac2b8Sthorpej void
pnice(struct pinfo * pi,VARENT * ve,enum mode mode)6305a6cfab1Schristos pnice(struct pinfo *pi, VARENT *ve, enum mode mode)
6313fdac2b8Sthorpej {
6325a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
633fddfc1d3Sws 	VAR *v;
634fddfc1d3Sws 
635fddfc1d3Sws 	v = ve->var;
636a98dd470Ssimonb 	intprintorsetwidth(v, k->p_nice - NZERO, mode);
637fddfc1d3Sws }
638fddfc1d3Sws 
639fddfc1d3Sws void
pri(struct pinfo * pi,VARENT * ve,enum mode mode)6405a6cfab1Schristos pri(struct pinfo *pi, VARENT *ve, enum mode mode)
64161f28255Scgd {
6425a6cfab1Schristos 	struct kinfo_lwp *l = pi->li;
6434d1457ceScgd 	VAR *v;
6444d1457ceScgd 
6454d1457ceScgd 	v = ve->var;
646bb6c89afSad 	intprintorsetwidth(v, l->l_priority, mode);
64761f28255Scgd }
64861f28255Scgd 
6494d1457ceScgd void
usrname(struct pinfo * pi,VARENT * ve,enum mode mode)650b42c7b02Skamil usrname(struct pinfo *pi, VARENT *ve, enum mode mode)
65161f28255Scgd {
6525a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
6534d1457ceScgd 	VAR *v;
6544d1457ceScgd 
6554d1457ceScgd 	v = ve->var;
656a98dd470Ssimonb 	strprintorsetwidth(v, user_from_uid(k->p_uid, 0), mode);
65761f28255Scgd }
65861f28255Scgd 
6594d1457ceScgd void
runame(struct pinfo * pi,VARENT * ve,enum mode mode)6605a6cfab1Schristos runame(struct pinfo *pi, VARENT *ve, enum mode mode)
66161f28255Scgd {
6625a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
6634d1457ceScgd 	VAR *v;
6644d1457ceScgd 
6654d1457ceScgd 	v = ve->var;
666a98dd470Ssimonb 	strprintorsetwidth(v, user_from_uid(k->p_ruid, 0), mode);
66761f28255Scgd }
66861f28255Scgd 
6694d1457ceScgd void
svuname(struct pinfo * pi,VARENT * ve,enum mode mode)6705a6cfab1Schristos svuname(struct pinfo *pi, VARENT *ve, enum mode mode)
67140f30459Satatat {
6725a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
67340f30459Satatat 	VAR *v;
67440f30459Satatat 
67540f30459Satatat 	v = ve->var;
67640f30459Satatat 	strprintorsetwidth(v, user_from_uid(k->p_svuid, 0), mode);
67740f30459Satatat }
67840f30459Satatat 
67940f30459Satatat void
gname(struct pinfo * pi,VARENT * ve,enum mode mode)6805a6cfab1Schristos gname(struct pinfo *pi, VARENT *ve, enum mode mode)
68140f30459Satatat {
6825a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
68340f30459Satatat 	VAR *v;
68440f30459Satatat 
68540f30459Satatat 	v = ve->var;
68640f30459Satatat 	strprintorsetwidth(v, group_from_gid(k->p_gid, 0), mode);
68740f30459Satatat }
68840f30459Satatat 
68940f30459Satatat void
rgname(struct pinfo * pi,VARENT * ve,enum mode mode)6905a6cfab1Schristos rgname(struct pinfo *pi, VARENT *ve, enum mode mode)
69140f30459Satatat {
6925a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
69340f30459Satatat 	VAR *v;
69440f30459Satatat 
69540f30459Satatat 	v = ve->var;
69640f30459Satatat 	strprintorsetwidth(v, group_from_gid(k->p_rgid, 0), mode);
69740f30459Satatat }
69840f30459Satatat 
69940f30459Satatat void
svgname(struct pinfo * pi,VARENT * ve,enum mode mode)7005a6cfab1Schristos svgname(struct pinfo *pi, VARENT *ve, enum mode mode)
70140f30459Satatat {
7025a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
70340f30459Satatat 	VAR *v;
70440f30459Satatat 
70540f30459Satatat 	v = ve->var;
70640f30459Satatat 	strprintorsetwidth(v, group_from_gid(k->p_svgid, 0), mode);
70740f30459Satatat }
70840f30459Satatat 
70940f30459Satatat void
tdev(struct pinfo * pi,VARENT * ve,enum mode mode)7105a6cfab1Schristos tdev(struct pinfo *pi, VARENT *ve, enum mode mode)
71161f28255Scgd {
7125a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
7134d1457ceScgd 	VAR *v;
7144d1457ceScgd 	dev_t dev;
7154d1457ceScgd 	char buff[16];
71661f28255Scgd 
7174d1457ceScgd 	v = ve->var;
718fd521aefSsimonb 	dev = k->p_tdev;
719a98dd470Ssimonb 	if (dev == NODEV) {
720a98dd470Ssimonb 		if (mode == PRINTMODE)
7213e870b85Schristos 			(void)printf("%*s", v->width, "?");
722f24cb256Sdsl 		else
723f24cb256Sdsl 			if (v->width < 2)
724f24cb256Sdsl 				v->width = 2;
725a98dd470Ssimonb 	} else {
7264d1457ceScgd 		(void)snprintf(buff, sizeof(buff),
727a5c6617dSchristos 		    "%lld/%lld", (long long)major(dev), (long long)minor(dev));
728a98dd470Ssimonb 		strprintorsetwidth(v, buff, mode);
72961f28255Scgd 	}
73061f28255Scgd }
73161f28255Scgd 
7324d1457ceScgd void
tname(struct pinfo * pi,VARENT * ve,enum mode mode)7335a6cfab1Schristos tname(struct pinfo *pi, VARENT *ve, enum mode mode)
73461f28255Scgd {
7355a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
7364d1457ceScgd 	VAR *v;
73761f28255Scgd 	dev_t dev;
7380e2f9ea9Smycroft 	const char *ttname;
739a98dd470Ssimonb 	int noctty;
74061f28255Scgd 
7414d1457ceScgd 	v = ve->var;
742fd521aefSsimonb 	dev = k->p_tdev;
743a98dd470Ssimonb 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) {
744a98dd470Ssimonb 		if (mode == PRINTMODE)
7453e870b85Schristos 			(void)printf("%-*s", v->width, "?");
746f24cb256Sdsl 		else
747f24cb256Sdsl 			if (v->width < 2)
748f24cb256Sdsl 				v->width = 2;
749a98dd470Ssimonb 	} else {
750a98dd470Ssimonb 		noctty = !(k->p_eflag & EPROC_CTTY) ? 1 : 0;
751a98dd470Ssimonb 		if (mode == WIDTHMODE) {
752a98dd470Ssimonb 			int fmtlen;
753a98dd470Ssimonb 
754a98dd470Ssimonb 			fmtlen = strlen(ttname) + noctty;
755a98dd470Ssimonb 			if (v->width < fmtlen)
756292b6688Ssimonb 				v->width = fmtlen;
757a98dd470Ssimonb 		} else {
758a98dd470Ssimonb 			if (noctty)
759abb32017Ssimonb 				(void)printf("%-*s-", v->width - 1, ttname);
760a98dd470Ssimonb 			else
761abb32017Ssimonb 				(void)printf("%-*s", v->width, ttname);
762a98dd470Ssimonb 		}
76361f28255Scgd 	}
76461f28255Scgd }
76561f28255Scgd 
7664d1457ceScgd void
longtname(struct pinfo * pi,VARENT * ve,enum mode mode)7675a6cfab1Schristos longtname(struct pinfo *pi, VARENT *ve, enum mode mode)
76861f28255Scgd {
7695a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
7704d1457ceScgd 	VAR *v;
77161f28255Scgd 	dev_t dev;
7720e2f9ea9Smycroft 	const char *ttname;
77361f28255Scgd 
7744d1457ceScgd 	v = ve->var;
775fd521aefSsimonb 	dev = k->p_tdev;
776a98dd470Ssimonb 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) {
777a98dd470Ssimonb 		if (mode == PRINTMODE)
7783e870b85Schristos 			(void)printf("%-*s", v->width, "?");
779f24cb256Sdsl 		else
780f24cb256Sdsl 			if (v->width < 2)
781f24cb256Sdsl 				v->width = 2;
782f24cb256Sdsl 	} else {
783a98dd470Ssimonb 		strprintorsetwidth(v, ttname, mode);
784a98dd470Ssimonb 	}
78561f28255Scgd }
78661f28255Scgd 
7874d1457ceScgd void
started(struct pinfo * pi,VARENT * ve,enum mode mode)7885a6cfab1Schristos started(struct pinfo *pi, VARENT *ve, enum mode mode)
78961f28255Scgd {
7905a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
7914d1457ceScgd 	VAR *v;
7928936958fScgd 	time_t startt;
79361f28255Scgd 	struct tm *tp;
794a98dd470Ssimonb 	char buf[100], *cp;
795a98dd470Ssimonb 
7964d1457ceScgd 	v = ve->var;
797fd521aefSsimonb 	if (!k->p_uvalid) {
798a98dd470Ssimonb 		if (mode == PRINTMODE)
799a98dd470Ssimonb 			(void)printf("%*s", v->width, "-");
80061f28255Scgd 		return;
80161f28255Scgd 	}
80261f28255Scgd 
803fd521aefSsimonb 	startt = k->p_ustart_sec;
8048936958fScgd 	tp = localtime(&startt);
80563e11689Ssimonb 	if (now == 0)
80661f28255Scgd 		(void)time(&now);
807a98dd470Ssimonb 	if (now - k->p_ustart_sec < SECSPERDAY)
808266b57cdSmaya 		safe_strftime(buf, sizeof(buf) - 1, "%l:%M%p", tp);
809a98dd470Ssimonb 	else if (now - k->p_ustart_sec < DAYSPERWEEK * SECSPERDAY)
810266b57cdSmaya 		safe_strftime(buf, sizeof(buf) - 1, "%a%I%p", tp);
811a98dd470Ssimonb 	else
8120d5e2b23Schristos 		safe_strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
813a98dd470Ssimonb 	/* %e and %l can start with a space. */
814a98dd470Ssimonb 	cp = buf;
815a98dd470Ssimonb 	if (*cp == ' ')
816a98dd470Ssimonb 		cp++;
817a98dd470Ssimonb 	strprintorsetwidth(v, cp, mode);
81861f28255Scgd }
81961f28255Scgd 
8204d1457ceScgd void
lstarted(struct pinfo * pi,VARENT * ve,enum mode mode)8215a6cfab1Schristos lstarted(struct pinfo *pi, VARENT *ve, enum mode mode)
82261f28255Scgd {
8235a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
8244d1457ceScgd 	VAR *v;
8258936958fScgd 	time_t startt;
82661f28255Scgd 	char buf[100];
82761f28255Scgd 
8284d1457ceScgd 	v = ve->var;
829fd521aefSsimonb 	startt = k->p_ustart_sec;
830a98dd470Ssimonb 
831b9d1a331Ssimonb 	if (mode == WIDTHMODE) {
832b9d1a331Ssimonb 		/*
833b9d1a331Ssimonb 		 * We only need to set the width once, as we assume
834b9d1a331Ssimonb 		 * that all times are the same length.  We do need to
835b9d1a331Ssimonb 		 * check against the header length as well, as "no
836b9d1a331Ssimonb 		 * header" mode for this variable will set the field
837b9d1a331Ssimonb 		 * width to the length of the header anyway (ref: the
838b9d1a331Ssimonb 		 * P1003.1-2004 comment in findvar()).
839b9d1a331Ssimonb 		 *
840b9d1a331Ssimonb 		 * XXX: The hardcoded "STARTED" string.  Better or
841*7c674e8eSandvar 		 * worse than a "<= 7" or some other arbitrary number?
842b9d1a331Ssimonb 		 */
8430d5e2b23Schristos 		if (v->width > (int)sizeof("STARTED") - 1) {
8440d5e2b23Schristos 			return;
845a98dd470Ssimonb 		}
846b9d1a331Ssimonb 	} else {
847b9d1a331Ssimonb 		if (!k->p_uvalid) {
848b9d1a331Ssimonb 			(void)printf("%*s", v->width, "-");
8490d5e2b23Schristos 			return;
8500d5e2b23Schristos 		}
8510d5e2b23Schristos 	}
8520d5e2b23Schristos 	safe_strftime(buf, sizeof(buf) - 1, "%c", localtime(&startt));
853b9d1a331Ssimonb 	strprintorsetwidth(v, buf, mode);
854b9d1a331Ssimonb }
85561f28255Scgd 
8564d1457ceScgd void
elapsed(struct pinfo * pi,VARENT * ve,enum mode mode)8575a6cfab1Schristos elapsed(struct pinfo *pi, VARENT *ve, enum mode mode)
85863e11689Ssimonb {
8595a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
86063e11689Ssimonb 	VAR *v;
86163e11689Ssimonb 	int32_t origseconds, secs, mins, hours, days;
86263e11689Ssimonb 	int fmtlen, printed_something;
86363e11689Ssimonb 
86463e11689Ssimonb 	v = ve->var;
86563e11689Ssimonb 	if (k->p_uvalid == 0) {
86663e11689Ssimonb 		origseconds = 0;
86763e11689Ssimonb 	} else {
86863e11689Ssimonb 		if (now == 0)
86963e11689Ssimonb 			(void)time(&now);
87063e11689Ssimonb 		origseconds = now - k->p_ustart_sec;
87163e11689Ssimonb 		if (origseconds < 0) {
87263e11689Ssimonb 			/*
87363e11689Ssimonb 			 * Don't try to be fancy if the machine's
87463e11689Ssimonb 			 * clock has been rewound to before the
87563e11689Ssimonb 			 * process "started".
87663e11689Ssimonb 			 */
87763e11689Ssimonb 			origseconds = 0;
87863e11689Ssimonb 		}
87963e11689Ssimonb 	}
88063e11689Ssimonb 
88163e11689Ssimonb 	secs = origseconds;
88263e11689Ssimonb 	mins = secs / SECSPERMIN;
88363e11689Ssimonb 	secs %= SECSPERMIN;
88463e11689Ssimonb 	hours = mins / MINSPERHOUR;
88563e11689Ssimonb 	mins %= MINSPERHOUR;
88663e11689Ssimonb 	days = hours / HOURSPERDAY;
88763e11689Ssimonb 	hours %= HOURSPERDAY;
88863e11689Ssimonb 
88963e11689Ssimonb 	if (mode == WIDTHMODE) {
89063e11689Ssimonb 		if (origseconds == 0)
89163e11689Ssimonb 			/* non-zero so fmtlen is calculated at least once */
89263e11689Ssimonb 			origseconds = 1;
89363e11689Ssimonb 
89463e11689Ssimonb 		if (origseconds > v->longestp) {
89563e11689Ssimonb 			v->longestp = origseconds;
89663e11689Ssimonb 
89763e11689Ssimonb 			if (days > 0) {
89863e11689Ssimonb 				/* +9 for "-hh:mm:ss" */
89963e11689Ssimonb 				fmtlen = iwidth(days) + 9;
90063e11689Ssimonb 			} else if (hours > 0) {
90163e11689Ssimonb 				/* +6 for "mm:ss" */
90263e11689Ssimonb 				fmtlen = iwidth(hours) + 6;
90363e11689Ssimonb 			} else {
90463e11689Ssimonb 				/* +3 for ":ss" */
90563e11689Ssimonb 				fmtlen = iwidth(mins) + 3;
90663e11689Ssimonb 			}
90763e11689Ssimonb 
90863e11689Ssimonb 			if (fmtlen > v->width)
90963e11689Ssimonb 				v->width = fmtlen;
91063e11689Ssimonb 		}
91163e11689Ssimonb 	} else {
912d8f2ef9aSsimonb 		printed_something = 0;
91363e11689Ssimonb 		fmtlen = v->width;
91463e11689Ssimonb 
91563e11689Ssimonb 		if (days > 0) {
91663e11689Ssimonb 			(void)printf("%*d", fmtlen - 9, days);
91763e11689Ssimonb 			printed_something = 1;
91863e11689Ssimonb 		} else if (fmtlen > 9) {
91963e11689Ssimonb 			(void)printf("%*s", fmtlen - 9, "");
92063e11689Ssimonb 		}
92163e11689Ssimonb 		if (fmtlen > 9)
92263e11689Ssimonb 			fmtlen = 9;
92363e11689Ssimonb 
92463e11689Ssimonb 		if (printed_something) {
92563e11689Ssimonb 			(void)printf("-%.*d", fmtlen - 7, hours);
92663e11689Ssimonb 			printed_something = 1;
92763e11689Ssimonb 		} else if (hours > 0) {
92863e11689Ssimonb 			(void)printf("%*d", fmtlen - 6, hours);
92963e11689Ssimonb 			printed_something = 1;
93063e11689Ssimonb 		} else if (fmtlen > 6) {
93163e11689Ssimonb 			(void)printf("%*s", fmtlen - 6, "");
93263e11689Ssimonb 		}
93363e11689Ssimonb 		if (fmtlen > 6)
93463e11689Ssimonb 			fmtlen = 6;
93563e11689Ssimonb 
93663e11689Ssimonb 		/* Don't need to set fmtlen or printed_something any more... */
93763e11689Ssimonb 		if (printed_something) {
93863e11689Ssimonb 			(void)printf(":%.*d", fmtlen - 4, mins);
93963e11689Ssimonb 		} else if (mins > 0) {
94063e11689Ssimonb 			(void)printf("%*d", fmtlen - 3, mins);
94163e11689Ssimonb 		} else if (fmtlen > 3) {
94263e11689Ssimonb 			(void)printf("%*s", fmtlen - 3, "0");
94363e11689Ssimonb 		}
94463e11689Ssimonb 
94563e11689Ssimonb 		(void)printf(":%.2d", secs);
94663e11689Ssimonb 	}
94763e11689Ssimonb }
94863e11689Ssimonb 
94963e11689Ssimonb void
wchan(struct pinfo * pi,VARENT * ve,enum mode mode)9505a6cfab1Schristos wchan(struct pinfo *pi, VARENT *ve, enum mode mode)
95161f28255Scgd {
9525a6cfab1Schristos 	struct kinfo_lwp *l = pi->li;
9534d1457ceScgd 	VAR *v;
9544d1457ceScgd 
9554d1457ceScgd 	v = ve->var;
9560bab8dfeSjoerg 	if (l->l_wmesg[0]) {
9573fdac2b8Sthorpej 		strprintorsetwidth(v, l->l_wmesg, mode);
958f24cb256Sdsl 		v->width = min(v->width, KI_WMESGLEN);
959a98dd470Ssimonb 	} else {
960a98dd470Ssimonb 		if (mode == PRINTMODE)
96161f28255Scgd 			(void)printf("%-*s", v->width, "-");
96261f28255Scgd 	}
963a98dd470Ssimonb }
96461f28255Scgd 
965e9b3916bSdholland #define	pgtok(a)        (((a)*(size_t)getpagesize())/1024)
96661f28255Scgd 
9674d1457ceScgd void
vsize(struct pinfo * pi,VARENT * ve,enum mode mode)9685a6cfab1Schristos vsize(struct pinfo *pi, VARENT *ve, enum mode mode)
96961f28255Scgd {
9705a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
9714d1457ceScgd 	VAR *v;
9724d1457ceScgd 
9734d1457ceScgd 	v = ve->var;
974fcc02354Smrg 	intprintorsetwidth(v, pgtok(k->p_vm_msize), mode);
97561f28255Scgd }
97661f28255Scgd 
9774d1457ceScgd void
rssize(struct pinfo * pi,VARENT * ve,enum mode mode)9785a6cfab1Schristos rssize(struct pinfo *pi, VARENT *ve, enum mode mode)
97961f28255Scgd {
9805a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
9814d1457ceScgd 	VAR *v;
9824d1457ceScgd 
9834d1457ceScgd 	v = ve->var;
98461f28255Scgd 	/* XXX don't have info about shared */
985a98dd470Ssimonb 	intprintorsetwidth(v, pgtok(k->p_vm_rssize), mode);
98661f28255Scgd }
98761f28255Scgd 
9884d1457ceScgd void
p_rssize(struct pinfo * pi,VARENT * ve,enum mode mode)9895a6cfab1Schristos p_rssize(struct pinfo *pi, VARENT *ve, enum mode mode)	/* doesn't account for text */
99061f28255Scgd {
9915a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
9924d1457ceScgd 	VAR *v;
9934d1457ceScgd 
9944d1457ceScgd 	v = ve->var;
995a98dd470Ssimonb 	intprintorsetwidth(v, pgtok(k->p_vm_rssize), mode);
99661f28255Scgd }
99761f28255Scgd 
9984d1457ceScgd void
cpuid(struct pinfo * pi,VARENT * ve,enum mode mode)9995a6cfab1Schristos cpuid(struct pinfo *pi, VARENT *ve, enum mode mode)
1000da86f0e5Schristos {
10015a6cfab1Schristos 	struct kinfo_lwp *l = pi->li;
1002da86f0e5Schristos 	VAR *v;
1003da86f0e5Schristos 
1004da86f0e5Schristos 	v = ve->var;
10058b95f823Srmind 	intprintorsetwidth(v, l->l_cpuid, mode);
1006da86f0e5Schristos }
1007da86f0e5Schristos 
1008b3dffa81Smlelstv static void
cputime1(int32_t secs,int32_t psecs,VAR * v,enum mode mode)10094e3b1a0bSdholland cputime1(int32_t secs, int32_t psecs, VAR *v, enum mode mode)
101061f28255Scgd {
1011a98dd470Ssimonb 	int fmtlen;
101261f28255Scgd 
101361f28255Scgd 	/*
101461f28255Scgd 	 * round and scale to 100's
101561f28255Scgd 	 */
101661f28255Scgd 	psecs = (psecs + 5000) / 10000;
101761f28255Scgd 	secs += psecs / 100;
101861f28255Scgd 	psecs = psecs % 100;
1019bd8009e5Sdsl 
1020a98dd470Ssimonb 	if (mode == WIDTHMODE) {
1021a98dd470Ssimonb 		/*
1022f43fbf8eSsimonb 		 * Ugg, this is the only field where a value of 0 is longer
1023f24cb256Sdsl 		 * than the column title.
1024a98dd470Ssimonb 		 * Use SECSPERMIN, because secs is divided by that when
1025f24cb256Sdsl 		 * passed to iwidth().
1026a98dd470Ssimonb 		 */
1027f24cb256Sdsl 		if (secs == 0)
1028a98dd470Ssimonb 			secs = SECSPERMIN;
1029f24cb256Sdsl 
1030a98dd470Ssimonb 		if (secs > v->longestp) {
1031a98dd470Ssimonb 			v->longestp = secs;
1032f24cb256Sdsl 			/* "+6" for the ":%02ld.%02ld" in the printf() below */
1033f24cb256Sdsl 			fmtlen = iwidth(secs / SECSPERMIN) + 6;
1034a98dd470Ssimonb 			if (fmtlen > v->width)
1035a98dd470Ssimonb 				v->width = fmtlen;
1036a98dd470Ssimonb 		}
1037a98dd470Ssimonb 	} else {
1038abb32017Ssimonb 		(void)printf("%*ld:%02ld.%02ld", v->width - 6,
1039abb32017Ssimonb 		    (long)(secs / SECSPERMIN), (long)(secs % SECSPERMIN),
1040abb32017Ssimonb 		    (long)psecs);
1041a98dd470Ssimonb 	}
104261f28255Scgd }
104361f28255Scgd 
1044b3dffa81Smlelstv void
cputime(struct pinfo * pi,VARENT * ve,enum mode mode)10455a6cfab1Schristos cputime(struct pinfo *pi, VARENT *ve, enum mode mode)
1046b3dffa81Smlelstv {
10475a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
1048b3dffa81Smlelstv 	VAR *v;
1049b3dffa81Smlelstv 	int32_t secs;
1050b3dffa81Smlelstv 	int32_t psecs;	/* "parts" of a second. first micro, then centi */
1051b3dffa81Smlelstv 
1052b3dffa81Smlelstv 	v = ve->var;
1053b3dffa81Smlelstv 
1054b3dffa81Smlelstv 	/*
1055b3dffa81Smlelstv 	 * This counts time spent handling interrupts.  We could
1056b3dffa81Smlelstv 	 * fix this, but it is not 100% trivial (and interrupt
1057b3dffa81Smlelstv 	 * time fractions only work on the sparc anyway).	XXX
1058b3dffa81Smlelstv 	 */
1059b3dffa81Smlelstv 	secs = k->p_rtime_sec;
1060b3dffa81Smlelstv 	psecs = k->p_rtime_usec;
1061b3dffa81Smlelstv 	if (sumrusage) {
1062b3dffa81Smlelstv 		secs += k->p_uctime_sec;
1063b3dffa81Smlelstv 		psecs += k->p_uctime_usec;
1064b3dffa81Smlelstv 	}
1065b3dffa81Smlelstv 
1066b3dffa81Smlelstv 	cputime1(secs, psecs, v, mode);
1067b3dffa81Smlelstv }
1068b3dffa81Smlelstv 
1069b3dffa81Smlelstv void
lcputime(struct pinfo * pi,VARENT * ve,enum mode mode)10705a6cfab1Schristos lcputime(struct pinfo *pi, VARENT *ve, enum mode mode)
1071b3dffa81Smlelstv {
10725a6cfab1Schristos 	struct kinfo_lwp *l = pi->li;
1073b3dffa81Smlelstv 	VAR *v;
1074b3dffa81Smlelstv 	int32_t secs;
1075b3dffa81Smlelstv 	int32_t psecs;	/* "parts" of a second. first micro, then centi */
1076b3dffa81Smlelstv 
1077b3dffa81Smlelstv 	v = ve->var;
1078b3dffa81Smlelstv 
1079b3dffa81Smlelstv 	secs = l->l_rtime_sec;
1080b3dffa81Smlelstv 	psecs = l->l_rtime_usec;
1081b3dffa81Smlelstv 
1082b3dffa81Smlelstv 	cputime1(secs, psecs, v, mode);
1083b3dffa81Smlelstv }
1084b3dffa81Smlelstv 
10854d1457ceScgd void
pcpu(struct pinfo * pi,VARENT * ve,enum mode mode)10865a6cfab1Schristos pcpu(struct pinfo *pi, VARENT *ve, enum mode mode)
108761f28255Scgd {
10884d1457ceScgd 	VAR *v;
10890697f9d2Snjoly 	double dbl;
10904d1457ceScgd 
10914d1457ceScgd 	v = ve->var;
10925a6cfab1Schristos 	dbl = pi->pcpu;
1093c45af204Snjoly 	doubleprintorsetwidth(v, dbl, (dbl >= 99.95) ? 0 : 1, mode);
109461f28255Scgd }
109561f28255Scgd 
109661f28255Scgd double
getpmem(const struct kinfo_proc2 * k)1097da4f7877Smatt getpmem(const struct kinfo_proc2 *k)
109861f28255Scgd {
109961f28255Scgd 	double fracmem;
110061f28255Scgd 	int szptudot;
110161f28255Scgd 
110261f28255Scgd 	if (!nlistread)
1103b095bb75Srin 		donlist();
110461f28255Scgd 
110561f28255Scgd 	/* XXX want pmap ptpages, segtab, etc. (per architecture) */
110668b3b7e9Smatt 	szptudot = uspace/getpagesize();
110761f28255Scgd 	/* XXX don't have info about shared */
1108fd521aefSsimonb 	fracmem = ((float)k->p_vm_rssize + szptudot)/mempages;
110961f28255Scgd 	return (100.0 * fracmem);
111061f28255Scgd }
111161f28255Scgd 
11124d1457ceScgd void
pmem(struct pinfo * pi,VARENT * ve,enum mode mode)11135a6cfab1Schristos pmem(struct pinfo *pi, VARENT *ve, enum mode mode)
111461f28255Scgd {
11155a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
11164d1457ceScgd 	VAR *v;
11174d1457ceScgd 
11184d1457ceScgd 	v = ve->var;
1119a98dd470Ssimonb 	doubleprintorsetwidth(v, getpmem(k), 1, mode);
112061f28255Scgd }
112161f28255Scgd 
11224d1457ceScgd void
pagein(struct pinfo * pi,VARENT * ve,enum mode mode)11235a6cfab1Schristos pagein(struct pinfo *pi, VARENT *ve, enum mode mode)
112461f28255Scgd {
11255a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
11264d1457ceScgd 	VAR *v;
11274d1457ceScgd 
11284d1457ceScgd 	v = ve->var;
1129a98dd470Ssimonb 	intprintorsetwidth(v, k->p_uvalid ? k->p_uru_majflt : 0, mode);
113061f28255Scgd }
113161f28255Scgd 
11324d1457ceScgd void
maxrss(struct pinfo * pi,VARENT * ve,enum mode mode)11335a6cfab1Schristos maxrss(struct pinfo *pi, VARENT *ve, enum mode mode)
113461f28255Scgd {
11354d1457ceScgd 	VAR *v;
11364d1457ceScgd 
11374d1457ceScgd 	v = ve->var;
1138a98dd470Ssimonb 	/* No need to check width! */
1139a98dd470Ssimonb 	if (mode == PRINTMODE)
114061f28255Scgd 		(void)printf("%*s", v->width, "-");
114161f28255Scgd }
114261f28255Scgd 
11434d1457ceScgd void
tsize(struct pinfo * pi,VARENT * ve,enum mode mode)11445a6cfab1Schristos tsize(struct pinfo *pi, VARENT *ve, enum mode mode)
114561f28255Scgd {
11465a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
11474d1457ceScgd 	VAR *v;
11484d1457ceScgd 
11494d1457ceScgd 	v = ve->var;
1150a98dd470Ssimonb 	intprintorsetwidth(v, pgtok(k->p_vm_tsize), mode);
115161f28255Scgd }
115261f28255Scgd 
1153c879b655Schristos static void
printsig(VAR * v,const sigset_t * s,enum mode mode)1154c879b655Schristos printsig(VAR *v, const sigset_t *s, enum mode mode)
1155c879b655Schristos {
1156c879b655Schristos #define	SIGSETSIZE	__arraycount(s->__bits)
1157c879b655Schristos 	if ((v->flag & ALTPR) == 0) {
1158c879b655Schristos 		char buf[SIGSETSIZE * 8 + 1];
1159c879b655Schristos 		size_t i;
1160c879b655Schristos 
1161c879b655Schristos 		for (i = 0; i < SIGSETSIZE; i++)
1162c879b655Schristos 			(void)snprintf(&buf[i * 8], 9, "%.8x",
1163c879b655Schristos 			    s->__bits[(SIGSETSIZE - 1) - i]);
1164c879b655Schristos 
1165c879b655Schristos 		/* Skip leading zeroes */
1166c879b655Schristos 		for (i = 0; buf[i] == '0'; i++)
1167c879b655Schristos 			continue;
1168c879b655Schristos 
1169c879b655Schristos 		if (buf[i] == '\0')
1170c879b655Schristos 			i--;
1171c879b655Schristos 		strprintorsetwidth(v, buf + i, mode);
1172c879b655Schristos 	} else {
1173c879b655Schristos 		size_t maxlen = 1024, len = 0;
11749dc307c4Schristos 		char *buf = emalloc(maxlen);
1175c879b655Schristos 		*buf = '\0';
1176c879b655Schristos 		for (size_t i = 0; i < SIGSETSIZE; i++) {
1177c879b655Schristos 			uint32_t m = s->__bits[i];
1178c879b655Schristos 			for (uint32_t j = 0; j < 32; j++) {
1179c879b655Schristos 				if ((m & (1 << j)) == 0)
1180c879b655Schristos 					continue;
1181c879b655Schristos 				const char *n = signalname(j + 1);
1182c879b655Schristos 				size_t sn = strlen(n);
1183c879b655Schristos 				if (len)
1184c879b655Schristos 					sn++;
1185c879b655Schristos 				if (len + sn >= maxlen) {
1186c879b655Schristos 					maxlen += 1024;
11879dc307c4Schristos 					buf = erealloc(buf, maxlen);
1188c879b655Schristos 				}
1189c879b655Schristos 				snprintf(buf + len, sn + 1, "%s%s",
1190c879b655Schristos 				    len == 0 ? "" : ",", n);
1191c879b655Schristos 				len += sn;
1192c879b655Schristos 			}
1193c879b655Schristos 		}
1194c879b655Schristos 		strprintorsetwidth(v, buf, mode);
1195c879b655Schristos 		free(buf);
1196c879b655Schristos #undef SIGSETSIZE
1197c879b655Schristos 	}
1198c879b655Schristos }
1199c879b655Schristos 
1200c879b655Schristos static void
printflag(VAR * v,int flag,enum mode mode)1201c879b655Schristos printflag(VAR *v, int flag, enum mode mode)
1202c879b655Schristos {
1203c879b655Schristos 	char buf[1024];
12049dc307c4Schristos 	const char *fmt;
12059dc307c4Schristos 
12069dc307c4Schristos 	switch (v->type) {
12079dc307c4Schristos 	case PROCFLAG:
12089dc307c4Schristos 		fmt = __SYSCTL_PROC_FLAG_BITS;
12099dc307c4Schristos 		break;
12109dc307c4Schristos 	case KTRACEFLAG:
12119dc307c4Schristos 		fmt = __KTRACE_FLAG_BITS;
12129dc307c4Schristos 		break;
12139dc307c4Schristos 	case PROCACFLAG:
12149dc307c4Schristos 		fmt = __ACCT_FLAG_BITS;
12159dc307c4Schristos 		break;
12169dc307c4Schristos 	default:
12179dc307c4Schristos 		err(EXIT_FAILURE, "Bad type %d", v->type);
1218c879b655Schristos 	}
1219c879b655Schristos 
12209dc307c4Schristos 	snprintb(buf, sizeof(buf), fmt, (unsigned)flag);
1221c879b655Schristos 	strprintorsetwidth(v, buf, mode);
1222c879b655Schristos }
1223c879b655Schristos 
122461f28255Scgd /*
122561f28255Scgd  * Generic output routines.  Print fields from various prototype
122661f28255Scgd  * structures.
122761f28255Scgd  */
12284d1457ceScgd static void
printval(void * bp,VAR * v,enum mode mode)12294e3b1a0bSdholland printval(void *bp, VAR *v, enum mode mode)
123061f28255Scgd {
123161f28255Scgd 	static char ofmt[32] = "%";
1232a98dd470Ssimonb 	int width, vok, fmtlen;
12336310b596Schristos 	const char *fcp;
12346310b596Schristos 	char *cp;
1235f24cb256Sdsl 	int64_t val;
1236f24cb256Sdsl 	u_int64_t uval;
123761f28255Scgd 
12381d55d889She 	val = 0;	/* XXXGCC -Wuninitialized [hpcarm] */
12391d55d889She 	uval = 0;	/* XXXGCC -Wuninitialized [hpcarm] */
12401d55d889She 
1241731f8de0Scgd 	/*
124281a15254Scgd 	 * Note that the "INF127" check is nonsensical for types
1243731f8de0Scgd 	 * that are or can be signed.
1244731f8de0Scgd 	 */
1245731f8de0Scgd #define	GET(type)		(*(type *)bp)
124681a15254Scgd #define	CHK_INF127(n)		(((n) > 127) && (v->flag & INF127) ? 127 : (n))
1247731f8de0Scgd 
1248a98dd470Ssimonb #define	VSIGN	1
1249a98dd470Ssimonb #define	VUNSIGN	2
1250a98dd470Ssimonb #define	VPTR	3
1251a98dd470Ssimonb 
1252a98dd470Ssimonb 	if (mode == WIDTHMODE) {
1253a98dd470Ssimonb 		vok = 0;
1254a98dd470Ssimonb 		switch (v->type) {
1255a98dd470Ssimonb 		case CHAR:
1256a98dd470Ssimonb 			val = GET(char);
1257a98dd470Ssimonb 			vok = VSIGN;
1258a98dd470Ssimonb 			break;
1259a98dd470Ssimonb 		case UCHAR:
1260a98dd470Ssimonb 			uval = CHK_INF127(GET(u_char));
1261a98dd470Ssimonb 			vok = VUNSIGN;
1262a98dd470Ssimonb 			break;
1263a98dd470Ssimonb 		case SHORT:
1264a98dd470Ssimonb 			val = GET(short);
1265a98dd470Ssimonb 			vok = VSIGN;
1266a98dd470Ssimonb 			break;
1267c879b655Schristos 		case PROCACFLAG:
1268c879b655Schristos 			if (v->flag & ALTPR)
1269c879b655Schristos 				break;
1270c879b655Schristos 			/*FALLTHROUGH*/
1271a98dd470Ssimonb 		case USHORT:
1272a98dd470Ssimonb 			uval = CHK_INF127(GET(u_short));
1273a98dd470Ssimonb 			vok = VUNSIGN;
1274a98dd470Ssimonb 			break;
1275a98dd470Ssimonb 		case INT32:
1276a98dd470Ssimonb 			val = GET(int32_t);
1277a98dd470Ssimonb 			vok = VSIGN;
1278a98dd470Ssimonb 			break;
12799dc307c4Schristos 		case KTRACEFLAG:
1280c879b655Schristos 		case PROCFLAG:
1281c879b655Schristos 			if (v->flag & ALTPR)
1282c879b655Schristos 				break;
1283c879b655Schristos 			/*FALLTHROUGH*/
1284a98dd470Ssimonb 		case INT:
1285a98dd470Ssimonb 			val = GET(int);
1286a98dd470Ssimonb 			vok = VSIGN;
1287a98dd470Ssimonb 			break;
1288a98dd470Ssimonb 		case UINT:
1289a98dd470Ssimonb 		case UINT32:
1290a98dd470Ssimonb 			uval = CHK_INF127(GET(u_int));
1291a98dd470Ssimonb 			vok = VUNSIGN;
1292a98dd470Ssimonb 			break;
1293a98dd470Ssimonb 		case LONG:
1294a98dd470Ssimonb 			val = GET(long);
1295a98dd470Ssimonb 			vok = VSIGN;
1296a98dd470Ssimonb 			break;
1297a98dd470Ssimonb 		case ULONG:
1298a98dd470Ssimonb 			uval = CHK_INF127(GET(u_long));
1299a98dd470Ssimonb 			vok = VUNSIGN;
1300a98dd470Ssimonb 			break;
1301a98dd470Ssimonb 		case KPTR:
1302f24cb256Sdsl 			uval = GET(u_int64_t);
1303a98dd470Ssimonb 			vok = VPTR;
1304a98dd470Ssimonb 			break;
1305a98dd470Ssimonb 		case KPTR24:
1306f24cb256Sdsl 			uval = GET(u_int64_t);
1307f320afb2Sitojun 			uval &= 0xffffff;
1308a98dd470Ssimonb 			vok = VPTR;
1309a98dd470Ssimonb 			break;
131043634bc5Snathanw 		case INT64:
1311f24cb256Sdsl 			val = GET(int64_t);
131243634bc5Snathanw 			vok = VSIGN;
131343634bc5Snathanw 			break;
131443634bc5Snathanw 		case UINT64:
1315f24cb256Sdsl 			uval = CHK_INF127(GET(u_int64_t));
131643634bc5Snathanw 			vok = VUNSIGN;
131743634bc5Snathanw 			break;
131843634bc5Snathanw 
1319f24cb256Sdsl 		case SIGLIST:
1320a98dd470Ssimonb 		default:
1321a98dd470Ssimonb 			/* nothing... */;
1322a98dd470Ssimonb 		}
1323a98dd470Ssimonb 		switch (vok) {
1324a98dd470Ssimonb 		case VSIGN:
1325a98dd470Ssimonb 			if (val < 0 && val < v->longestn) {
1326a98dd470Ssimonb 				v->longestn = val;
1327f24cb256Sdsl 				fmtlen = iwidth(-val) + 1;
1328a98dd470Ssimonb 				if (fmtlen > v->width)
1329a98dd470Ssimonb 					v->width = fmtlen;
1330a98dd470Ssimonb 			} else if (val > 0 && val > v->longestp) {
1331a98dd470Ssimonb 				v->longestp = val;
1332f24cb256Sdsl 				fmtlen = iwidth(val);
1333a98dd470Ssimonb 				if (fmtlen > v->width)
1334a98dd470Ssimonb 					v->width = fmtlen;
1335a98dd470Ssimonb 			}
1336a98dd470Ssimonb 			return;
1337a98dd470Ssimonb 		case VUNSIGN:
1338a98dd470Ssimonb 			if (uval > v->longestu) {
1339a98dd470Ssimonb 				v->longestu = uval;
1340f24cb256Sdsl 				v->width = iwidth(uval);
1341a98dd470Ssimonb 			}
1342a98dd470Ssimonb 			return;
1343a98dd470Ssimonb 		case VPTR:
1344a98dd470Ssimonb 			fmtlen = 0;
1345a98dd470Ssimonb 			while (uval > 0) {
1346a98dd470Ssimonb 				uval >>= 4;
1347a98dd470Ssimonb 				fmtlen++;
1348a98dd470Ssimonb 			}
1349a98dd470Ssimonb 			if (fmtlen > v->width)
1350a98dd470Ssimonb 				v->width = fmtlen;
1351a98dd470Ssimonb 			return;
1352a98dd470Ssimonb 		}
1353a98dd470Ssimonb 	}
1354a98dd470Ssimonb 
1355a98dd470Ssimonb 	width = v->width;
1356a98dd470Ssimonb 	cp = ofmt + 1;
1357a98dd470Ssimonb 	fcp = v->fmt;
1358a98dd470Ssimonb 	if (v->flag & LJUST)
1359a98dd470Ssimonb 		*cp++ = '-';
1360a98dd470Ssimonb 	*cp++ = '*';
1361a98dd470Ssimonb 	while ((*cp++ = *fcp++) != '\0')
1362a98dd470Ssimonb 		continue;
1363a98dd470Ssimonb 
136461f28255Scgd 	switch (v->type) {
136561f28255Scgd 	case CHAR:
1366a98dd470Ssimonb 		(void)printf(ofmt, width, GET(char));
1367a98dd470Ssimonb 		return;
136861f28255Scgd 	case UCHAR:
1369a98dd470Ssimonb 		(void)printf(ofmt, width, CHK_INF127(GET(u_char)));
1370a98dd470Ssimonb 		return;
137161f28255Scgd 	case SHORT:
1372a98dd470Ssimonb 		(void)printf(ofmt, width, GET(short));
1373a98dd470Ssimonb 		return;
1374c879b655Schristos 	case PROCACFLAG:
1375c879b655Schristos 		if (v->flag & ALTPR) {
13769dc307c4Schristos 			printflag(v, CHK_INF127(GET(u_short)), mode);
1377c879b655Schristos 			return;
1378c879b655Schristos 		}
1379c879b655Schristos 		/*FALLTHROUGH*/
138061f28255Scgd 	case USHORT:
1381a98dd470Ssimonb 		(void)printf(ofmt, width, CHK_INF127(GET(u_short)));
1382a98dd470Ssimonb 		return;
13839dc307c4Schristos 	case KTRACEFLAG:
1384c879b655Schristos 	case PROCFLAG:
1385c879b655Schristos 		if (v->flag & ALTPR) {
1386c879b655Schristos 			printflag(v, GET(int), mode);
1387c879b655Schristos 			return;
1388c879b655Schristos 		}
1389c879b655Schristos 		/*FALLTHROUGH*/
1390630b3b09Scgd 	case INT:
1391a98dd470Ssimonb 		(void)printf(ofmt, width, GET(int));
1392a98dd470Ssimonb 		return;
1393630b3b09Scgd 	case UINT:
1394a98dd470Ssimonb 		(void)printf(ofmt, width, CHK_INF127(GET(u_int)));
1395a98dd470Ssimonb 		return;
139661f28255Scgd 	case LONG:
1397a98dd470Ssimonb 		(void)printf(ofmt, width, GET(long));
1398a98dd470Ssimonb 		return;
139961f28255Scgd 	case ULONG:
1400a98dd470Ssimonb 		(void)printf(ofmt, width, CHK_INF127(GET(u_long)));
1401a98dd470Ssimonb 		return;
140261f28255Scgd 	case KPTR:
1403f24cb256Sdsl 		(void)printf(ofmt, width, GET(u_int64_t));
1404a98dd470Ssimonb 		return;
1405d5c7180eSmrg 	case KPTR24:
1406f24cb256Sdsl 		(void)printf(ofmt, width, GET(u_int64_t) & 0xffffff);
1407f24cb256Sdsl 		return;
1408f24cb256Sdsl 	case INT32:
1409f24cb256Sdsl 		(void)printf(ofmt, width, GET(int32_t));
1410f24cb256Sdsl 		return;
1411f24cb256Sdsl 	case UINT32:
1412f24cb256Sdsl 		(void)printf(ofmt, width, CHK_INF127(GET(u_int32_t)));
1413a98dd470Ssimonb 		return;
141443634bc5Snathanw 	case INT64:
1415f24cb256Sdsl 		(void)printf(ofmt, width, GET(int64_t));
141643634bc5Snathanw 		return;
141743634bc5Snathanw 	case UINT64:
1418f24cb256Sdsl 		(void)printf(ofmt, width, CHK_INF127(GET(u_int64_t)));
141943634bc5Snathanw 		return;
1420c879b655Schristos 	case SIGLIST:
1421c879b655Schristos 		printsig(v, (const sigset_t *)(void *)bp, mode);
1422c879b655Schristos 		return;
142361f28255Scgd 	default:
1424b02b35c9Schristos 		errx(EXIT_FAILURE, "unknown type %d", v->type);
142561f28255Scgd 	}
1426731f8de0Scgd #undef GET
142781a15254Scgd #undef CHK_INF127
142861f28255Scgd }
14294d1457ceScgd 
14304d1457ceScgd void
pvar(struct pinfo * pi,VARENT * ve,enum mode mode)14315a6cfab1Schristos pvar(struct pinfo *pi, VARENT *ve, enum mode mode)
14324d1457ceScgd {
14336721aabcSchristos 	VAR *v = ve->var;
14346721aabcSchristos 	char *b = (v->flag & LWP) ? (char *)pi->li : (char *)pi->ki;
14354d1457ceScgd 
14366721aabcSchristos 	if ((v->flag & UAREA) && !pi->ki->p_uvalid) {
1437f24cb256Sdsl 		if (mode == PRINTMODE)
1438f24cb256Sdsl 			(void)printf("%*s", v->width, "-");
1439f24cb256Sdsl 		return;
1440f24cb256Sdsl 	}
1441f24cb256Sdsl 
14426721aabcSchristos 	(void)printval(b + v->off, v, mode);
14434d1457ceScgd }
1444f24cb256Sdsl 
1445f24cb256Sdsl void
putimeval(struct pinfo * pi,VARENT * ve,enum mode mode)14465a6cfab1Schristos putimeval(struct pinfo *pi, VARENT *ve, enum mode mode)
1447f24cb256Sdsl {
1448f24cb256Sdsl 	VAR *v = ve->var;
14495a6cfab1Schristos 	struct kinfo_proc2 *k = pi->ki;
14506721aabcSchristos 	char *b = (v->flag & LWP) ? (char *)pi->li : (char *)pi->ki;
14516721aabcSchristos 	ulong secs = *(uint32_t *)(b + v->off);
14526721aabcSchristos 	ulong usec = *(uint32_t *)(b + v->off + sizeof (uint32_t));
1453f24cb256Sdsl 	int fmtlen;
1454f24cb256Sdsl 
1455f24cb256Sdsl 	if (!k->p_uvalid) {
1456f24cb256Sdsl 		if (mode == PRINTMODE)
1457f24cb256Sdsl 			(void)printf("%*s", v->width, "-");
1458f24cb256Sdsl 		return;
1459f24cb256Sdsl 	}
1460f24cb256Sdsl 
1461f24cb256Sdsl 	if (mode == WIDTHMODE) {
146263e11689Ssimonb 		if (secs == 0)
146363e11689Ssimonb 			/* non-zero so fmtlen is calculated at least once */
1464f24cb256Sdsl 			secs = 1;
1465f24cb256Sdsl 		if (secs > v->longestu) {
1466f24cb256Sdsl 			v->longestu = secs;
1467f24cb256Sdsl 			if (secs <= 999)
1468f24cb256Sdsl 				/* sss.ssssss */
1469f24cb256Sdsl 				fmtlen = iwidth(secs) + 6 + 1;
1470f24cb256Sdsl 			else
1471f24cb256Sdsl 				/* hh:mm:ss.ss */
1472c2c93105Ssimonb 				fmtlen = iwidth((secs + 1) / SECSPERHOUR)
1473f24cb256Sdsl 					+ 2 + 1 + 2 + 1 + 2 + 1;
1474f24cb256Sdsl 			if (fmtlen > v->width)
1475f24cb256Sdsl 				v->width = fmtlen;
1476f24cb256Sdsl 		}
1477f24cb256Sdsl 		return;
1478f24cb256Sdsl 	}
1479f24cb256Sdsl 
1480f24cb256Sdsl 	if (secs < 999)
1481f24cb256Sdsl 		(void)printf( "%*lu.%.6lu", v->width - 6 - 1, secs, usec);
1482f24cb256Sdsl 	else {
1483f24cb256Sdsl 		uint h, m;
1484f24cb256Sdsl 		usec += 5000;
1485f24cb256Sdsl 		if (usec >= 1000000) {
1486f24cb256Sdsl 			usec -= 1000000;
1487f24cb256Sdsl 			secs++;
1488f24cb256Sdsl 		}
1489c2c93105Ssimonb 		m = secs / SECSPERMIN;
1490c2c93105Ssimonb 		secs -= m * SECSPERMIN;
1491c2c93105Ssimonb 		h = m / MINSPERHOUR;
1492c2c93105Ssimonb 		m -= h * MINSPERHOUR;
1493abb32017Ssimonb 		(void)printf( "%*u:%.2u:%.2lu.%.2lu", v->width - 9, h, m, secs,
1494abb32017Ssimonb 		    usec / 10000u );
1495f24cb256Sdsl 	}
1496f24cb256Sdsl }
149737ac06beSyamt 
149837ac06beSyamt void
lname(struct pinfo * pi,VARENT * ve,enum mode mode)14995a6cfab1Schristos lname(struct pinfo *pi, VARENT *ve, enum mode mode)
150037ac06beSyamt {
15015a6cfab1Schristos 	struct kinfo_lwp *l = pi->li;
150237ac06beSyamt 	VAR *v;
150337ac06beSyamt 
150437ac06beSyamt 	v = ve->var;
15050bab8dfeSjoerg 	if (l->l_name[0] != '\0') {
150637ac06beSyamt 		strprintorsetwidth(v, l->l_name, mode);
150737ac06beSyamt 		v->width = min(v->width, KI_LNAMELEN);
150837ac06beSyamt 	} else {
150937ac06beSyamt 		if (mode == PRINTMODE)
151037ac06beSyamt 			(void)printf("%-*s", v->width, "-");
151137ac06beSyamt 	}
151237ac06beSyamt }
1513