kern.file weirdness
Eirik Nygaard
eirikn at kerneled.com
Sun Nov 23 03:10:00 PST 2003
On Sun, Nov 23, 2003 at 09:01:19AM +0900, YONETANI Tomokazu wrote:
> On Sat, Nov 22, 2003 at 02:22:57PM +0100, Eirik Nygaard wrote:
> > On Sat, Nov 22, 2003 at 10:08:57PM +0900, YONETANI Tomokazu wrote:
> > > Hello.
> > >
> > > On Sat, Nov 22, 2003 at 11:53:30AM +0100, Eirik Nygaard wrote:
> > > > I am working on removing perlism in userland and have come over a little
> > > > problem when I am rewriting sockstat. I try to get all the open fd's from
> > > > the kern.file sysctl with this code:
[ ... ]
> > > >
> > > > but it only gives me bogus results for some reason.
> > > >
> > > > Output:
> > > > Type: -16333
> > > > Type: -14424
> > > > [...]
> > > > Type: -14424
> > > >
> > > > Would be grateful if someone knows what I am doing wrong here.
> > >
> > > FreeBSD-current's version of sockstat has a block of code
> > > which looks like this:
> > >
[ ... ]
> > >
> > > i.e., you must resize the buffer until sysctlbyname() fails with
> > > ENOMEM.
> >
> > If you check out the manpage for sysctlbyname it states:
> > The size of the available data can be determined by calling sysctl() with
> > the NULL argument for oldp. The size of the available data will be
> > returned in the location pointed to by oldlenp. For some operations, the
> > amount of space may change often. For these operations, the system
> > attempts to round up so that the returned size is large enough for a call
> > to return the data shortly thereafter.
> >
> > so I think it is something else, but thanks for the tip.
>
> Ah, I didn't even understand your question, sorry. Please do
>
> less +/^sysctl_kern_file /sys/kern/kern_descrip.c
>
> And you'll notice why the returned array has an extra garbage(filehead)
> in front of it.
>
> | error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead));
> | if (error)
> | return (error);
> |
> | /*
> | * followed by an array of file structures
> | */
> | LIST_FOREACH(fp, &filehead, f_list) {
> | error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file));
> | if (error)
> | return (error);
> | }
> | return (0);
> |}
>
> So you can rewrite your example code to something like this:
>
> void
> get_files(void)
> {
> struct {
> struct filelist head;
> struct file array[1];
> } *files;
> struct file *f;
> size_t size;
> int i;
>
> if (sysctlbyname("kern.file", NULL, &size, NULL, 0) < 0)
> err(1, "sysctlbyname()");
> if ((files = malloc(size)) == NULL)
> err(1, "malloc()");
> if (sysctlbyname("kern.file", files, &size, NULL, 0) < 0)
> err(1, "sysctlbyname()");
> nfiles = (size - sizeof(files->head)) / (sizeof files->array[0]);
> for(f = files->array; f < files->array + nfiles; ++f)
> printf("Type: %d\n", f->f_type);
> }
>
> FreeBSD-CURRENT's version of `sysctl -b kern.file' returns just an
> array of struct xfile, so your code could be simpler(but making
> sysctl_kern_file messy).
>
>
Of course!
I missed the struct filelist head when I looked at that command. Thanks.
Works like a charm now. :)
--
Eirik Nygaard
eirikn at xxxxxxxxxxxx
Attachment:
pgp00012.pgp
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pgp00012.pgp
Type: application/octet-stream
Size: 187 bytes
Desc: "Description: PGP signature"
URL: <http://lists.dragonflybsd.org/pipermail/submit/attachments/20031123/24ff22d8/attachment-0019.obj>
More information about the Submit
mailing list