'how to use pipe to connect two child process in C

I am self-studying an OS textbook and doing its homework:

Write a program that creates two children, and connects the standard output of one to the standard input of the other, using the pipe() system call.

then I try to write my code like this:


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
    printf("parent in pid: (%d)\n", (int)getpid());
    fflush(stdout);
    int p1[2], p2[2];
    pipe(p1);
     pipe(p2);
    
    char buff1[100];
    char buff2[100];
    int rc = fork();
    if (rc < 0)
    {
        fprintf(stderr, "fork failed");
        exit(1);
    }
    else if (rc == 0)
    {
        int fd = open("test1.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
        printf("%d\n", fd);
        printf("entering child1 process at pid : (%d)\n", (int)getpid());
        dup2(p1[0], STDIN_FILENO);
        dup2(p2[1], STDOUT_FILENO);
        int n = read(STDIN_FILENO, buff1, sizeof buff1);
        
        puts("this is a message from child 1");
        write(fd, buff1, n);
    }
    else
    {
        int rc2 = fork();
        if (rc2 == 0)
        {
            int fd2 = open("test2.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
            printf("%d\n", fd2);
            printf("entering child2 process at pid : (%d)\n", (int)getpid());
            dup2(p2[0], STDIN_FILENO);
            dup2(p1[1], STDOUT_FILENO);
            int n = read(STDIN_FILENO, buff2, sizeof buff2);
            
            puts("this is a message from child 2");
            write(fd2, buff2, n);
        }
        else
        {
            printf("final parent in pid: (%d)\n", (int)getpid());
        }
        
    }
    return 0;
}

if all went correctly. I should see messages from child1 or child2 in the txt files. But nothing happened when I run this code. But if I delete any one of the read statement like this:


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
    printf("parent in pid: (%d)\n", (int)getpid());
    fflush(stdout);
    int p1[2], p2[2];
    pipe(p1);
     pipe(p2);
    
    char buff1[100];
    char buff2[100];
    int rc = fork();
    if (rc < 0)
    {
        fprintf(stderr, "fork failed");
        exit(1);
    }
    else if (rc == 0)
    {
        int fd = open("test1.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
        printf("%d\n", fd);
        printf("entering child1 process at pid : (%d)\n", (int)getpid());
        dup2(p1[0], STDIN_FILENO);
        dup2(p2[1], STDOUT_FILENO);
        //int n = read(STDIN_FILENO, buff1, sizeof buff1);
        
        puts("this is a message from child 1");
        //write(fd, buff1, n);
    }
    else
    {
        int rc2 = fork();
        if (rc2 == 0)
        {
            int fd2 = open("test2.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
            printf("%d\n", fd2);
            printf("entering child2 process at pid : (%d)\n", (int)getpid());
            dup2(p2[0], STDIN_FILENO);
            dup2(p1[1], STDOUT_FILENO);
            int n = read(STDIN_FILENO, buff2, sizeof buff2);
            
            puts("this is a message from child 2");
            write(fd2, buff2, n);
        }
        else
        {
            printf("final parent in pid: (%d)\n", (int)getpid());
        }
        
    }
    return 0;
}

or like this


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
    printf("parent in pid: (%d)\n", (int)getpid());
    fflush(stdout);
    int p1[2], p2[2];
    pipe(p1);
     pipe(p2);
    
    char buff1[100];
    char buff2[100];
    int rc = fork();
    if (rc < 0)
    {
        fprintf(stderr, "fork failed");
        exit(1);
    }
    else if (rc == 0)
    {
        int fd = open("test1.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
        printf("%d\n", fd);
        printf("entering child1 process at pid : (%d)\n", (int)getpid());
        dup2(p1[0], STDIN_FILENO);
        dup2(p2[1], STDOUT_FILENO);
        int n = read(STDIN_FILENO, buff1, sizeof buff1);
        
        puts("this is a message from child 1");
        write(fd, buff1, n);
    }
    else
    {
        int rc2 = fork();
        if (rc2 == 0)
        {
            int fd2 = open("test2.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
            printf("%d\n", fd2);
            printf("entering child2 process at pid : (%d)\n", (int)getpid());
            dup2(p2[0], STDIN_FILENO);
            dup2(p1[1], STDOUT_FILENO);
            //int n = read(STDIN_FILENO, buff2, sizeof buff2);
            
            puts("this is a message from child 2");
            //write(fd2, buff2, n);
        }
        else
        {
            printf("final parent in pid: (%d)\n", (int)getpid());
        }
        
    }
    return 0;
}

I could see correct output in the txt file from both sides. I'm wondering what happened in my code and what went wrong in the first case?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source