redirecting output to a file in C

后端 未结 3 593
傲寒
傲寒 2020-12-06 03:10

i coded a basic shell in C for executing basic commands it\'ll execute commands ls, ls -al , ls -al | more etc.

i want to exec

相关标签:
3条回答
  • 2020-12-06 03:31

    Before you call execve(2) in the newly created process to execute the command, you can redirect its standard input or output via the dup2(2) system call:

    /* redirect stdout to a file */
    dup2(1, some_open_file_descriptor);
    

    Of course, you need to have some error handling.

    0 讨论(0)
  • 2020-12-06 03:32

    Don't use pipe when the output is to go to a file.

    When you fork the child to run the ls command, you note the redirection, and open the file; you then use dup2() (or close() and dup()) so that the file descriptor is now standard output for the child; you close the duplicated file descriptor - the one returned by open(); then you execute ls as usual; its standard output is now sent to the file.

    Note that you do the non-pipe I/O redirection after forking, not before. Pipes have to be set up before forking, but other I/O redirection does not.

    0 讨论(0)
  • 2020-12-06 03:34

    This is the result of my testing things out with dup2

    The more subtle point is remembering fflush at the right times :) Otherwise, you'll get very surprising results.

    Also, prefer fileno instead of hardcoding 1 (stdout) 2 (stderr).

    Redirecting stdin was left as an exercise for the reader

    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    int main(int argc, const char *argv[])
    {
        int out = open("cout.log", O_RDWR|O_CREAT|O_APPEND, 0600);
        if (-1 == out) { perror("opening cout.log"); return 255; }
    
        int err = open("cerr.log", O_RDWR|O_CREAT|O_APPEND, 0600);
        if (-1 == err) { perror("opening cerr.log"); return 255; }
    
        int save_out = dup(fileno(stdout));
        int save_err = dup(fileno(stderr));
    
        if (-1 == dup2(out, fileno(stdout))) { perror("cannot redirect stdout"); return 255; }
        if (-1 == dup2(err, fileno(stderr))) { perror("cannot redirect stderr"); return 255; }
    
        puts("doing an ls or something now");
    
        fflush(stdout); close(out);
        fflush(stderr); close(err);
    
        dup2(save_out, fileno(stdout));
        dup2(save_err, fileno(stderr));
    
        close(save_out);
        close(save_err);
    
        puts("back to normal output");
    
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题