Recent Solaris provides a way to delete all file descriptors
greater than a given integer, and provides a way to ask
posix_spawn to do so. I believe glibc should implement these extensions.
Both of the big programs I have worked on, xemacs and openjdk,
have written their own way to do this.
extern int posix_spawn_file_actions_addclosefrom_np(
extern void closefrom(int);
The functionality that has been added to glibc allowing FD_CLOSE_ON_EXEC
to be specified at time of creation of the fd does help (thank you)
but it is not sufficient for "open" programs like the JDK where
arbitrary third party native code may be concurrently opening file
descriptors while creating a subprocess.
nscd.c does this by hand in a Linux-specific way, and it is trivial to implement
in libc on Hurd. So this seems like a good addition.
No, it's a horrible idea. The assumption that a program knows all the open file
descriptors is simply invalid. The runtime (all kinds of libraries) can at any
point in time create additional file descriptors and indiscriminately calls for
trouble. The correct way is to name the individual file descriptors the program
knows about and let the creator of the other file descriptors worry about the rest.
The reason nscd can do it the way it does it is simple: all the code used is
controlled by libc. But that's a special case.
Aside from the Solaris 10 precedent, other OSes have adopted
closefrom, apparently with the same behavior.
To provide more motivation, the idea is that you are in a
large multithreaded app that is swimming in a sea of unknown
file descriptors that may or may not have FD_CLOEXEC set,
you fork(), frob some file descriptors you care about,
and then need to close the rest. You write your own buggy closefrom
or use the one provided by the system.
(In reply to comment #3)
> Here's OpenBSD:
> Here's NetBSD:
This is *anything* but an argument in favor.
> To provide more motivation, the idea is that you are in a
> large multithreaded app that is swimming in a sea of unknown
> file descriptors that may or may not have FD_CLOEXEC set,
So, fix the code. We have O_CLOEXEC support as well. There is no reason to
work around buggy code and this interface *actively* prevents innovations by
usurping file descriptors.
>> To provide more motivation, the idea is that you are in a
>> large multithreaded app that is swimming in a sea of unknown
>> file descriptors that may or may not have FD_CLOEXEC set,
>So, fix the code. We have O_CLOEXEC support as well. There is no reason to
>work around buggy code and this interface *actively* prevents innovations by
>usurping file descriptors.
For many applications, there is no way in practice to control all the
code running in the same address space. This is especially true for
"platforms" like java, where arbitrary user-created shared libraries
are loaded and executed at runtime.
The idea of permitting innovations that use file descriptors is
an interesting one, but one that in my opinion cannot succeed.
Too many people (like myself) are maintaining library code
that starts new subprocesses, and they will continue to
indiscriminately close unknown file descriptors,
with or without help from their libc.
While my library closes file descriptors unconditionally,
The python subprocess API makes closing fds an option.
"""If close_fds is true, all file descriptors except 0, 1 and 2 will be
closed before the child process is executed."""
Interestingly, python provides a related function
.. function:: closerange(fd_low, fd_high)
Close all file descriptors from *fd_low* (inclusive) to *fd_high* (exclusive),
ignoring errors. Availability: Unix, Windows. Equivalent to::
for fd in xrange(fd_low, fd_high):
which doesn't seem to support "infinity" for the second argument.