16

In Stevens' UNIX Network Programming, he mentions redirecting stdin, stdout and stderr, which is needed when setting up a daemon. He does it with the following C code

/* redirect stdin, stdout, and stderr to /dev/null */
open("/dev/null", O_RDONLY);
open("/dev/null", O_RDWR);
open("/dev/null", O_RDWR);

I'm confused how these three 'know' they are redirecting the three std*. Especially since the last two commands are the same. Could someone explain or point me in the right direction?

matsjoyce
  • 5,744
  • 6
  • 31
  • 38
Paul
  • 161
  • 1
  • 1
  • 3

2 Answers2

17

Presumably file descriptors 0, 1, and 2 have already been closed when this code executes, and there are no other threads which might be allocating new file descriptors. In this case, since open is required to always allocate the lowest available file descriptor number, these three calls to open will yield file descriptors 0, 1, and 2, unless they fail.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Any reason he chose `O_RDWR` instead of `O_WRONLY`? – Matt Joiner Nov 24 '10 at 03:23
  • 1
    Because the order of the file descriptors is stdin, stdout, stderr. The standard input is, of course, read only. – salezica Nov 24 '10 at 03:24
  • Surely stdout and stderr could be opened `O_WRONLY`, but I don't think it really matters... – R.. GitHub STOP HELPING ICE Nov 24 '10 at 03:29
  • You are correct, all file descriptors were closed prior to the code I provided. Thanks, this makes perfect sense. – Paul Dec 04 '10 at 20:06
  • @R..GitHubSTOPHELPINGICE one case is silent and does something you never intended to happen, other case returns explicit error telling you that what you're doing is completely wrong. It obviously matters, unless software quality doesn't matter. –  Mar 03 '22 at 17:34
5

It's because file descriptors 0, 1 and 2 are input, output and error respectively, and open will grab the first file descriptor available. Note that this will only work if file descriptors 0, 1 and 2 are not already being used.

And you should be careful about the terms used, stdin, stdout and stderr are actually file handles (FILE*) rather than file descriptors, although there is a correlation between those and the file descriptors.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953