Safdari
Safdari

Reputation: 31

redirect stdout/stderr to function in C

I want to redirect stdout and stderr to a function and write a simple code. fprintf is ok but when i use printf without \r, stream passed to terminal!

#include <stdio.h>
static ssize_t file_write(void *c, const char *buf, size_t size)
{
  FILE * pFile;
  pFile = fopen ("output.txt","w");
  fprintf(pFile, "%s", buf);
  fclose (pFile);

return size;
}

void redirect()
{
  FILE *stream;
  stream=fopencookie(NULL, "w", (cookie_io_functions_t) {(ssize_t) 0,  file_write, 0, 0});
  setbuf(stdout, NULL);
  stdout = stream;
  setbuf(stderr, NULL);
  stderr = stream;
}

int main()
{
  redirect();
  fprintf(stderr,"1-stderr test\n");
  fprintf(stdout, "2-stdout test\n");
  printf("3-printf with r test\n\r");
  printf("4-printf without r test\n");

return 0;
}

file "output.txt":

1-stderr test
2-stdout test
3-printf with r test

Terminal output:

$ ./sample
4-printf without r test

Upvotes: 2

Views: 4491

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409482

You can't "redirect" standard input from, or standard output to a function in your program.

You can however create a pair of pipes and replace standard input and output with these pipes, and have another function (possibly in another thread or even a child process) use the other end of the pipes to communicate with the function.

You can of course use e.g. setvbuf to change the buffers of stdin and stdout to a pair of buffers you provide, then you can read directly from, or write directly to the buffers like any other memory buffer (i.e. array). Not that I recommend it though, it's frail and prone to errors.

However in this case it seems like what you want is that all writing to stdout should go to the file. In that case (like the use of pipes) there is no standard C way of handling it, but you need to use operating system specific functionality. Then if you're on a POSIX platform (like Linux or OSX) you can tell the operating system to duplicate the underlying file descriptor for your file, and say that STDOUT_FILNO (which is the file descriptor used for stdout) is a duplicate for the file descriptor of the file you opened. Then all writes to stdout will be written to your file. For this you need to use the dup2 system call.

Upvotes: 2

Related Questions