The behaviour of printf()
seems to depend on the location of stdout
.
stdout
is sent to the console, then printf
Your are wrongly combining buffered and unbuffered IO functions. Such a combination must be done very carefully especially when the code has to be portable. (and it is bad to write unportable code...)
It is certainly best to avoid combining buffered and unbuffered IO on the same file descriptor.
Buffered IO: fprintf()
, fopen()
, fclose()
, freopen()
...
Unbuffered IO: write()
, open()
, close()
, dup()
...
When you use dup2()
to redirect stdout. The function is not aware of the buffer which was filled by fprintf()
. So when dup2()
closes the old descriptor 1 it does not flush the buffer and the content could be flushed to a different output. In your case 2a it was sent to /dev/null
.
In your case it is best to use freopen()
instead of dup2()
. This solves all your problems:
FILE
stream. (case 2a)Here is the correct implementation of your function:
void RedirectStdout2File(const char* log_path) {
if(freopen(log_path, "a+", stdout) == NULL) err(EXIT_FAILURE, NULL);
}
Unfortunately with buffered IO you cannot directly set permissions of a newly created file. You have to use other calls to change the permissions or you can use unportable glibc extensions. See the fopen() man page.