I mean to associate a file descriptor with a file pointer and use that for writing.
I put together program io.cc
below:
int main() {
ssize_t nbytes;
const int fd = 3;
char c[100] = "Testing\n";
nbytes = write(fd, (void *) c, strlen(c)); // Line #1
FILE * fp = fdopen(fd, "a");
fprintf(fp, "Writing to file descriptor %d\n", fd);
cout << "Testing alternate writing to stdout and to another fd" << endl;
fprintf(fp, "Writing again to file descriptor %d\n", fd);
close(fd); // Line #2
return 0;
}
I can alternately comment lines 1 and/or 2, compile/run
./io 3> io_redirect.txt
and check the contents of io_redirect.txt
.
Whenever line 1 is not commented, it produces in io_redirect.txt
the expected line Testing\n
.
If line 2 is commented, I get the expected lines
Writing to file descriptor 3
Writing again to file descriptor 3
in io_redirect.txt
.
But if it is not commented, those lines do not show up in io_redirect.txt
.
- Why is that?
- What is the correct way of using
fdopen
?
NOTE.
This seems to be the right approach for a (partial) answer to Smart-write to arbitrary file descriptor from C/C++
I say "partial" since I would be able to use C-style fprintf
.
I still would like to also use C++-style stream<<
.
EDIT:
I was forgetting about fclose(fp)
.
That "closes" part of the question.
The opened stream ("stream" is an opened
FILE*
) is block buffered, so nothing gets written to the destination before the file is flushed. Exiting from an application closes all open streams, which flushes the stream.Because you close the underlying file descriptor before flushing the stream, the behavior of your program is undefined. I would really recommend you to read posix 2.5.1 Interaction of File Descriptors and Standard I/O Streams (which is written in a horrible language, nonetheless), from which:
A "handle" is a file descriptor or a stream. An "active handle" is the last handle that you did something with.
The
fp
stream is the active handle that is open for appending to file descriptor3
. Becausefp
is an active handle and is not flushed and you switch the active handle tofd
withclose(fd)
, the behavior of your program is undefined.What is my guess and most probably happens is that your C standard library implementation calls
fflush(fp)
aftermain
returns, becausefd
is closed, some internalwrite(3, ...)
call returns an error and nothing is written to the output.The usage you presented is the correct way of using
fdopen
.