tags:

views:

325

answers:

3

I have to capture the stdout in a program and write that into a file...so I created a pipe. In the parent process, I captured the stdout in the pipe using dup() and I need to get this into a file...so I did a dup() in the child to get the captured file descriptor into the stdin. Now, how do I write this stdin into a file using fwrite()?

A: 

You should capture into a byte or char buffer and the send that ot the fwrite. When I say a buffer I mean an array or dynamically allocated block of bytes/chars.

FernandoZ
+2  A: 

Isn't that doing things the hard way? All you need to do in the parent is use freopen() to connect stdout to the file of your choosing.

FILE *fp = freopen("/tmp/mylogfile", "w", stdout);

if (fp == 0)
    error("...something went wrong opening the log file...\n");

The direct answer to your question is:

char buffer[32768];
ssize_t nbytes;
FILE *fp = fopen("/tmp/mylogfile", "w");

if (fp == 0)
    error("....something went wrong opening my log file...\n");

while ((nbytes = fread(buffer, sizeof(char), sizeof(buffer), stdin)) > 0)
    if (fwrite(buffer, sizeof(char), nbytes, fp) != nbytes)
        error("...something went wrong writing to standard output...\n");

However, this is hardly necessary. You can improve the error handling in all sorts of ways; I'm simply assuming that 'error()' reports a message and does not return.

Jonathan Leffler
yeah but this was just a way to learn C...i am trying to learn to use pipes.
sfactor
OK - it would do no harm to mention that; it excuses sub-optimal techniques for doing things. I've given the direct answer already. But if I'm using pipes as pipes, rather than coincidentally using file streams that happen to be connected to pipes, I'd be using file descriptor I/O calls (such as read() and write()) and not file stream I/O calls such as fread() and fwrite().
Jonathan Leffler
The main thing to remember with pipes, especially when using dup(), is to close the unused ends of the pipes. If you don't, things don't terminate properly.
Jonathan Leffler
+1  A: 

The easiest way is just to open the file and provide that as the child's stdout:

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

#include <stdio.h>

int main() {
  pid_t pid = fork();
  switch (pid) {
  case -1:
    perror("fork");
    return 1;

  case 0:;
    int new_out = open("output.txt", O_WRONLY | O_CREAT, 0666);
    if (new_out == -1) {
      perror("open");
      return 1;
    }
    if (dup2(new_out, 1) == -1) {
      perror("dup2");
      return 1;
    }
    char* args[] = {"/bin/echo", "test output", 0};
    execv(args[0], args);
    perror("exec");
    return 1;

  default:;
    int s;
    if (waitpid(pid, &s, 0) == -1) {
      perror("waitpid");
      return 1;
    }
    if (WIFEXITED(s)) {
      return WEXITSTATUS(s);
    }
    return 1;
  }
}
Roger Pate