2 * Copyright (c) 1989, 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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 * 4. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #if defined(LIBC_SCCS) && !defined(lint)
35 static char sccsid
[] = "@(#)kvm_file.c 8.1 (Berkeley) 6/4/93";
37 #endif /* LIBC_SCCS and not lint */
40 * File list interface for kvm. pstat, fstat and netstat are
41 * users of this code, so we've factored it out into a separate module.
42 * Thus, we keep this grunge out of the other kvm applications (i.e.,
43 * most other applications are interested only in open/close/read/nlist).
46 #include <sys/param.h>
49 #define _WANT_FILE /* make file.h give us 'struct file' */
52 #include <sys/ioctl.h>
57 #include <vm/vm_param.h>
59 #include <sys/sysctl.h>
65 #include "kvm_private.h"
67 #define KREAD(kd, addr, obj) \
68 (kvm_read(kd, addr, obj, sizeof(*obj)) != sizeof(*obj))
70 #define KREADN(kd, addr, obj, cnt) \
71 (kvm_read(kd, addr, obj, (cnt)) != (cnt))
74 * Get file structures.
77 kvm_deadfiles(kd
, op
, arg
, allproc_o
, nprocs
)
83 struct filedesc filed
;
84 int buflen
= kd
->arglen
, ocnt
= 0, n
= 0, once
= 0, i
;
88 char *where
= kd
->argspc
;
90 if (buflen
< sizeof (struct file
*) + sizeof (struct file
))
92 if (KREAD(kd
, allproc_o
, &p
)) {
93 _kvm_err(kd
, kd
->program
, "cannot read allproc");
96 for (; p
!= NULL
; p
= LIST_NEXT(&proc
, p_list
)) {
97 if (KREAD(kd
, (u_long
)p
, &proc
)) {
98 _kvm_err(kd
, kd
->program
, "can't read proc at %x", p
);
101 if (proc
.p_state
== PRS_NEW
)
103 if (proc
.p_fd
== NULL
)
105 if (KREAD(kd
, (u_long
)p
->p_fd
, &filed
)) {
106 _kvm_err(kd
, kd
->program
, "can't read filedesc at %x",
110 if (filed
.fd_lastfile
+ 1 > ocnt
) {
111 ocnt
= filed
.fd_lastfile
+ 1;
113 ofiles
= (struct file
**)_kvm_malloc(kd
,
114 ocnt
* sizeof(struct file
*));
118 if (KREADN(kd
, (u_long
)filed
.fd_ofiles
, ofiles
,
119 ocnt
* sizeof(struct file
*))) {
120 _kvm_err(kd
, kd
->program
, "can't read ofiles at %x",
124 for (i
= 0; i
<= filed
.fd_lastfile
; i
++) {
125 if ((fp
= ofiles
[i
]) == NULL
)
128 * copyout filehead (legacy)
131 *(struct file
**)kd
->argspc
= fp
;
132 *(struct file
**)where
= fp
;
133 buflen
-= sizeof (fp
);
134 where
+= sizeof (fp
);
137 if (buflen
< sizeof (struct file
))
139 if (KREAD(kd
, (long)fp
, ((struct file
*)where
))) {
140 _kvm_err(kd
, kd
->program
, "can't read kfp");
143 buflen
-= sizeof (struct file
);
144 fp
= (struct file
*)where
;
145 where
+= sizeof (struct file
);
158 kvm_getfiles(kd
, op
, arg
, cnt
)
163 int mib
[2], st
, n
, nfiles
, nprocs
;
166 _kvm_syserr(kd
, kd
->program
, "kvm_getfiles has been broken for years");
172 st
= sysctl(mib
, 2, NULL
, &size
, NULL
, 0);
174 _kvm_syserr(kd
, kd
->program
, "kvm_getfiles");
178 kd
->argspc
= (char *)_kvm_malloc(kd
, size
);
179 else if (kd
->arglen
< size
)
180 kd
->argspc
= (char *)_kvm_realloc(kd
, kd
->argspc
, size
);
184 st
= sysctl(mib
, 2, kd
->argspc
, &size
, NULL
, 0);
186 _kvm_syserr(kd
, kd
->program
, "kvm_getfiles");
189 nfiles
= size
/ sizeof(struct xfile
);
191 struct nlist nl
[4], *p
;
193 nl
[0].n_name
= "_allproc";
194 nl
[1].n_name
= "_nprocs";
195 nl
[2].n_name
= "_nfiles";
198 if (kvm_nlist(kd
, nl
) != 0) {
199 for (p
= nl
; p
->n_type
!= 0; ++p
)
201 _kvm_err(kd
, kd
->program
,
202 "%s: no such symbol", p
->n_name
);
205 if (KREAD(kd
, nl
[1].n_value
, &nprocs
)) {
206 _kvm_err(kd
, kd
->program
, "can't read nprocs");
209 if (KREAD(kd
, nl
[2].n_value
, &nfiles
)) {
210 _kvm_err(kd
, kd
->program
, "can't read nfiles");
213 size
= sizeof(void *) + (nfiles
+ 10) * sizeof(struct file
);
215 kd
->argspc
= (char *)_kvm_malloc(kd
, size
);
216 else if (kd
->arglen
< size
)
217 kd
->argspc
= (char *)_kvm_realloc(kd
, kd
->argspc
, size
);
221 n
= kvm_deadfiles(kd
, op
, arg
, nl
[0].n_value
, nprocs
);
223 _kvm_err(kd
, kd
->program
, "inconsistant nfiles");