DragonFly BSD
DragonFly submit List (threaded) for 2003-11
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: kern.file weirdness


From: Eirik Nygaard <eirikn@xxxxxxxxxxxx>
Date: Sat, 22 Nov 2003 14:22:57 +0100

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:
> > void
> > get_files(void)
> > {
> > 	size_t size;
> > 	
> > 	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(struct file);
> > 	{
> > 		int i;
> > 		for(i = 0; i < nfiles; i++)
> > 			printf("Type: %d\n", files[i].f_type);
> > 	}
> > 	
> > }
> > 
> > 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:
> 
> static void
> getfiles(void)
> {
> 	size_t len;
> 
> 	if ((xfiles = malloc(len = sizeof *xfiles)) == NULL)
> 		err(1, "malloc()");
> 	while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) {
> 		if (errno != ENOMEM)
> 			err(1, "sysctlbyname()");
> 		len *= 2;
> 		if ((xfiles = realloc(xfiles, len)) == NULL)
> 			err(1, "realloc()");
> 	}
> 	if (len > 0 && xfiles->xf_size != sizeof *xfiles)
> 		errx(1, "struct xfile size mismatch");
> 	nxfiles = len / sizeof *xfiles;
> }
> 
> 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.

> Cheers.


-- 
Eirik Nygaard
eirikn@xxxxxxxxxxxx




[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]