Search code examples
cunixdup

C: dup and close-on-exec


In a (German) book about C programming (Linux-UNIX-Programmierung, by Jürgen Wolf) I have found a statement, which translated to English would be as following (sentences numbered by me):

In some cases it can be necessary that you need to duplicate a file descriptor [1]. An example for this would be, if a parent process wants to exchange data with a child process and the child process is overlaid by a new process through the use of exec*() [2]. In such a case, without dup() or dup2(), the close-on-exec flag would be set [3]. When this flag is set, all file descriptors become invalid (since being overlaid by the new process) - that is, they are not present anymore [4]. The communication between the parent and child process would thus be stopped [5]. If on the other hand you duplicate the file descriptor with dup() or dup2(), then the close-on-exec flag is deleted, and the newly overlaid process can use this file descriptor to communicate [6].

I believe that the above paragraph contains several misleading statements or even errors.

In sentence [3], I do not understand why without the use of dup() or dup2() the close-on-exec flag would be set?


Solution

  • The advice is wrong. Close-on-exec is set only on file descriptors that your program has explicitly asked to be close-on-exec.

    The reasons you may choose to use dup2 may be:

    • The process to be executed expects its I/O to be via particular file descriptors (usually 0, 1, and 2, corresponding to standard input, output and error streams respectively), or
    • the process will close some file descriptors, for whatever reason, and you need this fd to be outside the range to be closed.

    The description is also slightly misleading - it's only the new descriptor (i.e. the return value from dup() or dup2()) which has close-on-exec unset. The close-on-exec state of the original fd is unchanged.