xref: /freebsd/bin/ps/print.c (revision b52b9d56d4e96089873a75f9e29062eec19fabba)
1 /*-
2  * Copyright (c) 1990, 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #if 0
35 #ifndef lint
36 static char sccsid[] = "@(#)print.c	8.6 (Berkeley) 4/16/94";
37 #endif /* not lint */
38 #endif
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD$");
41 
42 #include <sys/param.h>
43 #include <sys/time.h>
44 #include <sys/resource.h>
45 #include <sys/proc.h>
46 #include <sys/stat.h>
47 
48 #include <sys/user.h>
49 #include <sys/sysctl.h>
50 
51 #include <err.h>
52 #include <grp.h>
53 #include <langinfo.h>
54 #include <locale.h>
55 #include <math.h>
56 #include <nlist.h>
57 #include <pwd.h>
58 #include <stddef.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <unistd.h>
63 #include <vis.h>
64 
65 #include "lomac.h"
66 #include "ps.h"
67 
68 static void printval(void *, VAR *);
69 
70 void
71 printheader(void)
72 {
73 	VAR *v;
74 	struct varent *vent;
75 
76 	for (vent = vhead; vent; vent = vent->next) {
77 		v = vent->var;
78 		if (v->flag & LJUST) {
79 			if (vent->next == NULL)	/* last one */
80 				(void)printf("%s", v->header);
81 			else
82 				(void)printf("%-*s", v->width, v->header);
83 		} else
84 			(void)printf("%*s", v->width, v->header);
85 		if (vent->next != NULL)
86 			(void)putchar(' ');
87 	}
88 	(void)putchar('\n');
89 }
90 
91 void
92 arguments(KINFO *k, VARENT *ve)
93 {
94 	VAR *v;
95 	int left;
96 	char *cp, *vis_args;
97 
98 	v = ve->var;
99 
100 	if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL)
101 		errx(1, "malloc failed");
102 	strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH);
103 
104 	if (ve->next == NULL) {
105 		/* last field */
106 		if (termwidth == UNLIMITED) {
107 			(void)printf("%s", vis_args);
108 		} else {
109 			left = termwidth - (totwidth - v->width);
110 			if (left < 1) /* already wrapped, just use std width */
111 				left = v->width;
112 			for (cp = vis_args; --left >= 0 && *cp != '\0';)
113 				(void)putchar(*cp++);
114 		}
115 	} else {
116 		(void)printf("%-*.*s", v->width, v->width, vis_args);
117 	}
118 	free(vis_args);
119 }
120 
121 void
122 command(KINFO *k, VARENT *ve)
123 {
124 	VAR *v;
125 	int left;
126 	char *cp, *vis_env, *vis_args;
127 
128 	v = ve->var;
129 
130 	if (cflag) {
131 		if (ve->next == NULL)	/* last field, don't pad */
132 			(void)printf("%s", k->ki_p->ki_comm);
133 		else
134 			(void)printf("%-*s", v->width, k->ki_p->ki_comm);
135 		return;
136 	}
137 
138 	if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL)
139 		errx(1, "malloc failed");
140 	strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH);
141 	if (k->ki_env) {
142 		if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) == NULL)
143 			errx(1, "malloc failed");
144 		strvis(vis_env, k->ki_env, VIS_TAB | VIS_NL | VIS_NOSLASH);
145 	} else
146 		vis_env = NULL;
147 
148 	if (ve->next == NULL) {
149 		/* last field */
150 		if (termwidth == UNLIMITED) {
151 			if (vis_env)
152 				(void)printf("%s ", vis_env);
153 			(void)printf("%s", vis_args);
154 		} else {
155 			left = termwidth - (totwidth - v->width);
156 			if (left < 1) /* already wrapped, just use std width */
157 				left = v->width;
158 			if ((cp = vis_env) != NULL) {
159 				while (--left >= 0 && *cp)
160 					(void)putchar(*cp++);
161 				if (--left >= 0)
162 					putchar(' ');
163 			}
164 			for (cp = vis_args; --left >= 0 && *cp != '\0';)
165 				(void)putchar(*cp++);
166 		}
167 	} else
168 		/* XXX env? */
169 		(void)printf("%-*.*s", v->width, v->width, vis_args);
170 	free(vis_args);
171 	if (vis_env != NULL)
172 		free(vis_env);
173 }
174 
175 void
176 ucomm(KINFO *k, VARENT *ve)
177 {
178 	VAR *v;
179 
180 	v = ve->var;
181 	(void)printf("%-*s", v->width, k->ki_p->ki_comm);
182 }
183 
184 void
185 logname(KINFO *k, VARENT *ve)
186 {
187 	VAR *v;
188 	char *s;
189 
190 	v = ve->var;
191 	(void)printf("%-*s", v->width, (s = k->ki_p->ki_login, *s) ? s : "-");
192 }
193 
194 void
195 state(KINFO *k, VARENT *ve)
196 {
197 	int flag, sflag, tdflags;
198 	char *cp;
199 	VAR *v;
200 	char buf[16];
201 
202 	v = ve->var;
203 	flag = k->ki_p->ki_flag;
204 	sflag = k->ki_p->ki_sflag;
205 	tdflags = k->ki_p->ki_tdflags;	/* XXXKSE */
206 	cp = buf;
207 
208 	switch (k->ki_p->ki_stat) {
209 
210 	case SSTOP:
211 		*cp = 'T';
212 		break;
213 
214 	case SSLEEP:
215 		if (tdflags & TDF_SINTR)	/* interruptable (long) */
216 			*cp = k->ki_p->ki_slptime >= MAXSLP ? 'I' : 'S';
217 		else
218 			*cp = 'D';
219 		break;
220 
221 	case SRUN:
222 	case SIDL:
223 		*cp = 'R';
224 		break;
225 
226 	case SWAIT:
227 		*cp = 'W';
228 		break;
229 
230 	case SMTX:
231 		*cp = 'M';
232 		break;
233 
234 	case SZOMB:
235 		*cp = 'Z';
236 		break;
237 
238 	default:
239 		*cp = '?';
240 	}
241 	cp++;
242 	if (!(sflag & PS_INMEM))
243 		*cp++ = 'W';
244 	if (k->ki_p->ki_nice < NZERO)
245 		*cp++ = '<';
246 	else if (k->ki_p->ki_nice > NZERO)
247 		*cp++ = 'N';
248 	if (flag & P_TRACED)
249 		*cp++ = 'X';
250 	if (flag & P_WEXIT && k->ki_p->ki_stat != SZOMB)
251 		*cp++ = 'E';
252 	if (flag & P_PPWAIT)
253 		*cp++ = 'V';
254 	if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0)
255 		*cp++ = 'L';
256 	if (k->ki_p->ki_kiflag & KI_SLEADER)
257 		*cp++ = 's';
258 	if ((flag & P_CONTROLT) && k->ki_p->ki_pgid == k->ki_p->ki_tpgid)
259 		*cp++ = '+';
260 	if (flag & P_JAILED)
261 		*cp++ = 'J';
262 	*cp = '\0';
263 	(void)printf("%-*s", v->width, buf);
264 }
265 
266 void
267 pri(KINFO *k, VARENT *ve)
268 {
269 	VAR *v;
270 
271 	v = ve->var;
272 	(void)printf("%*d", v->width, k->ki_p->ki_pri.pri_level - PZERO);
273 }
274 
275 void
276 uname(KINFO *k, VARENT *ve)
277 {
278 	VAR *v;
279 
280 	v = ve->var;
281 	(void)printf("%-*s", v->width, user_from_uid(k->ki_p->ki_uid, 0));
282 }
283 
284 int
285 s_uname(KINFO *k)
286 {
287 	    return (strlen(user_from_uid(k->ki_p->ki_uid, 0)));
288 }
289 
290 void
291 rgroupname(KINFO *k, VARENT *ve)
292 {
293 	VAR *v;
294 
295 	v = ve->var;
296 	(void)printf("%-*s", v->width, group_from_gid(k->ki_p->ki_rgid, 0));
297 }
298 
299 int
300 s_rgroupname(KINFO *k)
301 {
302 	return (strlen(group_from_gid(k->ki_p->ki_rgid, 0)));
303 }
304 
305 void
306 runame(KINFO *k, VARENT *ve)
307 {
308 	VAR *v;
309 
310 	v = ve->var;
311 	(void)printf("%-*s", v->width, user_from_uid(k->ki_p->ki_ruid, 0));
312 }
313 
314 int
315 s_runame(KINFO *k)
316 {
317 	    return (strlen(user_from_uid(k->ki_p->ki_ruid, 0)));
318 }
319 
320 void
321 tdev(KINFO *k, VARENT *ve)
322 {
323 	VAR *v;
324 	dev_t dev;
325 	char buff[16];
326 
327 	v = ve->var;
328 	dev = k->ki_p->ki_tdev;
329 	if (dev == NODEV)
330 		(void)printf("%*s", v->width, "??");
331 	else {
332 		(void)snprintf(buff, sizeof(buff),
333 		    "%d/%d", major(dev), minor(dev));
334 		(void)printf("%*s", v->width, buff);
335 	}
336 }
337 
338 void
339 tname(KINFO *k, VARENT *ve)
340 {
341 	VAR *v;
342 	dev_t dev;
343 	char *ttname;
344 
345 	v = ve->var;
346 	dev = k->ki_p->ki_tdev;
347 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
348 		(void)printf("%*s ", v->width-1, "??");
349 	else {
350 		if (strncmp(ttname, "tty", 3) == 0 ||
351 		    strncmp(ttname, "cua", 3) == 0)
352 			ttname += 3;
353 		(void)printf("%*.*s%c", v->width-1, v->width-1, ttname,
354 			k->ki_p->ki_kiflag & KI_CTTY ? ' ' : '-');
355 	}
356 }
357 
358 void
359 longtname(KINFO *k, VARENT *ve)
360 {
361 	VAR *v;
362 	dev_t dev;
363 	char *ttname;
364 
365 	v = ve->var;
366 	dev = k->ki_p->ki_tdev;
367 	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
368 		(void)printf("%-*s", v->width, "??");
369 	else
370 		(void)printf("%-*s", v->width, ttname);
371 }
372 
373 void
374 started(KINFO *k, VARENT *ve)
375 {
376 	VAR *v;
377 	time_t then;
378 	struct tm *tp;
379 	char buf[100];
380 	static int  use_ampm = -1;
381 
382 	v = ve->var;
383 	if (!k->ki_valid) {
384 		(void)printf("%-*s", v->width, "-");
385 		return;
386 	}
387 
388 	if (use_ampm < 0)
389 		use_ampm = (*nl_langinfo(T_FMT_AMPM) != '\0');
390 
391 	then = k->ki_p->ki_start.tv_sec;
392 	tp = localtime(&then);
393 	if (now - k->ki_p->ki_start.tv_sec < 24 * 3600) {
394 		(void)strftime(buf, sizeof(buf) - 1,
395 		use_ampm ? "%l:%M%p" : "%k:%M  ", tp);
396 	} else if (now - k->ki_p->ki_start.tv_sec < 7 * 86400) {
397 		(void)strftime(buf, sizeof(buf) - 1,
398 		use_ampm ? "%a%I%p" : "%a%H  ", tp);
399 	} else
400 		(void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
401 	(void)printf("%-*s", v->width, buf);
402 }
403 
404 void
405 lstarted(KINFO *k, VARENT *ve)
406 {
407 	VAR *v;
408 	time_t then;
409 	char buf[100];
410 
411 	v = ve->var;
412 	if (!k->ki_valid) {
413 		(void)printf("%-*s", v->width, "-");
414 		return;
415 	}
416 	then = k->ki_p->ki_start.tv_sec;
417 	(void)strftime(buf, sizeof(buf) -1, "%c", localtime(&then));
418 	(void)printf("%-*s", v->width, buf);
419 }
420 
421 void
422 mtxname(KINFO *k, VARENT *ve)
423 {
424 	VAR *v;
425 
426 	v = ve->var;
427 	if (k->ki_p->ki_kiflag & KI_MTXBLOCK) {
428 		if (k->ki_p->ki_mtxname[0] != 0)
429 			(void)printf("%-*.*s", v->width, v->width,
430 				      k->ki_p->ki_mtxname);
431 		else
432 			(void)printf("%-*s", v->width, "???");
433 	} else
434 		(void)printf("%-*s", v->width, "-");
435 }
436 
437 void
438 wchan(KINFO *k, VARENT *ve)
439 {
440 	VAR *v;
441 
442 	v = ve->var;
443 	if (k->ki_p->ki_wchan) {
444 		if (k->ki_p->ki_wmesg[0] != 0)
445 			(void)printf("%-*.*s", v->width, v->width,
446 				      k->ki_p->ki_wmesg);
447 		else
448 			(void)printf("%-*lx", v->width,
449 			    (long)k->ki_p->ki_wchan);
450 	} else {
451 		(void)printf("%-*s", v->width, "-");
452 	}
453 }
454 
455 void
456 mwchan(KINFO *k, VARENT *ve)
457 {
458 	VAR *v;
459 
460 	v = ve->var;
461 	if (k->ki_p->ki_wchan) {
462 		if (k->ki_p->ki_wmesg[0] != 0)
463 			(void)printf("%-*.*s", v->width, v->width,
464 				      k->ki_p->ki_wmesg);
465 		else
466 			(void)printf("%-*lx", v->width,
467 			    (long)k->ki_p->ki_wchan);
468 	} else if (k->ki_p->ki_kiflag & KI_MTXBLOCK) {
469 		if (k->ki_p->ki_mtxname[0]) {
470 			(void)printf("%-*.*s", v->width, v->width,
471 			    k->ki_p->ki_mtxname);
472 		} else {
473 			(void)printf("%-*s", v->width, "???");
474 		}
475 	} else {
476 		(void)printf("%-*s", v->width, "-");
477 	}
478 }
479 
480 #ifndef pgtok
481 #define pgtok(a)        (((a)*getpagesize())/1024)
482 #endif
483 
484 void
485 vsize(KINFO *k, VARENT *ve)
486 {
487 	VAR *v;
488 
489 	v = ve->var;
490 	(void)printf("%*lu", v->width, (u_long)(k->ki_p->ki_size / 1024));
491 }
492 
493 void
494 cputime(KINFO *k, VARENT *ve)
495 {
496 	VAR *v;
497 	long secs;
498 	long psecs;	/* "parts" of a second. first micro, then centi */
499 	char obuff[128];
500 	static char decimal_point = 0;
501 
502 	if (!decimal_point)
503 		decimal_point = localeconv()->decimal_point[0];
504 	v = ve->var;
505 	if (k->ki_p->ki_stat == SZOMB || !k->ki_valid) {
506 		secs = 0;
507 		psecs = 0;
508 	} else {
509 		/*
510 		 * This counts time spent handling interrupts.  We could
511 		 * fix this, but it is not 100% trivial (and interrupt
512 		 * time fractions only work on the sparc anyway).	XXX
513 		 */
514 		secs = k->ki_p->ki_runtime / 1000000;
515 		psecs = k->ki_p->ki_runtime % 1000000;
516 		if (sumrusage) {
517 			secs += k->ki_p->ki_childtime.tv_sec;
518 			psecs += k->ki_p->ki_childtime.tv_usec;
519 		}
520 		/*
521 		 * round and scale to 100's
522 		 */
523 		psecs = (psecs + 5000) / 10000;
524 		secs += psecs / 100;
525 		psecs = psecs % 100;
526 	}
527 	(void)snprintf(obuff, sizeof(obuff),
528 	    "%3ld:%02ld%c%02ld", secs/60, secs%60, decimal_point, psecs);
529 	(void)printf("%*s", v->width, obuff);
530 }
531 
532 void
533 elapsed(KINFO *k, VARENT *ve)
534 {
535 	VAR *v;
536 	time_t secs;
537 	char obuff[128];
538 
539 	v = ve->var;
540 
541 	secs = now - k->ki_p->ki_start.tv_sec;
542 	(void)snprintf(obuff, sizeof(obuff), "%3ld:%02ld", (long)secs/60,
543 	    (long)secs%60);
544 	(void)printf("%*s", v->width, obuff);
545 }
546 
547 double
548 getpcpu(const KINFO *k)
549 {
550 	static int failure;
551 
552 	if (!nlistread)
553 		failure = donlist();
554 	if (failure)
555 		return (0.0);
556 
557 #define	fxtofl(fixpt)	((double)(fixpt) / fscale)
558 
559 	/* XXX - I don't like this */
560 	if (k->ki_p->ki_swtime == 0 || (k->ki_p->ki_sflag & PS_INMEM) == 0)
561 		return (0.0);
562 	if (rawcpu)
563 		return (100.0 * fxtofl(k->ki_p->ki_pctcpu));
564 	return (100.0 * fxtofl(k->ki_p->ki_pctcpu) /
565 		(1.0 - exp(k->ki_p->ki_swtime * log(fxtofl(ccpu)))));
566 }
567 
568 void
569 pcpu(KINFO *k, VARENT *ve)
570 {
571 	VAR *v;
572 
573 	v = ve->var;
574 	(void)printf("%*.1f", v->width, getpcpu(k));
575 }
576 
577 static double
578 getpmem(KINFO *k)
579 {
580 	static int failure;
581 	double fracmem;
582 
583 	if (!nlistread)
584 		failure = donlist();
585 	if (failure)
586 		return (0.0);
587 
588 	if ((k->ki_p->ki_sflag & PS_INMEM) == 0)
589 		return (0.0);
590 	/* XXX want pmap ptpages, segtab, etc. (per architecture) */
591 	/* XXX don't have info about shared */
592 	fracmem = ((float)k->ki_p->ki_rssize)/mempages;
593 	return (100.0 * fracmem);
594 }
595 
596 void
597 pmem(KINFO *k, VARENT *ve)
598 {
599 	VAR *v;
600 
601 	v = ve->var;
602 	(void)printf("%*.1f", v->width, getpmem(k));
603 }
604 
605 void
606 pagein(KINFO *k, VARENT *ve)
607 {
608 	VAR *v;
609 
610 	v = ve->var;
611 	(void)printf("%*ld", v->width,
612 	    k->ki_valid ? k->ki_p->ki_rusage.ru_majflt : 0);
613 }
614 
615 /* ARGSUSED */
616 void
617 maxrss(KINFO *k __unused, VARENT *ve)
618 {
619 	VAR *v;
620 
621 	v = ve->var;
622 	/* XXX not yet */
623 	(void)printf("%*s", v->width, "-");
624 }
625 
626 void
627 tsize(KINFO *k, VARENT *ve)
628 {
629 	VAR *v;
630 
631 	v = ve->var;
632 	(void)printf("%*ld", v->width, (long)pgtok(k->ki_p->ki_tsize));
633 }
634 
635 void
636 priorityr(KINFO *k, VARENT *ve)
637 {
638 	VAR *v;
639 	struct priority *lpri;
640 	char str[8];
641 	unsigned class, level;
642 
643 	v = ve->var;
644 	lpri = (struct priority *) ((char *)k + v->off);
645 	class = lpri->pri_class;
646 	level = lpri->pri_level;
647 	switch (class) {
648 	case PRI_REALTIME:
649 		snprintf(str, sizeof(str), "real:%u", level);
650 		break;
651 	case PRI_TIMESHARE:
652 		strncpy(str, "normal", sizeof(str));
653 		break;
654 	case PRI_IDLE:
655 		snprintf(str, sizeof(str), "idle:%u", level);
656 		break;
657 	default:
658 		snprintf(str, sizeof(str), "%u:%u", class, level);
659 		break;
660 	}
661 	str[sizeof(str) - 1] = '\0';
662 	(void)printf("%*s", v->width, str);
663 }
664 
665 /*
666  * Generic output routines.  Print fields from various prototype
667  * structures.
668  */
669 static void
670 printval(void *bp, VAR *v)
671 {
672 	static char ofmt[32] = "%";
673 	const char *fcp;
674 	char *cp;
675 
676 	cp = ofmt + 1;
677 	fcp = v->fmt;
678 	if (v->flag & LJUST)
679 		*cp++ = '-';
680 	*cp++ = '*';
681 	while ((*cp++ = *fcp++));
682 
683 	switch (v->type) {
684 	case CHAR:
685 		(void)printf(ofmt, v->width, *(char *)bp);
686 		break;
687 	case UCHAR:
688 		(void)printf(ofmt, v->width, *(u_char *)bp);
689 		break;
690 	case SHORT:
691 		(void)printf(ofmt, v->width, *(short *)bp);
692 		break;
693 	case USHORT:
694 		(void)printf(ofmt, v->width, *(u_short *)bp);
695 		break;
696 	case INT:
697 		(void)printf(ofmt, v->width, *(int *)bp);
698 		break;
699 	case UINT:
700 		(void)printf(ofmt, v->width, *(u_int *)bp);
701 		break;
702 	case LONG:
703 		(void)printf(ofmt, v->width, *(long *)bp);
704 		break;
705 	case ULONG:
706 		(void)printf(ofmt, v->width, *(u_long *)bp);
707 		break;
708 	case KPTR:
709 		(void)printf(ofmt, v->width, *(u_long *)bp);
710 		break;
711 	default:
712 		errx(1, "unknown type %d", v->type);
713 	}
714 }
715 
716 void
717 kvar(KINFO *k, VARENT *ve)
718 {
719 	VAR *v;
720 
721 	v = ve->var;
722 	printval((char *)((char *)k->ki_p + v->off), v);
723 }
724 
725 void
726 rvar(KINFO *k, VARENT *ve)
727 {
728 	VAR *v;
729 
730 	v = ve->var;
731 	if (k->ki_valid)
732 		printval((char *)((char *)(&k->ki_p->ki_rusage) + v->off), v);
733 	else
734 		(void)printf("%*s", v->width, "-");
735 }
736 
737 void
738 lattr(KINFO *k, VARENT *ve)
739 {
740 	VAR *v;
741 
742 	v = ve->var;
743 	(void)printf("%-*d", v->width, get_lattr(k->ki_p->ki_pid));
744 }
745