5

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?

Felipe Lavratti
  • 2,887
  • 16
  • 34
lanoxx
  • 12,249
  • 13
  • 87
  • 142
  • Maybe they're talking about a library function, which doesn't know which descriptors the caller has set the *close-on-exec* flag for, so it has to assume the worst. – Barmar Dec 08 '16 at 22:20
  • 2
    Also, the library shouldn't change the state of file descriptors that the caller is using. – Barmar Dec 08 '16 at 22:20
  • @Barmar unless it's his purpose, ncurses, libcaca, etc. – Stargateur Dec 08 '16 at 22:22
  • 2
    [3] seems to imply the COE flag was set by default, which it isn't. But it's not actually *saying* this and not actually excluding that someone might have set it deliberately before. Agree, however, that this is at least misleading. – tofro Dec 08 '16 at 22:28
  • Is there some prior context that indicates that the file descriptors under discussion have the FD_CLOEXEC (or O_CLOEXEC) flag set? If not, it is probably mildly confused; FD_CLOEXEC is not set by default. – Jonathan Leffler Dec 08 '16 at 22:37
  • I just read this up in the original (http://openbook.rheinwerk-verlag.de/linux_unix_programmierung/Kap02-002.htm#RxxKap02002040000CC1F023214 for anyone who can read German), and yes, this actually seems to be messed up. The paragraph *really* sounds as if COE were the default. – tofro Dec 08 '16 at 22:40
  • "When **this flag** is set, **all** file descriptors become invalid" - It really sounds like this is saying there is one flag for the entire process, which is all kinds of wrong! – Kevin Dec 08 '16 at 22:54
  • @tofro Thanks for reading this up in German and confirming that its messed up. I was already starting to doubt my understanding of C and IPC. – lanoxx Dec 08 '16 at 23:18
  • 2
    You didn't read on: It continues "If you don't completely follow this or don't get it at all, that's not so important now" :) Nice book! – tofro Dec 08 '16 at 23:23
  • There are *many* terrible books on C. The tough part is finding a good one. I'm partial to the C11 draft standard n1570 myself, and the POSIX standard for POSIX-related topics. – EOF Dec 09 '16 at 06:00

1 Answers1

3

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.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103