1 /* $NetBSD: pstat.c,v 1.115 2009/09/16 07:27:41 mlelstv Exp $ */
4 * Copyright (c) 1980, 1991, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
34 __COPYRIGHT("@(#) Copyright (c) 1980, 1991, 1993, 1994\
35 The Regents of the University of California. All rights reserved.");
40 static char sccsid
[] = "@(#)pstat.c 8.16 (Berkeley) 5/9/95";
42 __RCSID("$NetBSD: pstat.c,v 1.115 2009/09/16 07:27:41 mlelstv Exp $");
47 #include <sys/types.h>
49 #include <sys/param.h>
51 #include <sys/vnode.h>
52 #include <sys/ucred.h>
56 #include <sys/mount.h>
59 #include <ufs/ufs/inode.h>
60 #include <ufs/ufs/ufsmount.h>
62 #include <miscfs/genfs/layer.h>
65 #include <nfs/nfsproto.h>
66 #include <nfs/rpcv2.h>
68 #include <nfs/nfsnode.h>
69 #include <sys/ioctl.h>
73 #include <sys/sysctl.h>
88 { "_mountlist", 0, 0, 0, 0 }, /* address of head of mount list. */
90 { "_numvnodes", 0, 0, 0, 0 },
92 { "_nfiles", 0, 0, 0, 0 },
94 { "_maxfiles", 0, 0, 0, 0 },
96 { "_tty_count", 0, 0, 0, 0 },
98 { "_ttylist", 0, 0, 0, 0 },
99 #define NLMANDATORY TTY_TTYLIST /* names up to here are mandatory */
111 static const char * const dtypes
[] = { DTYPE_NAMES
};
114 static const struct {
122 struct flagbit_desc
{
127 #define SVAR(var) __STRING(var) /* to force expansion */
128 #define KGET(idx, var) \
129 KGET1(idx, &var, sizeof(var), SVAR(var))
130 #define KGET1(idx, p, s, msg) \
131 KGET2(nl[idx].n_value, p, s, msg)
132 #define KGET2(addr, p, s, msg) do { \
133 if (kvm_read(kd, (u_long)(addr), p, s) != s) \
134 warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \
135 } while (/* CONSTCOND */0)
136 #define KGETRET(addr, p, s, msg) do { \
137 if (kvm_read(kd, (u_long)(addr), p, s) != s) { \
138 warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \
141 } while (/* CONSTCOND */0)
143 #if 1 /* This is copied from vmstat/vmstat.c */
145 * Print single word. `ovflow' is number of characters didn't fit
146 * on the last word. `fmt' is a format string to print this word.
147 * It must contain asterisk for field width. `width' is a width
148 * occupied by this word. `fixed' is a number of constant chars in
149 * `fmt'. `val' is a value to be printed using format string `fmt'.
151 #define PRWORD(ovflw, fmt, width, fixed, val) do { \
152 (ovflw) += printf((fmt), \
153 (width) - (fixed) - (ovflw) > 0 ? \
154 (width) - (fixed) - (ovflw) : 0, \
158 } while (/* CONSTCOND */0)
162 int getfiles(char **, int *, char **);
163 int getflags(const struct flagbit_desc
*, char *, u_int
);
165 getmnt(struct mount
*);
166 char * kinfo_vnodes(int *);
167 void layer_header(void);
168 int layer_print(struct vnode
*, int);
169 char * loadvnodes(int *);
170 int main(int, char **);
171 void mount_print(struct mount
*);
172 void nfs_header(void);
173 int nfs_print(struct vnode
*, int);
175 void ttyprt(struct tty
*);
176 void ufs_header(void);
177 int ufs_print(struct vnode
*, int);
178 int ext2fs_print(struct vnode
*, int);
180 void vnode_header(void);
181 int vnode_print(struct vnode
*, struct vnode
*);
182 void vnodemode(void);
185 main(int argc
, char *argv
[])
187 int ch
, i
, quit
, ret
, use_sysctl
;
188 int fileflag
, swapflag
, ttyflag
, vnodeflag
;
189 gid_t egid
= getegid();
190 char buf
[_POSIX2_LINE_MAX
];
193 fileflag
= swapflag
= ttyflag
= vnodeflag
= 0;
194 while ((ch
= getopt(argc
, argv
, "TM:N:fghikmnstv")) != -1)
221 kflag
= 3; /* 1k ^ 3 */
227 kflag
= 2; /* 1k ^ 2 */
230 case 'i': /* Backward compatibility. */
240 * Discard setgid privileges. If not the running kernel, we toss
241 * them away totally so that bad guys can't print interesting stuff
242 * from kernel memory, otherwise switch back to kmem for the
243 * duration of the kvm_openfiles() call.
245 if (nlistf
!= NULL
|| memf
!= NULL
)
246 (void)setgid(getgid());
250 use_sysctl
= (nlistf
== NULL
&& memf
== NULL
);
252 if ((kd
= kvm_openfiles(nlistf
, memf
, NULL
, O_RDONLY
, buf
)) == 0)
253 errx(1, "kvm_openfiles: %s", buf
);
255 /* get rid of it now anyway */
256 if (nlistf
== NULL
&& memf
== NULL
)
257 (void)setgid(getgid());
258 if ((ret
= kvm_nlist(kd
, nl
)) != 0) {
260 errx(1, "kvm_nlist: %s", kvm_geterr(kd
));
261 for (i
= quit
= 0; i
<= NLMANDATORY
; i
++)
262 if (!nl
[i
].n_value
) {
264 warnx("undefined symbol: %s", nl
[i
].n_name
);
269 if (!(fileflag
| vnodeflag
| ttyflag
| swapflag
| totalflag
))
271 if (fileflag
|| totalflag
)
273 if (vnodeflag
|| totalflag
)
277 if (swapflag
|| totalflag
)
279 list_swap(0, kflag
, 0, totalflag
, 1, hflag
);
283 #define VPTRSZ sizeof(struct vnode *)
284 #define VNODESZ sizeof(struct vnode)
285 #define PTRSTRWIDTH ((int)sizeof(void *) * 2) /* Width of resulting string
286 when pointer is printed
290 devprintf(char *buf
, size_t buflen
, dev_t dev
)
292 (void)snprintf(buf
, buflen
, "%llu,%llu",
293 (unsigned long long)major(dev
),
294 (unsigned long long)minor(dev
));
300 char *e_vnodebase
, *endvnode
, *evp
;
302 struct mount
*maddr
, *mp
;
303 int numvnodes
, ovflw
;
304 int (*vnode_fsprint
) (struct vnode
*, int); /* per-fs data printer */
307 e_vnodebase
= loadvnodes(&numvnodes
);
309 (void)printf("%7d vnodes\n", numvnodes
);
312 endvnode
= e_vnodebase
+ numvnodes
* (VPTRSZ
+ VNODESZ
);
313 (void)printf("%d active vnodes\n", numvnodes
);
315 #define ST mp->mnt_stat
316 #define FSTYPE_IS(mp, name) \
317 (strncmp((mp)->mnt_stat.f_fstypename, (name), \
318 sizeof((mp)->mnt_stat.f_fstypename)) == 0)
320 vnode_fsprint
= NULL
;
321 for (evp
= e_vnodebase
; evp
< endvnode
; evp
+= VPTRSZ
+ VNODESZ
) {
322 vp
= (struct vnode
*)(evp
+ VPTRSZ
);
323 if (vp
->v_mount
!= maddr
) {
327 if ((mp
= getmnt(vp
->v_mount
)) == NULL
)
332 if (FSTYPE_IS(mp
, MOUNT_FFS
) ||
333 FSTYPE_IS(mp
, MOUNT_MFS
)) {
335 vnode_fsprint
= ufs_print
;
336 } else if (FSTYPE_IS(mp
, MOUNT_NFS
)) {
338 vnode_fsprint
= nfs_print
;
339 } else if (FSTYPE_IS(mp
, MOUNT_EXT2FS
)) {
341 vnode_fsprint
= ext2fs_print
;
342 } else if (FSTYPE_IS(mp
, MOUNT_NULL
) ||
343 FSTYPE_IS(mp
, MOUNT_OVERLAY
) ||
344 FSTYPE_IS(mp
, MOUNT_UMAP
)) {
346 vnode_fsprint
= layer_print
;
348 vnode_fsprint
= NULL
;
351 ovflw
= vnode_print(*(struct vnode
**)evp
, vp
);
352 if (VTOI(vp
) != NULL
&& vnode_fsprint
!= NULL
)
353 (*vnode_fsprint
)(vp
, ovflw
);
363 getflags(const struct flagbit_desc
*fd
, char *p
, u_int flags
)
373 for (; fd
->fd_flags
!= 0; fd
++)
374 if ((flags
& fd
->fd_flags
) != 0)
380 const struct flagbit_desc vnode_flags
[] = {
389 { VI_ONWORKLST
, 'O' },
397 (void)printf("%-*s TYP VFLAG USE HOLD TAG NPAGE",
398 PTRSTRWIDTH
, "ADDR");
402 vnode_print(struct vnode
*avnode
, struct vnode
*vp
)
405 char flags
[sizeof(vnode_flags
) / sizeof(vnode_flags
[0])];
411 switch (vp
->v_type
) {
436 (void)getflags(vnode_flags
, flags
,
437 vp
->v_uflag
| vp
->v_iflag
| vp
->v_vflag
);
440 PRWORD(ovflw
, "%*lx", PTRSTRWIDTH
, 0, (long)avnode
);
441 PRWORD(ovflw
, " %*s", 4, 1, type
);
442 PRWORD(ovflw
, " %*s", 6, 1, flags
);
443 PRWORD(ovflw
, " %*ld", 5, 1, (long)vp
->v_usecount
);
444 PRWORD(ovflw
, " %*ld", 5, 1, (long)vp
->v_holdcnt
);
445 PRWORD(ovflw
, " %*d", 4, 1, vp
->v_tag
);
446 PRWORD(ovflw
, " %*d", 6, 1, vp
->v_uobj
.uo_npages
);
450 const struct flagbit_desc ufs_flags
[] = {
454 { IN_MODIFIED
, 'M' },
455 { IN_ACCESSED
, 'a' },
459 { IN_CLEANING
, 'c' },
461 { IN_SPACECOUNTED
, 's' },
469 (void)printf(" FILEID IFLAG RDEV|SZ");
473 ufs_print(struct vnode
*vp
, int ovflw
)
475 struct inode inode
, *ip
= &inode
;
477 struct ufs1_dinode dp1
;
478 struct ufs2_dinode dp2
;
481 char flags
[sizeof(ufs_flags
) / sizeof(ufs_flags
[0])];
482 char dev
[4 + 1 + 7 + 1]; /* 12bit marjor + 20bit minor */
487 KGETRET(VTOI(vp
), &inode
, sizeof(struct inode
), "vnode's inode");
488 KGETRET(ip
->i_ump
, &ump
, sizeof(struct ufsmount
),
489 "vnode's mount point");
491 if (ump
.um_fstype
== UFS1
) {
492 KGETRET(ip
->i_din
.ffs1_din
, &dip
, sizeof (struct ufs1_dinode
),
494 rdev
= (uint32_t)dip
.dp1
.di_rdev
;
496 KGETRET(ip
->i_din
.ffs2_din
, &dip
, sizeof (struct ufs2_dinode
),
497 "inode's UFS2 dinode");
498 rdev
= dip
.dp2
.di_rdev
;
502 * XXX need to to locking state.
505 (void)getflags(ufs_flags
, flags
, ip
->i_flag
);
506 PRWORD(ovflw
, " %*llu", 7, 1, (unsigned long long)ip
->i_number
);
507 PRWORD(ovflw
, " %*s", 6, 1, flags
);
508 type
= ip
->i_mode
& S_IFMT
;
509 if (S_ISCHR(ip
->i_mode
) || S_ISBLK(ip
->i_mode
)) {
511 (name
= devname(rdev
, type
)) == NULL
) {
512 devprintf(dev
, sizeof(dev
), rdev
);
515 PRWORD(ovflw
, " %*s", 8, 1, name
);
517 PRWORD(ovflw
, " %*lld", 8, 1, (long long)ip
->i_size
);
522 ext2fs_print(struct vnode
*vp
, int ovflw
)
524 struct inode inode
, *ip
= &inode
;
525 struct ext2fs_dinode dip
;
526 char flags
[sizeof(ufs_flags
) / sizeof(ufs_flags
[0])];
527 char dev
[4 + 1 + 7 + 1]; /* 12bit marjor + 20bit minor */
531 KGETRET(VTOI(vp
), &inode
, sizeof(struct inode
), "vnode's inode");
532 KGETRET(ip
->i_din
.e2fs_din
, &dip
, sizeof (struct ext2fs_dinode
),
536 * XXX need to to locking state.
539 (void)getflags(ufs_flags
, flags
, ip
->i_flag
);
540 PRWORD(ovflw
, " %*llu", 7, 1, (unsigned long long)ip
->i_number
);
541 PRWORD(ovflw
, " %*s", 6, 1, flags
);
542 type
= dip
.e2di_mode
& S_IFMT
;
543 if (S_ISCHR(dip
.e2di_mode
) || S_ISBLK(dip
.e2di_mode
)) {
545 (name
= devname(dip
.e2di_rdev
, type
)) == NULL
) {
546 devprintf(dev
, sizeof(dev
), dip
.e2di_rdev
);
549 PRWORD(ovflw
, " %*s", 8, 1, name
);
551 PRWORD(ovflw
, " %*u", 8, 1, (u_int
)dip
.e2di_size
);
555 const struct flagbit_desc nfs_flags
[] = {
557 { NFLUSHINPROG
, 'P' },
570 (void)printf(" FILEID NFLAG RDEV|SZ");
574 nfs_print(struct vnode
*vp
, int ovflw
)
576 struct nfsnode nfsnode
, *np
= &nfsnode
;
577 char flags
[sizeof(nfs_flags
) / sizeof(nfs_flags
[0])];
578 char dev
[4 + 1 + 7 + 1]; /* 12bit marjor + 20bit minor */
583 KGETRET(VTONFS(vp
), &nfsnode
, sizeof(nfsnode
), "vnode's nfsnode");
584 (void)getflags(nfs_flags
, flags
, np
->n_flag
);
586 KGETRET(np
->n_vattr
, &va
, sizeof(va
), "vnode attr");
587 PRWORD(ovflw
, " %*ld", 7, 1, (long)va
.va_fileid
);
588 PRWORD(ovflw
, " %*s", 6, 1, flags
);
589 switch (va
.va_type
) {
597 if (usenumflag
|| (name
= devname(va
.va_rdev
, type
)) == NULL
) {
598 devprintf(dev
, sizeof(dev
), va
.va_rdev
);
601 PRWORD(ovflw
, " %*s", 8, 1, name
);
604 PRWORD(ovflw
, " %*lld", 8, 1, (long long)np
->n_size
);
614 (void)printf(" %*s", PTRSTRWIDTH
, "LOWER");
618 layer_print(struct vnode
*vp
, int ovflw
)
620 struct layer_node lnode
, *lp
= &lnode
;
622 KGETRET(VTOLAYER(vp
), &lnode
, sizeof(lnode
), "layer vnode");
624 PRWORD(ovflw
, " %*lx", PTRSTRWIDTH
+ 1, 1, (long)lp
->layer_lowervp
);
629 * Given a pointer to a mount structure in kernel space,
630 * read it in and return a usable pointer to it.
633 getmnt(struct mount
*maddr
)
643 for (mt
= mhead
; mt
!= NULL
; mt
= mt
->next
)
644 if (maddr
== mt
->maddr
)
646 KGETRET(maddr
, &mb
, sizeof(struct mount
), "mount table");
647 if ((mt
= malloc(sizeof(struct mtab
))) == NULL
)
657 mount_print(struct mount
*mp
)
661 (void)printf("*** MOUNT %s %s on %s", ST
.f_fstypename
,
662 ST
.f_mntfromname
, ST
.f_mntonname
);
663 if ((flags
= mp
->mnt_flag
) != 0) {
665 const char *sep
= " (";
667 for (i
= 0; i
< sizeof mnt_flags
/ sizeof mnt_flags
[0]; i
++) {
668 if (flags
& mnt_flags
[i
].m_flag
) {
669 (void)printf("%s%s", sep
, mnt_flags
[i
].m_name
);
670 flags
&= ~mnt_flags
[i
].m_flag
;
675 (void)printf("%sunknown_flags:%x", sep
, flags
);
682 loadvnodes(int *avnodes
)
689 KGET(V_NUMV
, *avnodes
);
696 return (kinfo_vnodes(avnodes
));
700 if (sysctl(mib
, 2, NULL
, ©size
, NULL
, 0) == -1)
701 err(1, "sysctl: KERN_VNODE");
702 if ((vnodebase
= malloc(copysize
)) == NULL
)
704 if (sysctl(mib
, 2, vnodebase
, ©size
, NULL
, 0) == -1)
705 err(1, "sysctl: KERN_VNODE");
706 if (copysize
% (VPTRSZ
+ VNODESZ
))
707 errx(1, "vnode size mismatch");
708 *avnodes
= copysize
/ (VPTRSZ
+ VNODESZ
);
714 * simulate what a running kernel does in in kinfo_vnode
717 kinfo_vnodes(int *avnodes
)
719 struct mntlist mlist
;
720 struct mount
*mp
, mount
;
721 struct vnode
*vp
, vnode
;
725 KGET(V_NUMV
, numvnodes
);
726 if ((bp
= malloc((numvnodes
+ 20) * (VPTRSZ
+ VNODESZ
))) == NULL
)
729 ep
= bp
+ (numvnodes
+ 20) * (VPTRSZ
+ VNODESZ
);
730 KGET(V_MOUNTLIST
, mlist
);
731 for (mp
= mlist
.cqh_first
;;
732 mp
= mount
.mnt_list
.cqe_next
) {
733 KGET2(mp
, &mount
, sizeof(mount
), "mount entry");
734 TAILQ_FOREACH(vp
, &mount
.mnt_vnodelist
, v_mntvnodes
) {
735 KGET2(vp
, &vnode
, sizeof(vnode
), "vnode");
736 if (bp
+ VPTRSZ
+ VNODESZ
> ep
)
737 /* XXX - should realloc */
738 errx(1, "no more room for vnodes");
739 memmove(bp
, &vp
, VPTRSZ
);
741 memmove(bp
, &vnode
, VNODESZ
);
744 if (mp
== mlist
.cqh_last
)
747 *avnodes
= (bp
- beg
) / (VPTRSZ
+ VNODESZ
);
755 struct ttylist_head tty_head
;
758 KGET(TTY_NTTY
, ntty
);
759 (void)printf("%d terminal device%s\n", ntty
, ntty
== 1 ? "" : "s");
760 KGET(TTY_TTYLIST
, tty_head
);
762 " LINE RAW CAN OUT HWT LWT COL STATE %-*s PGID DISC\n",
763 PTRSTRWIDTH
, "SESS");
764 for (tp
= tty_head
.tqh_first
; tp
; tp
= tty
.tty_link
.tqe_next
) {
765 KGET2(tp
, &tty
, sizeof tty
, "tty struct");
770 static const struct flagbit_desc ttystates
[] = {
790 ttyprt(struct tty
*tp
)
792 char state
[sizeof(ttystates
) / sizeof(ttystates
[0]) + 1];
793 char dev
[2 + 3 + 1 + 5 + 1]; /* 12bit major + 20bit minor */
794 struct linesw t_linesw
;
800 if (usenumflag
|| (name
= devname(tp
->t_dev
, S_IFCHR
)) == NULL
) {
801 devprintf(dev
, sizeof(dev
), tp
->t_dev
);
805 PRWORD(ovflw
, "%-*s", 7, 0, name
);
806 PRWORD(ovflw
, " %*d", 3, 1, tp
->t_rawq
.c_cc
);
807 PRWORD(ovflw
, " %*d", 4, 1, tp
->t_canq
.c_cc
);
808 PRWORD(ovflw
, " %*d", 4, 1, tp
->t_outq
.c_cc
);
809 PRWORD(ovflw
, " %*d", 5, 1, tp
->t_hiwat
);
810 PRWORD(ovflw
, " %*d", 4, 1, tp
->t_lowat
);
811 PRWORD(ovflw
, " %*d", 8, 1, tp
->t_column
);
812 n
= getflags(ttystates
, state
, tp
->t_state
);
817 PRWORD(ovflw
, " %-*s", 7, 1, state
);
818 PRWORD(ovflw
, " %*lX", PTRSTRWIDTH
+ 1, 1, (u_long
)tp
->t_session
);
820 if (tp
->t_pgrp
!= NULL
)
821 KGET2(&tp
->t_pgrp
->pg_id
, &pgid
, sizeof(pid_t
), "pgid");
822 PRWORD(ovflw
, " %*d", 6, 1, pgid
);
823 KGET2(tp
->t_linesw
, &t_linesw
, sizeof(t_linesw
),
824 "line discipline switch table");
825 name
= t_linesw
.l_name
;
828 KGET2(name
, &buffer
, sizeof(buffer
), "line discipline name");
831 (void)putchar(buffer
);
837 static const struct flagbit_desc filemode_flags
[] = {
841 #ifdef FSHLOCK /* currently gone */
852 struct kinfo_file
*ki
;
853 char flags
[sizeof(filemode_flags
) / sizeof(filemode_flags
[0])];
855 int len
, maxfile
, nfile
, ovflw
;
857 KGET(FNL_MAXFILE
, maxfile
);
859 KGET(FNL_NFILE
, nfile
);
860 (void)printf("%3d/%3d files\n", nfile
, maxfile
);
863 if (getfiles(&buf
, &len
, &offset
) == -1)
866 * Getfiles returns in malloc'd memory to an array of kinfo_file2
869 nfile
= len
/ sizeof(struct kinfo_file
);
871 (void)printf("%d/%d open files\n", nfile
, maxfile
);
872 (void)printf("%*s%s%*s TYPE FLG CNT MSG %*s%s%*s IFLG OFFSET\n",
873 (PTRSTRWIDTH
- 4) / 2, "", " LOC", (PTRSTRWIDTH
- 4) / 2, "",
874 (PTRSTRWIDTH
- 4) / 2, "", "DATA", (PTRSTRWIDTH
- 4) / 2, "");
875 for (ki
= (struct kinfo_file
*)offset
; nfile
--; ki
++) {
876 if ((unsigned)ki
->ki_ftype
>= sizeof(dtypes
) / sizeof(dtypes
[0]))
879 (void)getflags(filemode_flags
, flags
, ki
->ki_flag
);
880 PRWORD(ovflw
, "%*lx", PTRSTRWIDTH
, 0, (long)ki
->ki_fileaddr
);
881 PRWORD(ovflw
, " %-*s", 9, 1, dtypes
[ki
->ki_ftype
]);
882 PRWORD(ovflw
, " %*s", 6, 1, flags
);
883 PRWORD(ovflw
, " %*d", 5, 1, ki
->ki_count
);
884 PRWORD(ovflw
, " %*d", 5, 1, ki
->ki_msgcount
);
885 PRWORD(ovflw
, " %*lx", PTRSTRWIDTH
+ 1, 2, (long)ki
->ki_fdata
);
886 PRWORD(ovflw
, " %*x", 5, 1, 0);
887 if ((off_t
)ki
->ki_foffset
< 0)
888 PRWORD(ovflw
, " %-*lld\n", PTRSTRWIDTH
+ 1, 2,
889 (long long)ki
->ki_foffset
);
891 PRWORD(ovflw
, " %-*lld\n", PTRSTRWIDTH
+ 1, 2,
892 (long long)ki
->ki_foffset
);
898 getfiles(char **abuf
, int *alen
, char **aoffset
)
907 * Add emulation of KINFO_FILE here.
910 errx(1, "files on dead kernel, not implemented");
914 mib
[2] = KERN_FILE_BYFILE
;
916 mib
[4] = sizeof(struct kinfo_file
);
918 if (sysctl(mib
, 6, NULL
, &len
, NULL
, 0) == -1) {
919 warn("sysctl: KERN_FILE2");
922 /* We need to align (struct kinfo_file *) in the buffer. */
923 offset
= len
% sizeof(off_t
);
924 mib
[5] = len
/ sizeof(struct kinfo_file
);
925 if ((buf
= malloc(len
+ offset
)) == NULL
)
927 if (sysctl(mib
, 6, buf
+ offset
, &len
, NULL
, 0) == -1) {
928 warn("sysctl: 2nd KERN_FILE2");
933 *aoffset
= (buf
+ offset
);
941 (void)fprintf(stderr
,
942 "usage: %s [-T|-f|-s|-t|-v] [-ghkmn] [-M core] [-N system]\n",