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>