Code below redirects stdout to a file fname & then redirects back to original stdout. It works fine for me. But I am not able to understand how it actually works. If anyone can help me understand I will appreiciate it.
printf("\n This is console");
fflush(stdout);
fgetpos(stdout, &pos);
fd = dup(fileno(stdout));
freopen(fname, "a+", stdout);
printf("inside file op");
fflush(stdout);
dup2(fd,fileno(stdout));
close(fd);
clearerr(stdout);
fsetpos(stdout, &pos);
printf("\nBack to Console");
Let's go through it line by line. The first line prints something to stdout
:
printf("\n This is console");
Then it flushes stdout
so all the remaining data in the buffer gets sent to stdout
and won't get mixed up with the file data:
fflush(stdout);
Now we store the current position of ourselves in stdout
because otherwise if stdout
was already directed to a file, we might (?) overwrite earlier parts of it.
fgetpos(stdout, &pos);
Now we clone the file descriptor of what's currently stdout
. Since we're about to change where stdout
points to, we need to keep a copy of the original:
fd = dup(fileno(stdout));
Now that we have everything preserved, we can reopen stdout
as the file:
freopen(fname, "a+", stdout);
At this point, stdout
has been redirected to the file. We can now print to it:
printf("inside file op");
Now we're done printing to the file. We need to flush stdout
(now the file) so it doesn't get mixed up with the normal stdout
data:
fflush(stdout);
After that, we clone the original stdout
file descriptor over the current stdout
descriptor.
dup2(fd,fileno(stdout));
The cloned one can be closed now:
close(fd);
I'm not quite sure why this is here but this clears any errors that occurred writing to the file:
clearerr(stdout);
Now we restore our position in stdout
. Again, as far as I know, this is only useful if it was originally redirected to a file:
fsetpos(stdout, &pos);
Now we're back to the original stdout
, so we can print again:
printf("\nBack to Console");