How to use dup and or dup2 to redirect standard out into a pipe, then out to antoher pipe and then back out to standard out?
<p>Ok guys, there are a billion demos relating to dup, dup2, fcntl, pipe and all kinds of stuff that are wonderful when multiple processes exist.  However, I have yet to see one very basic thing that I think will help explain the behavior of pipe and its relationship to standard out and in. </p>

<p>My goal is to simply (in the same process) reroute standard output through a pipe back to standard output directly.  I have already accomplished this
with intermediate stages which redirect the pipe output to a file or write into a buffer... and then put standard output back to where it started.  At that point, of course I can write the buffer back to stdout, but I don't want to do this.  </p>

<p>Since I moved standard output to another location in the file table, I'd like to direct the output of the pipe to feed directly into the new standard output position and have it print like it normally would. </p>

<p>I feel like there is some kind of layer surrounding the file table that I am not understanding. </p>

<pre><code>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;unistd.h&gt;
#include &lt;fcntl.h&gt;

int main() {
    int pipeEnds_arr1[2];

    char str1[] = "STRING TO FEED INTO PIPE \n"; // make a string array

    pipe(pipeEnds_arr1);

    printf("File Descriptor for pipe ends from array\nPOSITION out  0 : %d\nPOSITION in 1 : %d\n", pipeEnds_arr1[0], pipeEnds_arr1[1]);


    /* now my goal is to shift the input of the pipe into the position of 
     * standard output, so that the print command feeds the pipe, then I 
     * would like to redirect the other end of the pipe to standard out. 
     */

    int someInt = dup(1); // duplicates stdout to next available file table position

    printf ("Some Int FD: %d\n", someInt); // print out the fd for someInt just for knowing where it is

    /* This is the problem area.  The out end of the pipe never 
     * makes it back to std out, and I see no way to do so.  
     * Stdout should be in the file table position 5, but when 
     * I dup2 the output end of the pipe into this position , 
     * I believe I am actually overwriting std out completely.  
     * But I don't want to overwrite it, i want to feed the output
     * of the pipe into std out. I think I am fundamentally 
     * misunderstanding this issue. 
     */

    dup2(pipeEnds_arr1[1], 1); //put input end of pipe into std out position
    //dup2(pipeEnds_arr1[0], 5); // this will not work
    //and other tests I have conducted do not work


    printf("File Descriptor for pipe ends from array\nPOSITION out  0 : %d\nPOSITION in 1 : %d\n", pipeEnds_arr1[0], pipeEnds_arr1[1]);

    fflush(stdout);

    close(pipeEnds_arr1[0]);
    close(pipeEnds_arr1[1]);

    return 0;
}
</code></pre>

<p>EDIT*********
OK, what I know is that somehow std out takes information from commands like printf and then routs it into a buffer that is then flushed to the shell.</p>

<p>What I believe is that there must be a way to rout the "read" or output end of the pipe to that same buffer that then gets to the shell. I have figured out how to rout the pipe output into a string, and then I can do as I please.  In the example code I post below, I will first rout the pipe out to a string and then open a file and write the string to the open file descriptor of that file...</p>

<pre><code>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;unistd.h&gt;
#include &lt;fcntl.h&gt;


int main() {
    /*  Each pipe end array has to have 2 positions in it.  The array
     *  position represents the two pipe ends with the 0 index
     *  position representing the output of the pipe (the place you want
     *  read your data from), and 1 index position representing the
     *  input file descriptor of the pipe (the place you want to write
     *  your data).
     */
    int pipeEnds_arr1[2];

    char str1[] = "Hello, we are feeding this into the pipe that we are through stdout into a pipe and then reading from the pipe and then feeding that output into a file \n"; // make a string array

    /*  Here we want to actually do the pipe command. We feed it the array
     *  with the 2 positions in it which will now hold file descriptors
     *  attached to the current process which allow for input and output
     *  through the new pipe. At this point, we don't know what the
     *  exact file decriptors are, but we can look at them by printing
     */

    pipe(pipeEnds_arr1);
    printf("File Descriptor for pipe ends from array\nPOSITION out  0 : %d\nPOSITION in 1 : %d\n", pipeEnds_arr1[0], pipeEnds_arr1[1]);

    /* now my goal is to shift the input of the pipe into the position of 
     * standard output, so that the print command feeds the pipe, then we
     * will try to read from the pipe and redirect the output to the std 
     * or in this test case out to a file.
     */

    int someInt = dup(1); // we moved what was stdout into someInt;

    /* put the write end of the pipe in the old stdout position by
     * using dup2 so we will print directly into the pipe
     */
    dup2(pipeEnds_arr1[1], 1);

    /* this is where id like to re-rout the pipe back to stdout but
     * im obviously not understanding this correctly
     */
    //dup2(someInt, 3);

    /* since std out has now been replaced by the pipe write end, this
     * printf will print into the pipe
     */
    printf("%s", str1);


    /* now we read from the pipe into a new string we make */
    int n;
    char str2[strlen(str1)];
    n = read(pipeEnds_arr1[0], str2, sizeof(str2)-1);
    str2[n] = 0;

    /* open a file and then write into it from the output of the pipe 
     * that we saved into the str2
     */
    int fd = open("tmp.out", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    write(fd, str2, strlen(str2));


    /* not sure about these last commands and their relevance */
    fflush(stdout);
    close(pipeEnds_arr1[0]);
    close(pipeEnds_arr1[1]);
    close(fd);

    return 0;
}
</code></pre>