xref: /openbsd-src/bin/ps/print.c (revision db3296cf5c1dd9058ceecc3a29fe4aaa0bd26000)
1 /*	$OpenBSD: print.c,v 1.31 2003/06/11 23:42:12 deraadt 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 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)print.c	8.6 (Berkeley) 4/16/94";
36 #else
37 static char rcsid[] = "$OpenBSD: print.c,v 1.31 2003/06/11 23:42:12 deraadt Exp $";
38 #endif
39 #endif /* not lint */
40 
41 #include <sys/param.h>
42 #include <sys/time.h>
43 #include <sys/resource.h>
44 #include <sys/proc.h>
45 #include <sys/stat.h>
46 
47 #include <sys/ucred.h>
48 #include <sys/sysctl.h>
49 #include <uvm/uvm_extern.h>
50 
51 #include <err.h>
52 #include <grp.h>
53 #include <kvm.h>
54 #include <math.h>
55 #include <nlist.h>
56 #include <stddef.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <tzfile.h>
61 #include <unistd.h>
62 #include <pwd.h>
63 
64 #include "ps.h"
65 
66 extern kvm_t *kd;
67 extern int needenv, needcomm, commandonly;
68 
69 static char *cmdpart(char *);
70 
71 #define	min(a,b)	((a) < (b) ? (a) : (b))
72 
73 static char *
74 cmdpart(char *arg0)
75 {
76 	char *cp;
77 
78 	return ((cp = strrchr(arg0, '/')) != NULL ? cp + 1 : arg0);
79 }
80 
81 void
82 printheader(void)
83 {
84 	VAR *v;
85 	struct varent *vent;
86 
87 	for (vent = vhead; vent; vent = vent->next) {
88 		v = vent->var;
89 		if (v->flag & LJUST) {
90 			if (vent->next == NULL)	/* last one */
91 				(void)printf("%s", v->header);
92 			else
93 				(void)printf("%-*s", v->width, v->header);
94 		} else
95 			(void)printf("%*s", v->width, v->header);
96 		if (vent->next != NULL)
97 			(void)putchar(' ');
98 	}
99 	(void)putchar('\n');
100 }
101 
102 void
103 command(KINFO *ki, VARENT *ve)
104 {
105 	VAR *v;
106 	int left;
107 	char **argv, **p;
108 
109 	v = ve->var;
110 	if (ve->next != NULL || termwidth != UNLIMITED) {
111 		if (ve->next == NULL) {
112 			left = termwidth - (totwidth - v->width);
113 			if (left < 1) /* already wrapped, just use std width */
114 				left = v->width;
115 		} else
116 			left = v->width;
117 	} else
118 		left = -1;
119 	if (needenv && kd != NULL) {
120 		argv = kvm_getenvv(kd, ki->ki_p, termwidth);
121 		if ((p = argv) != NULL) {
122 			while (*p) {
123 				fmt_puts(*p, &left);
124 				p++;
125 				fmt_putc(' ', &left);
126 			}
127 		}
128 	} else
129 		argv = NULL;
130 	if (needcomm) {
131 		if (!commandonly) {
132 			if (kd != NULL) {
133 				argv = kvm_getargv(kd, ki->ki_p, termwidth);
134 				if ((p = argv) != NULL) {
135 					while (*p) {
136 						fmt_puts(*p, &left);
137 						p++;
138 						fmt_putc(' ', &left);
139 					}
140 				}
141 			}
142 			if (argv == NULL || argv[0] == '\0' ||
143 			    strcmp(cmdpart(argv[0]), KI_PROC(ki)->p_comm)) {
144 				fmt_putc('(', &left);
145 				fmt_puts(KI_PROC(ki)->p_comm, &left);
146 				fmt_putc(')', &left);
147 			}
148 		} else {
149 			fmt_puts(KI_PROC(ki)->p_comm, &left);
150 		}
151 	}
152 	if (ve->next && left > 0)
153 		printf("%*s", left, "");
154 }
155 
156 void
157 ucomm(KINFO *k, VARENT *ve)
158 {
159 	VAR *v;
160 
161 	v = ve->var;
162 	(void)printf("%-*s", v->width, KI_PROC(k)->p_comm);
163 }
164 
165 void
166 logname(KINFO *k, VARENT *ve)
167 {
168 	VAR *v;
169 
170 	v = ve->var;
171 	if (KI_EPROC(k)->e_login[0]) {
172 		int n = min(v->width, MAXLOGNAME);
173 		(void)printf("%-*.*s", n, n, KI_EPROC(k)->e_login);
174 		if (v->width > n)
175 			(void)printf("%*s", v->width - n, "");
176 	} else
177 		(void)printf("%-*s", v->width, "-");
178 }
179 
180 #define pgtok(a)	(((a)*getpagesize())/1024)
181 
182 void
183 state(KINFO *k, VARENT *ve)
184 {
185 	struct proc *p;
186 	int flag;
187 	char *cp;
188 	VAR *v;
189 	char buf[16];
190 
191 	v = ve->var;
192 	p = KI_PROC(k);
193 	flag = p->p_flag;
194 	cp = buf;
195 
196 	switch (p->p_stat) {
197 
198 	case SSTOP:
199 		*cp = 'T';
200 		break;
201 
202 	case SSLEEP:
203 		if (flag & P_SINTR)	/* interruptible (long) */
204 			*cp = p->p_slptime >= maxslp ? 'I' : 'S';
205 		else
206 			*cp = 'D';
207 		break;
208 
209 	case SRUN:
210 	case SIDL:
211 		*cp = 'R';
212 		break;
213 
214 	case SZOMB:
215 		*cp = 'Z';
216 		break;
217 
218 	default:
219 		*cp = '?';
220 	}
221 	cp++;
222 	if (flag & P_INMEM) {
223 	} else
224 		*cp++ = 'W';
225 	if (p->p_nice < NZERO)
226 		*cp++ = '<';
227 	else if (p->p_nice > NZERO)
228 		*cp++ = 'N';
229 	if (flag & P_TRACED)
230 		*cp++ = 'X';
231 	if (flag & P_SYSTRACE)
232 		*cp++ = 'x';
233 	if (flag & P_WEXIT && p->p_stat != SZOMB)
234 		*cp++ = 'E';
235 	if (flag & P_PPWAIT)
236 		*cp++ = 'V';
237 	if (flag & P_SYSTEM)
238 		*cp++ = 'K';
239 	/* XXX Since P_SYSTEM now shows a K, should L just be for holdcnt? */
240 	if ((flag & P_SYSTEM) || p->p_holdcnt)
241 		*cp++ = 'L';
242 	if ((flag & P_SYSTEM) == 0 &&
243 	    KI_EPROC(k)->e_maxrss / 1024 < pgtok(KI_EPROC(k)->e_vm.vm_rssize))
244 		*cp++ = '>';
245 	if (KI_EPROC(k)->e_flag & EPROC_SLEADER)
246 		*cp++ = 's';
247 	if ((flag & P_CONTROLT) && KI_EPROC(k)->e_pgid == KI_EPROC(k)->e_tpgid)
248 		*cp++ = '+';
249 	*cp = '\0';
250 	(void)printf("%-*s", v->width, buf);
251 }
252 
253 void
254 pri(KINFO *k, VARENT *ve)
255 {
256 	VAR *v;
257 
258 	v = ve->var;
259 	(void)printf("%*d", v->width, KI_PROC(k)->p_priority - PZERO);
260 }
261 
262 void
263 uname(KINFO *k, VARENT *ve)
264 {
265 	VAR *v;
266 
267 	v = ve->var;
268 	(void)printf("%-*s",
269 	    (int)v->width, user_from_uid(KI_EPROC(k)->e_ucred.cr_uid, 0));
270 }
271 
272 void
273 runame(KINFO *k, VARENT *ve)
274 {
275 	VAR *v;
276 
277 	v = ve->var;
278 	(void)printf("%-*s",
279 	    (int)v->width, user_from_uid(KI_EPROC(k)->e_pcred.p_ruid, 0));
280 }
281 
282 void
283 gname(KINFO *k, VARENT *ve)
284 {
285 	VAR *v;
286 
287 	v = ve->var;
288 	(void)printf("%-*s",
289 	    (int)v->width, group_from_gid(KI_EPROC(k)->e_ucred.cr_gid, 0));
290 }
291 
292 void
293 rgname(KINFO *k, VARENT *ve)
294 {
295 	VAR *v;
296 
297 	v = ve->var;
298 	(void)printf("%-*s",
299 	    (int)v->width, group_from_gid(KI_EPROC(k)->e_pcred.p_rgid, 0));
300 }
301 
302 void
303 tdev(KINFO *k, VARENT *ve)
304 {
305 	VAR *v;
306 	dev_t dev;
307 	char buff[16];
308 
309 	v = ve->var;
310 	dev = KI_EPROC(k)->e_tdev;
311 	if (dev == NODEV)
312 		(void)printf("%*s", v->width, "??");
313 	else {
314 		(void)snprintf(buff, sizeof(buff),
315 		    "%d/%d", major(dev), minor(dev));
316 		(void)printf("%*s", v->width, buff);
317 	}
318 }
319 
320 void
321 tname(KINFO *k, VARENT *ve)
322 {
323 	VAR *v;
324 	dev_t dev;
325 	char *ttname;
326 
327 	v = ve->var;
328 	dev = KI_EPROC(k)->e_tdev;
329 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
330 		(void)printf("%-*s", v->width, "??");
331 	else {
332 		if (strncmp(ttname, "tty", 3) == 0)
333 			ttname += 3;
334 		(void)printf("%*.*s%c", v->width-1, v->width-1, ttname,
335 			KI_EPROC(k)->e_flag & EPROC_CTTY ? ' ' : '-');
336 	}
337 }
338 
339 void
340 longtname(KINFO *k, VARENT *ve)
341 {
342 	VAR *v;
343 	dev_t dev;
344 	char *ttname;
345 
346 	v = ve->var;
347 	dev = KI_EPROC(k)->e_tdev;
348 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
349 		(void)printf("%-*s", v->width, "??");
350 	else
351 		(void)printf("%-*s", v->width, ttname);
352 }
353 
354 void
355 started(KINFO *k, VARENT *ve)
356 {
357 	VAR *v;
358 	static time_t now;
359 	time_t startt;
360 	struct tm *tp;
361 	char buf[100];
362 
363 	v = ve->var;
364 	if (!k->ki_u.u_valid) {
365 		(void)printf("%-*s", v->width, "-");
366 		return;
367 	}
368 
369 	startt = k->ki_u.u_start.tv_sec;
370 	tp = localtime(&startt);
371 	if (!now)
372 		(void)time(&now);
373 	if (now - k->ki_u.u_start.tv_sec < 24 * SECSPERHOUR) {
374 		(void)strftime(buf, sizeof(buf) - 1, "%l:%M%p", tp);
375 	} else if (now - k->ki_u.u_start.tv_sec < 7 * SECSPERDAY) {
376 		(void)strftime(buf, sizeof(buf) - 1, "%a%I%p", tp);
377 	} else
378 		(void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
379 	(void)printf("%-*s", v->width, buf);
380 }
381 
382 void
383 lstarted(KINFO *k, VARENT *ve)
384 {
385 	VAR *v;
386 	time_t startt;
387 	char buf[100];
388 
389 	v = ve->var;
390 	if (!k->ki_u.u_valid) {
391 		(void)printf("%-*s", v->width, "-");
392 		return;
393 	}
394 	startt = k->ki_u.u_start.tv_sec;
395 	(void)strftime(buf, sizeof(buf) -1, "%c",
396 	    localtime(&startt));
397 	(void)printf("%-*s", v->width, buf);
398 }
399 
400 void
401 wchan(KINFO *k, VARENT *ve)
402 {
403 	VAR *v;
404 
405 	v = ve->var;
406 	if (KI_PROC(k)->p_wchan) {
407 		int n;
408 
409 		if (KI_PROC(k)->p_wmesg) {
410 			n = min(v->width, WMESGLEN);
411 			(void)printf("%-*.*s", n, n, KI_EPROC(k)->e_wmesg);
412 			if (v->width > n)
413 				(void)printf("%*s", v->width - n, "");
414 		} else
415 			(void)printf("%-*lx", v->width,
416 			    (long)KI_PROC(k)->p_wchan &~ KERNBASE);
417 	} else
418 		(void)printf("%-*s", v->width, "-");
419 }
420 
421 void
422 vsize(KINFO *k, VARENT *ve)
423 {
424 	VAR *v;
425 
426 	v = ve->var;
427 	(void)printf("%*d", v->width,
428 	    pgtok(KI_EPROC(k)->e_vm.vm_dsize + KI_EPROC(k)->e_vm.vm_ssize +
429 		KI_EPROC(k)->e_vm.vm_tsize));
430 }
431 
432 void
433 rssize(KINFO *k, VARENT *ve)
434 {
435 	VAR *v;
436 
437 	v = ve->var;
438 	/* XXX don't have info about shared */
439 	(void)printf("%*d", v->width, (KI_PROC(k)->p_flag & P_SYSTEM) ? 0 :
440 	    pgtok(KI_EPROC(k)->e_vm.vm_rssize));
441 }
442 
443 void
444 p_rssize(KINFO *k, VARENT *ve)
445 {
446 	VAR *v;
447 
448 	v = ve->var;
449 	(void)printf("%*d", v->width, (KI_PROC(k)->p_flag & P_SYSTEM) ? 0 :
450 	    pgtok(KI_EPROC(k)->e_vm.vm_rssize));
451 }
452 
453 void
454 cputime(KINFO *k, VARENT *ve)
455 {
456 	VAR *v;
457 	long secs;
458 	long psecs;	/* "parts" of a second. first micro, then centi */
459 	char obuff[128];
460 
461 	v = ve->var;
462 	if (KI_PROC(k)->p_stat == SZOMB || !k->ki_u.u_valid) {
463 		secs = 0;
464 		psecs = 0;
465 	} else {
466 		/*
467 		 * This counts time spent handling interrupts.  We could
468 		 * fix this, but it is not 100% trivial (and interrupt
469 		 * time fractions only work on the sparc anyway).	XXX
470 		 */
471 		secs = KI_PROC(k)->p_rtime.tv_sec;
472 		psecs = KI_PROC(k)->p_rtime.tv_usec;
473 		if (sumrusage) {
474 			secs += k->ki_u.u_cru.ru_utime.tv_sec +
475 				k->ki_u.u_cru.ru_stime.tv_sec;
476 			psecs += k->ki_u.u_cru.ru_utime.tv_usec +
477 				k->ki_u.u_cru.ru_stime.tv_usec;
478 		}
479 		/*
480 		 * round and scale to 100's
481 		 */
482 		psecs = (psecs + 5000) / 10000;
483 		secs += psecs / 100;
484 		psecs = psecs % 100;
485 	}
486 	(void)snprintf(obuff, sizeof(obuff),
487 	    "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
488 	(void)printf("%*s", v->width, obuff);
489 }
490 
491 double
492 getpcpu(KINFO *k)
493 {
494 	struct proc *p;
495 	static int failure;
496 	double d;
497 
498 	if (!nlistread)
499 		failure = donlist();
500 	if (failure)
501 		return (0.0);
502 
503 	p = KI_PROC(k);
504 #define	fxtofl(fixpt)	((double)(fixpt) / fscale)
505 
506 	/* XXX - I don't like this */
507 	if (p->p_swtime == 0 || (p->p_flag & P_INMEM) == 0)
508 		return (0.0);
509 	if (rawcpu)
510 		return (100.0 * fxtofl(p->p_pctcpu));
511 
512 	d = p->p_swtime * log(fxtofl(ccpu));
513 	if (d < -700.0)
514 		d = 0.0;		/* avoid IEEE underflow */
515 	else
516 		d = exp(d);
517 	if (d == 1.0)
518 		return (0.0);
519 	return (100.0 * fxtofl(p->p_pctcpu) /
520 		(1.0 - d));
521 }
522 
523 void
524 pcpu(KINFO *k, VARENT *ve)
525 {
526 	VAR *v;
527 
528 	v = ve->var;
529 	(void)printf("%*.1f", v->width, getpcpu(k));
530 }
531 
532 double
533 getpmem(KINFO *k)
534 {
535 	static int failure;
536 	struct proc *p;
537 	struct eproc *e;
538 	double fracmem;
539 	int szptudot;
540 
541 	if (!nlistread)
542 		failure = donlist();
543 	if (failure)
544 		return (0.0);
545 
546 	p = KI_PROC(k);
547 	e = KI_EPROC(k);
548 	if ((p->p_flag & P_INMEM) == 0 || (p->p_flag & P_SYSTEM))
549 		return (0.0);
550 	/* XXX want pmap ptpages, segtab, etc. (per architecture) */
551 	szptudot = USPACE/getpagesize();
552 	/* XXX don't have info about shared */
553 	fracmem = ((float)e->e_vm.vm_rssize + szptudot)/mempages;
554 	return (100.0 * fracmem);
555 }
556 
557 void
558 pmem(KINFO *k, VARENT *ve)
559 {
560 	VAR *v;
561 
562 	v = ve->var;
563 	(void)printf("%*.1f", v->width, getpmem(k));
564 }
565 
566 void
567 pagein(KINFO *k, VARENT *ve)
568 {
569 	VAR *v;
570 
571 	v = ve->var;
572 	(void)printf("%*ld", v->width,
573 	    k->ki_u.u_valid ? k->ki_u.u_ru.ru_majflt : 0);
574 }
575 
576 void
577 maxrss(KINFO *k, VARENT *ve)
578 {
579 	VAR *v;
580 
581 	v = ve->var;
582 	(void)printf("%*lld", v->width, KI_EPROC(k)->e_maxrss / 1024);
583 }
584 
585 void
586 tsize(KINFO *k, VARENT *ve)
587 {
588 	VAR *v;
589 
590 	v = ve->var;
591 	(void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_vm.vm_tsize));
592 }
593 
594 void
595 dsize(KINFO *k, VARENT *ve)
596 {
597 	VAR *v;
598 
599 	v = ve->var;
600 	(void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_vm.vm_dsize));
601 }
602 
603 void
604 ssize(KINFO *k, VARENT *ve)
605 {
606 	VAR *v;
607 
608 	v = ve->var;
609 	(void)printf("%*d", v->width, pgtok(KI_EPROC(k)->e_vm.vm_ssize));
610 }
611 
612 /*
613  * Generic output routines.  Print fields from various prototype
614  * structures.
615  */
616 static void
617 printval(char *bp, VAR *v)
618 {
619 	static char ofmt[32] = "%";
620 	char *fcp, *cp;
621 	enum type type;
622 
623 	cp = ofmt + 1;
624 	fcp = v->fmt;
625 	if (v->flag & LJUST)
626 		*cp++ = '-';
627 	*cp++ = '*';
628 	while ((*cp++ = *fcp++));
629 
630 	/*
631 	 * Note that the "INF127" check is nonsensical for types
632 	 * that are or can be signed.
633 	 */
634 #define	GET(type)		(*(type *)bp)
635 #define	CHK_INF127(n)		(((n) > 127) && (v->flag & INF127) ? 127 : (n))
636 
637 	switch (v->type) {
638 	case INT32:
639 		if (sizeof(int32_t) == sizeof(int))
640 			type = INT;
641 		else if (sizeof(int32_t) == sizeof(long))
642 			type = LONG;
643 		else
644 			errx(1, "unknown conversion for type %d", v->type);
645 		break;
646 	case UINT32:
647 		if (sizeof(u_int32_t) == sizeof(u_int))
648 			type = UINT;
649 		else if (sizeof(u_int32_t) == sizeof(u_long))
650 			type = ULONG;
651 		else
652 			errx(1, "unknown conversion for type %d", v->type);
653 		break;
654 	default:
655 		type = v->type;
656 		break;
657 	}
658 
659 	switch (type) {
660 	case CHAR:
661 		(void)printf(ofmt, v->width, GET(char));
662 		break;
663 	case UCHAR:
664 		(void)printf(ofmt, v->width, CHK_INF127(GET(u_char)));
665 		break;
666 	case SHORT:
667 		(void)printf(ofmt, v->width, GET(short));
668 		break;
669 	case USHORT:
670 		(void)printf(ofmt, v->width, CHK_INF127(GET(u_short)));
671 		break;
672 	case INT:
673 		(void)printf(ofmt, v->width, GET(int));
674 		break;
675 	case UINT:
676 		(void)printf(ofmt, v->width, CHK_INF127(GET(u_int)));
677 		break;
678 	case LONG:
679 		(void)printf(ofmt, v->width, GET(long));
680 		break;
681 	case ULONG:
682 		(void)printf(ofmt, v->width, CHK_INF127(GET(u_long)));
683 		break;
684 	case KPTR:
685 		(void)printf(ofmt, v->width, GET(u_long) &~ KERNBASE);
686 		break;
687 	default:
688 		errx(1, "unknown type %d", v->type);
689 	}
690 #undef GET
691 #undef CHK_INF127
692 }
693 
694 void
695 pvar(KINFO *k, VARENT *ve)
696 {
697 	VAR *v;
698 
699 	v = ve->var;
700 	printval((char *)((char *)KI_PROC(k) + v->off), v);
701 }
702 
703 void
704 evar(KINFO *k, VARENT *ve)
705 {
706 	VAR *v;
707 
708 	v = ve->var;
709 	printval((char *)((char *)KI_EPROC(k) + v->off), v);
710 }
711 
712 void
713 uvar(KINFO *k, VARENT *ve)
714 {
715 	VAR *v;
716 
717 	v = ve->var;
718 	if (k->ki_u.u_valid)
719 		printval((char *)((char *)&k->ki_u + v->off), v);
720 	else
721 		(void)printf("%*s", v->width, "-");
722 }
723 
724 void
725 rvar(KINFO *k, VARENT *ve)
726 {
727 	VAR *v;
728 
729 	v = ve->var;
730 	if (k->ki_u.u_valid)
731 		printval((char *)((char *)(&k->ki_u.u_ru) + v->off), v);
732 	else
733 		(void)printf("%*s", v->width, "-");
734 }
735 
736 void
737 emulname(KINFO *k, VARENT *ve)
738 {
739 	VAR *v;
740 
741 	v = ve->var;
742 
743 	(void)printf("%-*s",
744 	    (int)v->width, KI_EPROC(k)->e_emul);
745 }
746