1

In my fairly large C/C++ console application, I wish to redirect the output of printf, fprintf(stderr,...), cout, and cerr to screen as well as a log file.

I could do something like this using "tee" or redirecting the output when launching the program by using redirection (How can I redirect and append both stdout and stderr to a file with Bash?).

However, I want to do it programmatically from inside my main routine without modifying existing code. I was hoping to add some code at the start of my main() function to appropriately set the streams so that all subsequent calls to printf, fprintf(stdout,...), fprintf(stderr,...), cout, cerr, etc. print their output on screen as usual, but additionally also log the output into a file.

There may be some issue with the sequence due to stdout being buffered and stderr being not buffered, but that is OK. It would be even better, if it can be done in a cross-platform manner.

Community
  • 1
  • 1
Santosh Tiwari
  • 1,167
  • 2
  • 14
  • 26
  • You could change the file-descriptors to a `pipe()` you create on startup, then have a function `read()` from the pipe and distribute the data to whatever other streams you want. This may even be doable in a sane way, by having said redirection done in the program's parent. *Be* the shell... – EOF Jan 09 '17 at 16:55

1 Answers1

2

Not only would it be easier, but it would also be a better design to let the program user determine how to redirect the program's I/O, rather than building it into the program. If you wish, write a wrapper script around the binary that sets up the redirections you describe, so that people don't have to do that themselves.

With that said, you can do what you describe programmatically, at least on a POSIX system. You have to understand, however, that a single stream (stdout, for example) connects a single source with a single sink. In order to direct one source to two sinks, you need a middleman, such as the tee command. For that to be transparent to your process you'll need to fork off one or more other processes to handle it, redirecting the main process's standard output and standard error streams to that child(ren) over a pipe. You could exec tee in the child process(es), or you could roll your own implementation.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • I was thinking along similar lines. If I have to fork the process, then I can accomplish it. Thanks. – Santosh Tiwari Jan 09 '17 at 18:31
  • @SantoshTiwari, you should also be able to do it with threads rather than processes, if you should prefer to do that. I reiterate, however, that I think the whole thing is a bad idea. – John Bollinger Jan 09 '17 at 18:36