Close-on-exec
Close-on-exec is a per-file-descriptor flag that causes that descriptor to be closed when its process successfully replaces its program image with an exec-family operation.
Lifetime: FD_CLOEXEC does not close a descriptor at fork. The child initially retains its inherited reference; successful exec closes the child's descriptor when the flag is set. An exec failure that returns to the caller, such as ENOENT for a missing executable, leaves the descriptor open. The parent's reference remains separate. [1] [4]
Creation: open(..., O_CLOEXEC) sets the flag as part of descriptor creation. Opening first and setting FD_CLOEXEC later with fcntl leaves a window in which another thread can fork and exec with the descriptor still inheritable. O_CLOEXEC names the creation option, not an open-file-description status flag. [2]
Aliases: raw Linux dup clears close-on-exec on the new descriptor even when the original has it set. dup3(oldfd, newfd, O_CLOEXEC) sets it on a distinct target. Both descriptors still share the open file description and its offset. Closing one at exec does not close a surviving unmarked alias or undo earlier writes. [3] [5]
Failure boundary: an execve failure after the old image has been torn down can terminate the process instead of returning to its caller. The ENOENT example covers a returned failure, not every possible exec failure. [6]
Relations
- related
- File descriptor, Open file description, close, File offset
Limitations
- Close-on-exec is inheritance control, not a data flush or a complete process-isolation mechanism.
Citations
- Linux man-pages: F_GETFD(2const), descriptor flags and exec outcome
- Linux man-pages: open(2), O_CLOEXEC and atomic descriptor creation
- Linux man-pages: dup(2), descriptor-local flags and dup3
- Linux man-pages: fork(2), inherited descriptors and shared open file descriptions
- Hesela: Descriptor inheritance across program replacement
- Linux man-pages: execve(2), failures past program-image teardown
Sources & caveats
- API behavior is scoped to the cited Linux interfaces; high-level language runtimes may create non-inheritable descriptors by default.