Set the ``close-on-exec'' flag on the given descriptor. A descriptor with the close-on-exec flag is automatically closed when the current process starts another program with one of the exec
, create_process
and open_process
functions.
It is often a security hole to leak file descriptors opened on, say, a private file to an external program: the program, then, gets access to the private file and can do bad things with it. Hence, it is highly recommended to set all file descriptors ``close-on-exec'', except in the very few cases where a file descriptor actually needs to be transmitted to another program.
The best way to set a file descriptor ``close-on-exec'' is to create it in this state. To this end, the openfile
function has O_CLOEXEC
and O_KEEPEXEC
flags to enforce ``close-on-exec'' mode or ``keep-on-exec'' mode, respectively. All other operations in the Unix module that create file descriptors have an optional argument ?cloexec:bool
to indicate whether the file descriptor should be created in ``close-on-exec'' mode (by writing ~cloexec:true
) or in ``keep-on-exec'' mode (by writing ~cloexec:false
). For historical reasons, the default file descriptor creation mode is ``keep-on-exec'', if no cloexec
optional argument is given. This is not a safe default, hence it is highly recommended to pass explicit cloexec
arguments to operations that create file descriptors.
The cloexec
optional arguments and the O_KEEPEXEC
flag were introduced in OCaml 4.05. Earlier, the common practice was to create file descriptors in the default, ``keep-on-exec'' mode, then call set_close_on_exec
on those freshly-created file descriptors. This is not as safe as creating the file descriptor in ``close-on-exec'' mode because, in multithreaded programs, a window of vulnerability exists between the time when the file descriptor is created and the time set_close_on_exec
completes. If another thread spawns another program during this window, the descriptor will leak, as it is still in the ``keep-on-exec'' mode.
Regarding the atomicity guarantees given by ~cloexec:true
or by the use of the O_CLOEXEC
flag: on all platforms it is guaranteed that a concurrently-executing Caml thread cannot leak the descriptor by starting a new process. On Linux, this guarantee extends to concurrently-executing C threads. As of Feb 2017, other operating systems lack the necessary system calls and still expose a window of vulnerability during which a C thread can see the newly-created file descriptor in ``keep-on-exec'' mode.