1

I want to redirect the output of a program to a file. How can I do this? At the moment my file doesn't get created, I can only print the output to my console.

    int fd[2];
    int processId;
    int output;
    char filename[] = "output.txt";

    if((output = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR)) == -1){
        fprintf(stderr, "Unable to create/open file '%s'\n", filename);
        return 1;
    }

    if(pipe(fd) == -1){
        fprintf(stderr, "Error creating pipe\n");
        return 2;
    }

    if((processId = fork()) == -1){
        fprintf(stderr, "Error forking\n");
        return 3;
    }   

    if(processId == 0){
        int newFD = dup(STDOUT_FILENO);
        char newFileDescriptor[2];
        sprintf(newFileDescriptor, "%d", newFD);
        dup2(fd[1], output);
        close(fd[0]);
        execl("./pipetest", "pipetest", newFileDescriptor, NULL);
    }else{
        close(fd[1]);
        char c[10];
        int r = read(fd[0], c, sizeof(char) * 10);

        if(r > 0){
            fprintf(stderr, "PIPE INPUT = %s", c);
            fwrite(c, 1, sizeof(c), output);
        }
    }
3
  • You can either redirect simply using bash, or you could use freopen to redirect stdout inside your program. Commented Jan 20, 2016 at 19:22
  • The most glaring issue is you using 100 as your buffer to fwrite (the only correct parameter in that call seems to be the 1). Is there a reason why you're trying to do this with pipes instead of opening the file as fd 1 like a shell would? Commented Jan 20, 2016 at 19:22
  • Sorry, typing mistake, but also using this, it does not write to file. It is a task to use pipes. Commented Jan 20, 2016 at 19:26

4 Answers 4

5

A good start is not ignoring compiler warnings:

test.c: In function ‘main’:
test.c:42:13: warning: passing argument 4 of ‘fwrite’ makes pointer from integer without a cast [enabled by default]
             fwrite(c, 1, sizeof(c), output);
             ^
In file included from test.c:1:0:
/usr/include/stdio.h:715:15: note: expected ‘struct FILE * __restrict__’ but argument is of type ‘int’
 extern size_t fwrite (const void *__restrict __ptr, size_t __size,
               ^

int and FILE* are not interchangable. If you use open, write with write. If you use fopen, write with fwrite.

Additionally, you never modify stdout of your process. Instead you modify output, which doesn't make sense. Here are the minimum changes to your code to make it work:

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

int main() {                                                                                                                                                                                                                                                                                                                                                                                                                             
    int fd[2];                                                                                                                                                                                                                                                                                                                                                                                                                           
    int processId;                                                                                                                                                                                                                                                                                                                                                                                                                       
    int output;                                                                                                                                                                                                                                                                                                                                                                                                                          
    char filename[] = "output.txt";                                                                                                                                                                                                                                                                                                                                                                                                      

    if((output = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR)) == -1){                                                                                                                                                                                                                                                                                                                                                          
        fprintf(stderr, "Unable to create/open file '%s'\n", filename);                                                                                                                                                                                                                                                                                                                                                                  
        return 1;                                                                                                                                                                                                                                                                                                                                                                                                                        
    }                                                                                                                                                                                                                                                                                                                                                                                                                                    

    if(pipe(fd) == -1){                                                                                                                                                                                                                                                                                                                                                                                                                  
        fprintf(stderr, "Error creating pipe\n");                                                                                                                                                                                                                                                                                                                                                                                        
        return 2;                                                                                                                                                                                                                                                                                                                                                                                                                        
    }                                                                                                                                                                                                                                                                                                                                                                                                                                    

    if((processId = fork()) == -1){                                                                                                                                                                                                                                                                                                                                                                                                      
        fprintf(stderr, "Error forking\n");                                                                                                                                                                                                                                                                                                                                                                                              
        return 3;                                                                                                                                                                                                                                                                                                                                                                                                                        
    }                                                                                                                                                                                                                                                                                                                                                                                                                                    

    if(processId == 0){                                                                                                                                                                                                                                                                                                                                                                                                                  
        int newFD = dup(STDOUT_FILENO);                                                                                                                                                                                                                                                                                                                                                                                                  
        char newFileDescriptor[2];                                                                                                                                                                                                                                                                                                                                                                                                       
        sprintf(newFileDescriptor, "%d", newFD);                                                                                                                                                                                                                                                                                                                                                                                         
        dup2(fd[1], STDOUT_FILENO); // You want to modify STDOUT_FILENO                                                                                                                                                                                                                                                                                                                                                                  
        close(fd[0]);                                                                                                                                                                                                                                                                                                                                                                                                                    
        execl("/bin/echo", "echo", newFileDescriptor, NULL); // switched to echo                                                                                                                                                                                                                                                                                                                                                         
    }else{                                                                                                                                                                                                                                                                                                                                                                                                                               
        close(fd[1]);                                                                                                                                                                                                                                                                                                                                                                                                                    
        char c[10];                                                                                                                                                                                                                                                                                                                                                                                                                      
        int r = read(fd[0], c, sizeof(char) * 10);                                                                                                                                                                                                                                                                                                                                                                                       

        if(r > 0){                                                                                                                                                                                                                                                                                                                                                                                                                       
            fprintf(stderr, "PIPE INPUT = %s", c);                                                                                                                                                                                                                                                                                                                                                                                       
            write(output, c, r); // use write instead of fwrite                                                                                                                                                                                                                                                                                                                                                                          
        }                                                                                                                                                                                                                                                                                                                                                                                                                                
    }                                                                                                                                                                                                                                                                                                                                                                                                                                    
}                                                                                                                                                                                                                                                                                                                                                                                                                                        

Here's the result of running it:

$ gcc test.c -o test
$ ./test
PIPE INPUT = 6
$ cat output.txt 
6
Sign up to request clarification or add additional context in comments.

Comments

1

The easiest way is to do this at the bash by calling:

./myprogram > output.txt

This will redirect all of the outputs to output.txt

4 Comments

I'm creating a program that should do what the ">" does. Not use it.
@OlarAndrei, it sounds like what your want is simply to write all of your output routines with fprintf (fp, "...."); Then in your code, if you read > (or >>) as input, use fopen or freopen with the appropriate mode and take the file name as the next input following > or >>. (or stdout by default).
./pipetest has two printf() which I want to redirect to a file and not to my stdout.
1

You can use freopen, it's probably the simplest way:

if (!freopen("out.txt", "w", stdout))
{
    // failed to open the file stream, handle the error
}

You can then just use printf to write to that file. You can do the same with stderr, but that's probably a bad idea - by definition stderr is used to report errors, and from what I know the convention is to have it output to console.

Comments

0

Here's simples example how to do this:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(void) {
    int out = open("/tmp/output.txt", O_WRONLY | O_CREAT, 0644);
    if (out == -1) {
        perror("open:");
        return -1;
    }
    int r;
    r = close(1); /* this closes stdout */
    if (r != 0) {
        perror("close:");
        return -1;
    }
    r = dup2(out, 1); /* this duplicates your file descriptor to stdout */
    if (r == -1) {
        perror("dup2:");
        return -1;
    }
    printf("this should go to the output file\n");
    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.