tags:

views:

37

answers:

3

I am trying to redirect the output of a c program to file, even when it generates some errors because of problems with the input data. I can send the output but the error messages to a file.

Does somebody know how to do it?

+3  A: 

(This answer applies to bash shell, and similar flavors. You didn't specify your environment and this sort of question needs that detail.)

I assume you know about basic redirection with ">". To also capture STDERR in addition to STDOUT, use the following syntax:

command > file-name 2>&1

For some more background on standard streams and numbers:

http://en.wikipedia.org/wiki/Standard_streams#Standard_input_.28stdin.29

I believe that you have to do those in the other order, they way you have it would put the stdout of command into file-name, and the stderr of command into stdout of the pipeline. Also Aldo didn't say he is using bash, in fact there's nothing at all in the question to suggest that.
Ben Voigt
The order is correct but you're right about the bash assumption. I'll edit the answer.
+6  A: 

From within C source code, you can redirect outputs using freopen():

General outputs:

freopen("myfile.txt", "w", stdout);

Errors:

freopen("myfile_err.txt", "w", stderr);
Donotalo
+1  A: 

This depends on what you mean and what platform you are using. Very often you can accomplish this from the command line, which has been covered in another answer. If you use this method to accomplish this you should be aware that FILE * stderr is typically written immediately (unbuffered) while FILE * stdout may be buffered (usually line buffered) so you could end up with some of your error messages appearing to have been printed earlier than some other messages, but actually the other messages are just being printed late.

From within a C program you can also do something similar within the stdio system using freopen, which will effect the FILE *, so you could make fprintf(stderr, "fungus"); print to something besides what stderr normally would print to.

But if you want to know how to make a program redirect the actual file descriptors under a unix like system you need to learn about the dup and dup2 system calls. They allow you to duplicate a file descriptor.

int fd = open("some_file", O_WRONLY);
dup2(2,fd);
close(fd);

This code will make "some_file" the new stderr at the OS level. The dup2 call will close and replace file descriptor 2 (stderr, which is usually used by FILE * stderr but not necessarily if you call freopen(x,y,stderr) since that may make FILE *stderr use a different file descriptor).

This is how shell programs redirect input and output of programs. The open all of the files that the new program will need, fork, then the child uses dup2 to set up the files descriptors for the new program, then it closes any files that the new program won't need (usually just leaving 0, 1, and 2 open), and then uses one of the exec functions to become the program that the shell was told to run. (some of this isn't entirely accurate because some shells may rely on close on exe flags)

nategoose