[Haskell-cafe] Discussion: The CLOEXEC problem

Donn Cave donn at avvanta.com
Wed Jul 22 02:47:20 UTC 2015

quoth Niklas Hambüchen,
> The scope of this program is quite general unfortunately: It will happen
> for any program that uses parallel threads, and that runs two or more
> external processes at some time. It cannot be fixed by the part that
> starts the external process (e.g. you can't write a reliable
> `readProcess` function that doesn't have this problem, since the problem
> is rooted in the Fds, and there is no version of `exec()` that doesn't
> inherit parent Fds).
> This problem is a general problem in C on Unix, and was discovered quite
> late.

I believe it has actually been a familiar issue for decades.  I don't
have any code handy to check, but I'm pretty sure the UNIX system(3)
and popen(3) functions closed extraneous file descriptors back in the
early '90s, and probably had been doing it for some time by then.

I believe this approach to the problem is supported in System.Process,
via close_fds.  Implementation is a walk through open FDs, in the child
fork, closing anything not called for by the procedure's parameters
prior to the exec.

That approach has the advantage that it applies to all file descriptors,
whether created by open(2) or by other means - socket, dup(2), etc.

I like this already implemented solution much better than adding a
new flag to "all" opens (really only those opens that occur within
the Haskell runtime, while of course not for external library FDs.)
The O_CLOEXEC proposal wouldn't be the worst or most gratuitous
way Haskell tampers with normal UNIX parameters, but any time you
do that, you set up the conditions for breaking something that
works in C, which I hate to see happen with Haskell.


More information about the Haskell-Cafe mailing list