Passing data from one pipe to another

Viewed 39

I am new to pipes but how do I redirect the output from child_1 to the input for child_2?

I am trying to pass the value from the parent to child_1, adds 1 to the value, print the value, then use that output and pass it into child_2, add 1 again, and finally print the value.

The code below has the right output value for child_1, but not for child_2, how do I redirect the output from child_1 to the input for child_2?

Here is my code so far:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main(int argc, char * argv[]) {
    int fd[2];
    int PID;

    pipe(fd); //fd1[0] = read | fd1[1] = write

    PID = fork(); // spawn child_1

    if (PID < 0){ // failed to fork
        perror("Unable to fork child");
        exit(1);
    }


    if (PID > 0) { // parent
        int value = 100;
        
        // since parent is only writing, close the reading end of pipe
        close(fd[0]);
        // write the data to the write end of the pipe
        write(fd[1], &value,  sizeof(int));
        // then close the writing end of the pipe (parent)
        close(fd[1]);

/**********************************************************/
    } else { // child 1
        int val = 0;

        // read from the parent pipe
        read(fd[0], &val, sizeof(int));
        val += 1;
 
        // is this how to redirect from one pipe to another?
        dup2(fd[0], fd[1]);

        // this prints the right value for val (val [101] = value [100] + 1)
        printf("Child [%d] read value %d\n", getpid(), val);

        // close the reading end of the pipe for child_1
        close(fd[0]);


        int PID2 = fork();  // make child 2

        if(PID2 == 0) { // child 2
            int val2 = 0;  

            close(0); // close stdin since we are trying to take the value from child_1

            // read input from child_1 pipe (NOT WORKING?)
            read(fd[0], &val2, sizeof(int));
            val2 += 1;

            printf("Child [%d] out %d\n", getpid(), val2);

            close(fd[0]);
        }
    }

    return EXIT_SUCCESS;
}
1 Answers

The way you have things set up, there's no need to use dup2() or any other I/O redirection.

  • Add #include <unistd.h> to the list of include files (and remove #include <string.h> — it seems to be unused)
  • Delete: dup2(fd[0], fd[1]);
  • Delete: close(fd[0]);
  • Delete: close(0);
  • Before the second fork(), add write(fd[1], &val, sizeof(val));

When you have close(fd[0]) in the first child, you effectively close fd[0] for the second child too.

You should check the status of the read and write operations before using the results.

Those changes lead to:

/* SO 7383-1815 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    int fd[2];
    int PID;

    pipe(fd);

    PID = fork();

    if (PID < 0)
    {
        perror("Unable to fork child");
        exit(EXIT_FAILURE);
    }

    if (PID > 0)
    {
        int value = 100;
        close(fd[0]);
        write(fd[1], &value,  sizeof(int));
        close(fd[1]);
    }
    else
    {
        int val = 0;

        if (read(fd[0], &val, sizeof(val)) != sizeof(val))
        {
            perror("read() failed in child 1");
            exit(EXIT_FAILURE);
        }
        val += 1;
        printf("Child [%d] read value %d\n", getpid(), val);

        if (write(fd[1], &val, sizeof(val)) != sizeof(val))
        {
            perror("write() failed in child 1");
            exit(EXIT_FAILURE);
        }

        int PID2 = fork();

        if (PID2 == 0)
        {
            int val2 = 0;
            if (read(fd[0], &val2, sizeof(val2)) != sizeof(val2))
            {
                perror("read() failed in child 2");
                exit(EXIT_FAILURE);
            }
            val2 += 1;
            printf("Child [%d] out %d\n", getpid(), val2);
            close(fd[0]);
            close(fd[1]);
        }
    }

    return EXIT_SUCCESS;
}

When compiled (cleanly with options set fussy), it produces output such as:

Child [34520] read value 101
Child [34521] out 102

I believe this is what was wanted.

Related