add closefrom() call

Ighighi Ighighi ighighi at gmail.com
Fri Jul 6 12:23:04 UTC 2007


> 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;
}


More information about the freebsd-hackers mailing list