Date: Fri, 6 Jul 2007 08:23:02 -0400 From: "Ighighi Ighighi" <ighighi@gmail.com> To: d@delphij.net Cc: freebsd-hackers@freebsd.org Subject: Re: add closefrom() call Message-ID: <de5dfb5a0707060523w6cda3de9y57d32ad8b1d70ea@mail.gmail.com> In-Reply-To: <468CD5E9.7060000@delphij.net> References: <de5dfb5a0707041727j3e3518f9l5a019717a9f90aa@mail.gmail.com> <468CD5E9.7060000@delphij.net>
next in thread | previous in thread | raw e-mail | index | archive | help
> LI Xin <delphij at delphij.net> wrote:
> Here is my implementation for FreeBSD. Some difference between my and
> DragonFly's implementation:
>
> - closefrom(-1) would be no-op on DragonFly, my version would close all
> open files (From my understanding of OpenSolaris's userland
> implementation, this is Solaris's behavior).
> - my version closefrom(very_big_fd) would result in EBADF. I am not
> very sure whether this is correct, but it does not hurt for applications
> that thinks closefrom() would return void.
Why not follow current practice and return EBADF for -1 ?
It'd be dangerous to close all open files with -1 (a closefrom(0)
would suffice),
and weird to ignore very_big_fd.
I also agree that using fcntl() would be better.
Here's the code I'm using to emulate this call on FreeBSD >= 5.0 anyway.
int closefrom(int lowfd)
{
int mib[2] = { CTL_KERN, KERN_FILE };
struct xfile *files = NULL;
pid_t pid = getpid();
int i, nfiles;
size_t fsize;
for (;;) {
if (sysctl(mib, 2, files, &fsize, NULL, 0) == -1) {
if (errno != ENOMEM)
goto bad;
else if (files != NULL) {
free(files);
files = NULL;
}
}
else if (files == NULL) {
files = (struct xfile *) malloc(fsize);
if (files == NULL)
return -1;
}
else
break;
}
/* XXX This structure may change */
if (files->xf_size != sizeof(struct xfile) ||
fsize % sizeof(struct xfile))
{
errno = ENOSYS;
goto bad;
}
nfiles = fsize / sizeof(struct xfile);
for (i = 0; i < nfiles; i++)
if (files[i].xf_pid == pid && files[i].xf_fd >= lowfd)
close(files[i].xf_fd);
free(files);
return 0;
bad:
if (files != NULL) {
int save_errno = errno;
free(files);
errno = save_errno;
}
return -1;
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?de5dfb5a0707060523w6cda3de9y57d32ad8b1d70ea>
