kern.file weirdness

YONETANI Tomokazu qhwt at myrealbox.com
Sat Nov 22 05:09:49 PST 2003


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.

Cheers.





More information about the Submit mailing list