clinuxshellpipedup2

Execute the command " ls -l | grep ^d | wc " using dup2 and pipe()


#include<stdio.h>
#include<unistd.h>

int main()
{
    int fd1[2];
    pipe(fd1);

    if(!fork())
    {
        dup2(fd1[1],1);
        close(fd1[0]);
        execlp("ls" , "ls" ,"-l",(char*)0);
    }
    else{
        int fd2[2];
        pipe(fd2);
        dup2(fd1[0],0);
        close(fd1[1]);

        if(!fork()){
            dup2(fd2[0],0);
            close(fd2[0]);
            execlp("wc","wc",(char*)0);
        }
        else{
            dup2(fd2[1],1);
            close(fd2[0]);
            execlp("grep","grep","^d",(char*)0);
        }
    }
    return 0;
}

Trying to create a child process that will execute the ls -l command which then is passed from a pipe to the parent which reads from the pipe end instead of standard output and executes grep ^d command .

Some how i am not get the mistake why its not working but the reverse of it is working totally fine.

int main()
{
    int fd1[2];
    pipe(fd1);

    if(!fork())
    {
        dup2(fd1[1],1);
        close(fd1[0]);
        execlp("ls" , "ls" ,"-l",(char*)0);
    }
    else{
        int fd2[2];
        pipe(fd2);
        dup2(fd1[0],0);
        close(fd1[1]);

        if(!fork()){
            dup2(fd2[1],1);
            close(fd2[0]);
            execlp("grep","grep","^d",(char*)0);
        }
        else{
                dup2(fd2[0],0);
            close(fd2[1]);
            execlp("wc","wc",(char*)0);
        }
    }
    return 0;
}

Solution

  • The problem is you're not closing the FDs that you no longer need. For example, when your code executes wc, it leaves fd2[1] open, which means that it will never finish reading from its standard input. Close all of the ones you no longer need, such as by adding close(fd2[1]); before execlp("wc","wc",(char*)0); and it will start to work. Your second program only works by coincidence, because in it, the FDs that you forgot to close weren't as critical as they were in the first.