sdaau
sdaau

Reputation: 38619

Linux C: what happens to unused file descriptors?

(apologies for not taking care of my accepts lately - will do so as soon as I get some time; just wanted to ask this question now that it occurred)

Consider the following C program:

int main(void) {
  write(3, "aaaaaa\n", 7);
  write(2, "bbbbbb\n", 7);
  write(1, "cccccc\n", 7);
  return 0;
}

I build and run it from the bash shell like this:

$ gcc -o wtest wtest.c
$ ./wtest 3>/dev/stdout
aaaaaa
bbbbbb
cccccc

The way I see it, in this case, due to the shell redirection of fd 3 to stdout, that file descriptor is now "used" (not sure about "opened", since there is no opening of files, in the C code at least) - and so we get the cccccc string output to terminal, as expected.

If I don't use the redirection, then the output is this:

$ ./wtest 
aaaaaa
bbbbbb

Now fd 3 is not redirected - and so cccccc string is not output, again as expected.

 

My question is - what happened to those cccccc bytes? Did they dissapear in the same sense, as if I redirected fd 3 to /dev/null? (as in:

$ ./wtest 3>/dev/null

)

In addition, assuming that in a particular case I'd like to "hide" the fd 3 output: would there be a performance difference between redirecting "3>/dev/null" vs. not addressing fd 3 in the shell at all (in terms of streaming data; that is, if fd 3 outputs a really long byte stream, would there be an instruction penalty per byte written in the "3>/dev/null" case, as opposed to not addressing fd 3)?

 

Many thanks in advance for any answers,
Cheers!

Upvotes: 1

Views: 917

Answers (2)

ElDesdichado
ElDesdichado

Reputation: 31

Jens is right. If you run your program under strace on both situations, you'll see that when you redirect, the write works - because the shell called pipe() on your behalf before fork'ing your executable.

When you look at the strace without the redirection:

write(3, "aaaaaa\n", 7)                 = -1 EBADF (Bad file descriptor)
write(2, "bbbbbb\n", 7bbbbbb)                 = 7
write(1, "cccccc\n", 7cccccc)                 = 7

Which reminds us of the best practice - always check your return values.

Upvotes: 0

Jens Gustedt
Jens Gustedt

Reputation: 78903

My question is - what happened to those cccccc bytes?

nothing. you failed to capture the return code of write, it should tell you that there was an error and errno should tell you what the error was

You also seem to have a questionable concept of what is persistent, the "bytes" are still sitting in the string literal where the compiler put them from the beginning. write copies byte to a stream.

Upvotes: 4

Related Questions