1/*	$OpenBSD: print.c,v 1.89 2024/04/28 16:43:15 florian Exp $	*/
2/*	$NetBSD: print.c,v 1.27 1995/09/29 21:58:12 cgd Exp $	*/
3
4/*-
5 * Copyright (c) 1990, 1993, 1994
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/param.h>	/* PZERO NODEV */
34#include <sys/types.h>
35#include <sys/signal.h>
36#include <sys/proc.h>
37#include <sys/stat.h>
38
39#include <sys/sysctl.h>
40#define PLEDGENAMES
41#include <sys/pledge.h>
42
43#include <err.h>
44#include <grp.h>
45#include <kvm.h>
46#include <math.h>
47#include <nlist.h>
48#include <stddef.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#include <unistd.h>
53#include <limits.h>
54#include <pwd.h>
55
56#include "ps.h"
57
58extern kvm_t *kd;
59extern int needenv, needcomm, neednlist, commandonly;
60
61int mbswprint(const char *, int, int);  /* utf8.c */
62
63static char *cmdpart(char *);
64
65#define	min(a,b)	((a) < (b) ? (a) : (b))
66
67static char *
68cmdpart(char *arg0)
69{
70	char *cp;
71
72	return ((cp = strrchr(arg0, '/')) != NULL ? cp + 1 : arg0);
73}
74
75void
76printheader(void)
77{
78	VAR *v;
79	struct varent *vent;
80
81	if (!needheader)
82		return;
83	for (vent = vhead; vent; vent = vent->next) {
84		v = vent->var;
85		if (v->flag & LJUST) {
86			if (vent->next == NULL)	/* last one */
87				(void)printf("%s", v->header);
88			else
89				(void)printf("%-*s", v->width, v->header);
90		} else
91			(void)printf("%*s", v->width, v->header);
92		if (vent->next != NULL)
93			(void)putchar(' ');
94	}
95	(void)putchar('\n');
96}
97
98static int
99print_comm_name(const struct kinfo_proc *kp, int left, int trail)
100{
101	left -= mbswprint(kp->p_comm, left, trail);
102	if (left > 1 && kp->p_name[0] != '\0') {
103		putchar('/');
104		left--;
105		left -= mbswprint(kp->p_name, left, trail);
106	}
107	return left;
108}
109
110void
111command(const struct pinfo *pi, VARENT *ve)
112{
113	const struct kinfo_proc *kp = pi->ki;
114	VAR *v;
115	int left, wantspace = 0;
116	char **p;
117
118	/*
119	 * Determine the available number of display columns.
120	 * Always decrement and check after writing.
121	 * No check is needed before mbswprint()
122	 * and after writing the last data, though.
123	 */
124
125	v = ve->var;
126	if (ve->next != NULL || termwidth != UNLIMITED) {
127		if (ve->next == NULL) {
128			left = termwidth - (totwidth - v->width);
129			if (left < 1) /* already wrapped, just use std width */
130				left = v->width;
131		} else
132			left = v->width;
133	} else
134		left = INT_MAX;
135
136	if (needenv && kd != NULL) {
137		char **envp = kvm_getenvv(kd, kp, termwidth);
138		if ((p = envp) != NULL) {
139			while (*p) {
140				if (wantspace) {
141					putchar(' ');
142					left--;
143				}
144				left -= mbswprint(*p, left, 0);
145				if (left == 0)
146					return;
147				p++;
148				wantspace = 1;
149			}
150		}
151	}
152
153	if (needcomm) {
154		if (pi->prefix)
155			left -= mbswprint(pi->prefix, left, 0);
156		if (!commandonly) {
157			char **argv = NULL;
158
159			if (kd != NULL) {
160				argv = kvm_getargv(kd, kp, termwidth);
161				if ((p = argv) != NULL) {
162					while (*p) {
163						if (wantspace) {
164							putchar(' ');
165							left--;
166						}
167						left -= mbswprint(*p, left, 0);
168						if (left == 0)
169							return;
170						p++;
171						wantspace = 1;
172					}
173				}
174			}
175			if (argv == NULL || argv[0] == NULL ||
176			    kp->p_name[0] != '\0' ||
177			    strcmp(cmdpart(argv[0]), kp->p_comm)) {
178				if (wantspace) {
179					putchar(' ');
180					if (--left == 0)
181						return;
182				}
183				putchar('(');
184				left--;
185				left = print_comm_name(kp, left, 0);
186				if (left == 0)
187					return;
188				putchar(')');
189				left--;
190			}
191		} else {
192			if (wantspace) {
193				putchar(' ');
194				left--;
195			}
196			left = print_comm_name(kp, left, 0);
197		}
198	}
199	if (ve->next != NULL)
200		while (left-- > 0)
201			putchar(' ');
202}
203
204void
205ucomm(const struct pinfo *pi, VARENT *ve)
206{
207	const struct kinfo_proc *kp = pi->ki;
208	mbswprint(kp->p_comm, ve->var->width, ve->next != NULL);
209}
210
211void
212curwd(const struct pinfo *pi, VARENT *ve)
213{
214	const struct kinfo_proc *kp = pi->ki;
215	int name[] = { CTL_KERN, KERN_PROC_CWD, kp->p_pid };
216	char path[PATH_MAX];
217	size_t pathlen = sizeof path;
218
219	if (!kvm_sysctl_only || sysctl(name, 3, path, &pathlen, NULL, 0) != 0)
220		*path = '\0';
221
222	mbswprint(path, ve->var->width, ve->next != NULL);
223}
224
225void
226logname(const struct pinfo *pi, VARENT *ve)
227{
228	const struct kinfo_proc *kp = pi->ki;
229	VAR *v;
230
231	v = ve->var;
232	if (kp->p_login[0]) {
233		int n = min(v->width, LOGIN_NAME_MAX);
234		mbswprint(kp->p_login, n, ve->next != NULL);
235		if (ve->next != NULL)
236			while (n++ < v->width)
237				putchar(' ');
238	} else
239		(void)printf("%-*s", v->width, "-");
240}
241
242#define pgtok(a)	(((unsigned long long)(a)*getpagesize())/1024)
243
244void
245printstate(const struct pinfo *pi, VARENT *ve)
246{
247	const struct kinfo_proc *kp = pi->ki;
248	int flag;
249	char *cp, state = '\0';
250	VAR *v;
251	char buf[16];
252
253	v = ve->var;
254	flag = kp->p_flag;
255	cp = buf;
256
257	switch (kp->p_stat) {
258
259	case SSTOP:
260		*cp = 'T';
261		break;
262
263	case SSLEEP:
264		if (flag & P_SINTR)	/* interruptible (long) */
265			*cp = kp->p_slptime >= maxslp ? 'I' : 'S';
266		else
267			*cp = 'D';
268		break;
269
270	case SRUN:
271	case SIDL:
272	case SONPROC:
273		state = *cp = 'R';
274		break;
275
276	case SDEAD:
277		*cp = 'Z';
278		break;
279
280	default:
281		*cp = '?';
282	}
283	cp++;
284
285	if (kp->p_nice < NZERO)
286		*cp++ = '<';
287	else if (kp->p_nice > NZERO)
288		*cp++ = 'N';
289	if (kp->p_psflags & PS_TRACED)
290		*cp++ = 'X';
291	if ((kp->p_psflags & (PS_EXITING | PS_ZOMBIE)) == PS_EXITING)
292		*cp++ = 'E';
293	if (kp->p_psflags & PS_ISPWAIT)
294		*cp++ = 'V';
295	if (flag & P_SYSTEM)
296		*cp++ = 'K';
297	if ((flag & P_SYSTEM) == 0 &&
298	    kp->p_rlim_rss_cur / 1024 < pgtok(kp->p_vm_rssize))
299		*cp++ = '>';
300	if (kp->p_eflag & EPROC_SLEADER)
301		*cp++ = 's';
302	if ((kp->p_psflags & PS_CONTROLT) && kp->p__pgid == kp->p_tpgid)
303		*cp++ = '+';
304	if (kp->p_psflags & PS_PLEDGE)
305		*cp++ = 'p';
306	if (kp->p_eflag & EPROC_UNVEIL) {
307		if (kp->p_eflag & EPROC_LKUNVEIL)
308			*cp++ = 'U';
309		else
310			*cp++ = 'u';
311	}
312	if (kp->p_psflags & PS_CHROOT)
313		*cp++ = 'c';
314	*cp = '\0';
315
316	if (state == 'R' && kp->p_cpuid != KI_NOCPU) {
317		char pbuf[16];
318
319		snprintf(pbuf, sizeof pbuf, "/%llu", kp->p_cpuid);
320		*++cp = '\0';
321		strlcat(buf, pbuf, sizeof buf);
322		cp = buf + strlen(buf);
323	}
324
325	(void)printf("%-*s", v->width, buf);
326}
327
328void
329printpledge(const struct pinfo *pi, VARENT *ve)
330{
331	const struct kinfo_proc *kp = pi->ki;
332	int i;
333	VAR *v;
334	char buf[1024];
335
336	v = ve->var;
337	buf[0] = '\0';
338
339	for (i = 0; pledgenames[i].bits != 0; i++) {
340		if (pledgenames[i].bits & kp->p_pledge) {
341			if (*buf != '\0')
342				strlcat(buf, ",", sizeof buf);
343			strlcat(buf, pledgenames[i].name, sizeof buf);
344		}
345	}
346
347	(void)printf("%-*s", v->width, buf);
348}
349
350void
351pri(const struct pinfo *pi, VARENT *ve)
352{
353	const struct kinfo_proc *kp = pi->ki;
354	VAR *v;
355
356	v = ve->var;
357	(void)printf("%*d", v->width, kp->p_priority - PZERO);
358}
359
360void
361pnice(const struct pinfo *pi, VARENT *ve)
362{
363	const struct kinfo_proc *kp = pi->ki;
364	VAR *v;
365
366	v = ve->var;
367	(void)printf("%*d", v->width, kp->p_nice - NZERO);
368}
369
370void
371euname(const struct pinfo *pi, VARENT *ve)
372{
373	const struct kinfo_proc *kp = pi->ki;
374
375	mbswprint(user_from_uid(kp->p_uid, 0), ve->var->width,
376	    ve->next != NULL);
377}
378
379void
380runame(const struct pinfo *pi, VARENT *ve)
381{
382	const struct kinfo_proc *kp = pi->ki;
383
384	mbswprint(user_from_uid(kp->p_ruid, 0), ve->var->width,
385	    ve->next != NULL);
386}
387
388void
389gname(const struct pinfo *pi, VARENT *ve)
390{
391	const struct kinfo_proc *kp = pi->ki;
392
393	mbswprint(group_from_gid(kp->p_gid, 0), ve->var->width,
394	    ve->next != NULL);
395}
396
397void
398rgname(const struct pinfo *pi, VARENT *ve)
399{
400	const struct kinfo_proc *kp = pi->ki;
401
402	mbswprint(group_from_gid(kp->p_rgid, 0), ve->var->width,
403	    ve->next != NULL);
404}
405
406void
407supgid(const struct pinfo *pi, VARENT *ve)
408{
409	const struct kinfo_proc *kp = pi->ki;
410	char buf[1024];
411	char *p = buf;
412	ssize_t size = sizeof(buf);
413	int i, len;
414
415	for (i = 0; i < kp->p_ngroups; i++) {
416		len = snprintf(p, size, "%s%u",
417		    p == buf ? "" : ",",
418		    kp->p_groups[i]);
419		if (len < 0 || len >= size)
420			break;
421		p += len;
422		size -= len;
423	}
424
425	(void)printf("%-*s", ve->var->width, buf);
426}
427
428void
429supgrp(const struct pinfo *pi, VARENT *ve)
430{
431	const struct kinfo_proc *kp = pi->ki;
432	char buf[1024];
433	char *p = buf;
434	ssize_t size = sizeof(buf);
435	int i, len;
436
437	for (i = 0; i < kp->p_ngroups; i++) {
438		len = snprintf(p, size, "%s%s",
439		    p == buf ? "" : ",",
440		    group_from_gid(kp->p_groups[i], 0));
441		if (len < 0 || len >= size)
442			break;
443		p += len;
444		size -= len;
445	}
446
447	(void)printf("%-*s", ve->var->width, buf);
448}
449
450void
451tdev(const struct pinfo *pi, VARENT *ve)
452{
453	const struct kinfo_proc *kp = pi->ki;
454	VAR *v;
455	dev_t dev;
456
457	v = ve->var;
458	dev = kp->p_tdev;
459	if (dev == NODEV)
460		(void)printf("%*s", v->width, "??");
461	else {
462		char buff[10+1+10+1];
463
464		(void)snprintf(buff, sizeof(buff),
465		    "%u/%u", major(dev), minor(dev));
466		(void)printf("%*s", v->width, buff);
467	}
468}
469
470void
471tname(const struct pinfo *pi, VARENT *ve)
472{
473	const struct kinfo_proc *kp = pi->ki;
474	VAR *v;
475	dev_t dev;
476	char *ttname;
477
478	v = ve->var;
479	dev = kp->p_tdev;
480	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
481		(void)printf("%-*s", v->width, "??");
482	else {
483		if (strncmp(ttname, "tty", 3) == 0)
484			ttname += 3;
485		(void)printf("%*.*s%c", v->width-1, v->width-1, ttname,
486			kp->p_eflag & EPROC_CTTY ? ' ' : '-');
487	}
488}
489
490void
491longtname(const struct pinfo *pi, VARENT *ve)
492{
493	const struct kinfo_proc *kp = pi->ki;
494	VAR *v;
495	dev_t dev;
496	char *ttname;
497
498	v = ve->var;
499	dev = kp->p_tdev;
500	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
501		(void)printf("%-*s", v->width, "??");
502	else
503		(void)printf("%-*s", v->width, ttname);
504}
505
506void
507started(const struct pinfo *pi, VARENT *ve)
508{
509	const struct kinfo_proc *kp = pi->ki;
510	VAR *v;
511	static time_t now;
512	time_t startt;
513	struct tm *tp;
514	char buf[100];
515
516	v = ve->var;
517	if (!kp->p_uvalid) {
518		(void)printf("%-*s", v->width, "-");
519		return;
520	}
521
522#define SECSPERHOUR	(60 * 60)
523#define SECSPERDAY	(24 * 60 * 60)
524
525	startt = kp->p_ustart_sec;
526	tp = localtime(&startt);
527	if (tp == NULL) {
528		(void)printf("%-*s", v->width, "-");
529		return;
530	}
531	if (!now)
532		(void)time(&now);
533	if (now - kp->p_ustart_sec < 12 * SECSPERHOUR) {
534		(void)strftime(buf, sizeof(buf) - 1, "%l:%M%p", tp);
535	} else if (now - kp->p_ustart_sec < 7 * SECSPERDAY) {
536		(void)strftime(buf, sizeof(buf) - 1, "%a%I%p", tp);
537	} else
538		(void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
539	(void)printf("%-*s", v->width, buf);
540}
541
542void
543lstarted(const struct pinfo *pi, VARENT *ve)
544{
545	const struct kinfo_proc *kp = pi->ki;
546	VAR *v;
547	time_t startt;
548	char buf[100];
549
550	v = ve->var;
551	if (!kp->p_uvalid) {
552		(void)printf("%-*s", v->width, "-");
553		return;
554	}
555	startt = kp->p_ustart_sec;
556	(void)strftime(buf, sizeof(buf) -1, "%c",
557	    localtime(&startt));
558	(void)printf("%-*s", v->width, buf);
559}
560
561void elapsed(const struct pinfo *pi, VARENT *ve)
562{
563	const struct kinfo_proc *kp = pi->ki;
564	VAR *v;
565	static time_t now;
566	time_t secs;
567	char buf[64];
568	long days, hours, minutes, seconds;
569
570	v = ve->var;
571	if (!kp->p_uvalid) {
572		(void)printf("%*s", v->width, "-");
573		return;
574	}
575
576	if (!now)
577		(void)time(&now);
578	secs = now - kp->p_ustart_sec;
579
580	if (secs < 0) {
581		(void)printf("%*s", v->width, "-");
582		return;
583	}
584
585	days = secs / SECSPERDAY;
586	secs %= SECSPERDAY;
587
588	hours = secs / SECSPERHOUR;
589	secs %= SECSPERHOUR;
590
591	minutes = secs / 60;
592	seconds = secs % 60;
593
594	if (days > 0)
595		(void)snprintf(buf, sizeof(buf), "%ld-%02ld:%02ld:%02ld",
596		    days, hours, minutes, seconds);
597	else if (hours > 0)
598		(void)snprintf(buf, sizeof(buf), "%02ld:%02ld:%02ld",
599		    hours, minutes, seconds);
600	else
601		(void)snprintf(buf, sizeof(buf), "%02ld:%02ld",
602		    minutes, seconds);
603	(void)printf("%*s", v->width, buf);
604}
605
606void
607wchan(const struct pinfo *pi, VARENT *ve)
608{
609	const struct kinfo_proc *kp = pi->ki;
610	VAR *v;
611
612	v = ve->var;
613	if (kp->p_wmesg[0]) {
614		(void)printf("%-*s", (int)v->width, kp->p_wmesg);
615	} else
616		(void)printf("%-*s", v->width, "-");
617}
618
619void
620vsize(const struct pinfo *pi, VARENT *ve)
621{
622	const struct kinfo_proc *kp = pi->ki;
623	VAR *v;
624
625	v = ve->var;
626	(void)printf("%*llu", v->width,
627	    pgtok(kp->p_vm_dsize + kp->p_vm_ssize + kp->p_vm_tsize));
628}
629
630void
631rssize(const struct pinfo *pi, VARENT *ve)
632{
633	const struct kinfo_proc *kp = pi->ki;
634	VAR *v;
635
636	v = ve->var;
637	/* XXX don't have info about shared */
638	(void)printf("%*llu", v->width, (kp->p_flag & P_SYSTEM) ? 0 :
639	    pgtok(kp->p_vm_rssize));
640}
641
642void
643p_rssize(const struct pinfo *pi, VARENT *ve)
644{
645	const struct kinfo_proc *kp = pi->ki;
646	VAR *v;
647
648	v = ve->var;
649	(void)printf("%*llu", v->width, (kp->p_flag & P_SYSTEM) ? 0 :
650	    pgtok(kp->p_vm_rssize));
651}
652
653void
654cputime(const struct pinfo *pi, VARENT *ve)
655{
656	const struct kinfo_proc *kp = pi->ki;
657	VAR *v;
658	long secs;
659	long psecs;	/* "parts" of a second. first micro, then centi */
660	char obuff[128];
661
662	v = ve->var;
663	if (kp->p_stat == SDEAD || !kp->p_uvalid) {
664		secs = 0;
665		psecs = 0;
666	} else {
667		/*
668		 * This counts time spent handling interrupts.  XXX
669		 */
670		secs = kp->p_rtime_sec;
671		psecs = kp->p_rtime_usec;
672		if (sumrusage) {
673			secs += kp->p_uctime_sec;
674			psecs += kp->p_uctime_usec;
675		}
676		/*
677		 * round and scale to 100's
678		 */
679		psecs = (psecs + 5000) / 10000;
680		secs += psecs / 100;
681		psecs = psecs % 100;
682	}
683	(void)snprintf(obuff, sizeof(obuff),
684	    "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
685	(void)printf("%*s", v->width, obuff);
686}
687
688double
689getpcpu(const struct kinfo_proc *kp)
690{
691	if (fscale == 0)
692		return (0.0);
693
694#define	fxtofl(fixpt)	((double)(fixpt) / fscale)
695
696	return (100.0 * fxtofl(kp->p_pctcpu));
697}
698
699void
700pcpu(const struct pinfo *pi, VARENT *ve)
701{
702	VAR *v;
703
704	v = ve->var;
705	(void)printf("%*.1f", v->width, getpcpu(pi->ki));
706}
707
708double
709getpmem(const struct kinfo_proc *kp)
710{
711	double fracmem;
712
713	if (mempages == 0)
714		return (0.0);
715
716	if (kp->p_flag & P_SYSTEM)
717		return (0.0);
718	/* XXX don't have info about shared */
719	fracmem = ((float)kp->p_vm_rssize)/mempages;
720	return (100.0 * fracmem);
721}
722
723void
724pmem(const struct pinfo *pi, VARENT *ve)
725{
726	VAR *v;
727
728	v = ve->var;
729	(void)printf("%*.1f", v->width, getpmem(pi->ki));
730}
731
732void
733pagein(const struct pinfo *pi, VARENT *ve)
734{
735	const struct kinfo_proc *kp = pi->ki;
736	VAR *v;
737
738	v = ve->var;
739	(void)printf("%*llu", v->width,
740	    kp->p_uvalid ? kp->p_uru_majflt : 0);
741}
742
743void
744maxrss(const struct pinfo *pi, VARENT *ve)
745{
746	const struct kinfo_proc *kp = pi->ki;
747	VAR *v;
748
749	v = ve->var;
750	(void)printf("%*llu", v->width, kp->p_rlim_rss_cur / 1024);
751}
752
753void
754tsize(const struct pinfo *pi, VARENT *ve)
755{
756	const struct kinfo_proc *kp = pi->ki;
757	VAR *v;
758
759	v = ve->var;
760	(void)printf("%*llu", v->width, pgtok(kp->p_vm_tsize));
761}
762
763void
764dsize(const struct pinfo *pi, VARENT *ve)
765{
766	const struct kinfo_proc *kp = pi->ki;
767	VAR *v;
768
769	v = ve->var;
770	(void)printf("%*llu", v->width, pgtok(kp->p_vm_dsize));
771}
772
773void
774ssize(const struct pinfo *pi, VARENT *ve)
775{
776	const struct kinfo_proc *kp = pi->ki;
777	VAR *v;
778
779	v = ve->var;
780	(void)printf("%*llu", v->width, pgtok(kp->p_vm_ssize));
781}
782
783/*
784 * Generic output routines.  Print fields from various prototype
785 * structures.
786 */
787static void
788printval(char *bp, VAR *v)
789{
790	char ofmt[32];
791
792	snprintf(ofmt, sizeof(ofmt), "%%%s*%s", (v->flag & LJUST) ? "-" : "",
793	    v->fmt);
794
795	/*
796	 * Note that the "INF127" check is nonsensical for types
797	 * that are or can be signed.
798	 */
799#define	GET(type)		(*(type *)bp)
800#define	CHK_INF127(n)		(((n) > 127) && (v->flag & INF127) ? 127 : (n))
801
802	switch (v->type) {
803	case INT8:
804		(void)printf(ofmt, v->width, GET(int8_t));
805		break;
806	case UINT8:
807		(void)printf(ofmt, v->width, CHK_INF127(GET(u_int8_t)));
808		break;
809	case INT16:
810		(void)printf(ofmt, v->width, GET(int16_t));
811		break;
812	case UINT16:
813		(void)printf(ofmt, v->width, CHK_INF127(GET(u_int16_t)));
814		break;
815	case INT32:
816		(void)printf(ofmt, v->width, GET(int32_t));
817		break;
818	case UINT32:
819		(void)printf(ofmt, v->width, CHK_INF127(GET(u_int32_t)));
820		break;
821	case INT64:
822		(void)printf(ofmt, v->width, GET(int64_t));
823		break;
824	case UINT64:
825		(void)printf(ofmt, v->width, CHK_INF127(GET(u_int64_t)));
826		break;
827	default:
828		errx(1, "unknown type %d", v->type);
829	}
830#undef GET
831#undef CHK_INF127
832}
833
834void
835pvar(const struct pinfo *pi, VARENT *ve)
836{
837	const struct kinfo_proc *kp = pi->ki;
838	VAR *v;
839
840	v = ve->var;
841	if ((v->flag & USER) && !kp->p_uvalid)
842		(void)printf("%*s", v->width, "-");
843	else
844		printval((char *)kp + v->off, v);
845}
846