Stdout redirection does not work if stdout is a file

I use the following code to redirect stdout before calling a noisy function from an external Fortran library:

// copy standard output out = dup(STDOUT_FILENO); // close standard output close(STDOUT_FILENO); // use log file as standard output log = open(log_file, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); if(log != STDOUT_FILENO) fprintf(stderr, "could not create log file %s", log_file); // call the library function that uses a lot of printf func(); // restore original standard output dup2(out, STDOUT_FILENO); // close copy of standard output close(out); 

To summarize my intention for the above code snippet: copy stdout, close stdout (release file descriptor 0), open the file (uses the smallest file descriptor = 0 = stdout), run the code with the redirected stdout and reset stdout.

This works fine when I run my code using a terminal like stdout. However, when I set stdout to a file (using $ mycode > myfile.txt ), the redirect fails, and I end the output of func() in myfile.txt instead of the log file. How is this possible?

+1
source share
1 answer

You need to do fflush(stdout) before restoring the original stdout with dup2 .

The reason it works with the terminal is because stdout is string buffered for the terminal. Thus, your output is immediately cleared to a redirected file. But when you run your program using stdout in a file, stdout becomes fully buffered, so your func output will be in a buffer waiting to be reset. When you restore the original exposure without washing, the output is written to the original stdout when the program exits.

+2
source

Source: https://habr.com/ru/post/1263293/


All Articles