Rerouting stdin and stdout from C

前端 未结 8 1392
终归单人心
终归单人心 2020-11-22 12:15

I want to reopen the stdin and stdout (and perhaps stderr while I\'m at it) filehandles, so that future calls to printf()

相关标签:
8条回答
  • 2020-11-22 12:37
    freopen("/my/newstdin", "r", stdin);
    freopen("/my/newstdout", "w", stdout);
    freopen("/my/newstderr", "w", stderr);
    
    ... do your stuff
    
    freopen("/dev/stdin", "r", stdin);
    ...
    ...
    

    This peaks the needle on my round-peg-square-hole-o-meter, what are you trying to accomplish?

    Edit:

    Remember that stdin, stdout and stderr are file descriptors 0, 1 and 2 for every newly created process. freopen() should keep the same fd's, just assign new streams to them.

    So, a good way to ensure that this is actually doing what you want it to do would be:

    printf("Stdout is descriptor %d\n", fileno(stdout));
    freopen("/tmp/newstdout", "w", stdout);
    printf("Stdout is now /tmp/newstdout and hopefully still fd %d\n",
       fileno(stdout));
    freopen("/dev/stdout", "w", stdout);
    printf("Now we put it back, hopefully its still fd %d\n",
       fileno(stdout));
    

    I believe this is the expected behavior of freopen(), as you can see, you're still only using three file descriptors (and associated streams).

    This would override any shell redirection, as there would be nothing for the shell to redirect. However, its probably going to break pipes. You might want to be sure to set up a handler for SIGPIPE, in case your program finds itself on the blocking end of a pipe (not FIFO, pipe).

    So, ./your_program --stdout /tmp/stdout.txt --stderr /tmp/stderr.txt should be easily accomplished with freopen() and keeping the same actual file descriptors. What I don't understand is why you'd need to put them back once changing them? Surely, if someone passed either option, they would want it to persist until the program terminated?

    0 讨论(0)
  • 2020-11-22 12:39

    And in the meantime, there's a C source code library that will do all this for you, redirecting stdout or stderr. But the cool part is that it lets you assign as many callback functions as you want to the intercepted streams, allowing you then to very easily send a single message to multiple destinations, a DB, a text file, etc.

    On top of that, it makes it trivial to create new streams that look and behave the same as stdout and stderr, where you can redirect these new streams to multiple locations as well.

    look for U-Streams C library on *oogle.

    0 讨论(0)
  • 2020-11-22 12:45

    Why use freopen()? The C89 specification has the answer in one of the endnotes for the section on <stdio.h>:

    116. The primary use of the freopen function is to change the file associated with a standard text stream (stderr, stdin, or stdout), as those identifiers need not be modifiable lvalues to which the value returned by the fopen function may be assigned.

    freopen is commonly misused, e.g. stdin = freopen("newin", "r", stdin);. This is no more portable than fclose(stdin); stdin = fopen("newin", "r");. Both expressions attempt to assign to stdin, which is not guaranteed to be assignable.

    The right way to use freopen is to omit the assignment: freopen("newin", "r", stdin);

    0 讨论(0)
  • 2020-11-22 12:52

    This is the most readily available, handy and useful way to do

    freopen("dir","r",stdin);
    
    0 讨论(0)
  • 2020-11-22 12:54

    I think you're looking for something like freopen()

    0 讨论(0)
  • 2020-11-22 12:56

    This is a modified version of Tim Post's method; I used /dev/tty instead of /dev/stdout. I don't know why it doesn't work with stdout (which is a link to /proc/self/fd/1):

    freopen("log.txt","w",stdout);
    ...
    ...
    freopen("/dev/tty","w",stdout);
    

    By using /dev/tty the output is redirected to the terminal from where the app was launched.

    Hope this info is useful.

    0 讨论(0)
提交回复
热议问题