tags:

views:

71

answers:

1
+1  Q: 

Trouble with dup2

After incorporating Ben Voigt's answer into the code, it appears to work

Original question:

I'm trying to use dup2 to:

  1. pass the output of "ls -al" as input to "grep foo",
  2. whose output becomes input for "grep bar",
  3. which finally outputs to stdout.

The final output is (blank), the file "in" is (blank) & the file "out" has the output of "ls -al".

Any ideas what could be happening?

int main()
{
    pid_t pid;
    int i;
    int inFileDes,outFileDes;   
    inFileDes=open("in",O_RDWR | O_CREAT,S_IRUSR | S_IWUSR); 
    outFileDes=open("out",O_RDWR | O_CREAT,S_IRUSR | S_IWUSR);  
    for(i=0;i<3;i++)
    {   
        if((pid=fork())==0)
        {
            switch(i)
            {
                case 0:
                dup2(outFileDes,1);
                execl("/bin/ls","ls","-al",0);
                break;
                case 1:
                                                  // originally:
                dup2(outFileDes,0);   // dup2(outFileDes,1);  
                dup2(inFileDes,1);    // dup2(inFileDes,0);

                execl("/bin/grep","grep","foo",0);   //lines having foo
                break;
                case 2:
                dup2(inFileDes,0);
                execl("/bin/grep","grep","bar",0);  //lines having foo & bar
                break;
            }
            exit(-1);  //in error   
        }
        waitpid(pid,NULL,0);
    }
    close(inFileDes);
    close(outFileDes);
    return(0);
}
+1  A: 

Your open call creates an empty file "in" and none of the programs write to it, so that's expected. Since both instances of grep read from an empty file, their output is also empty.

What you really want is to use the pipe function to get a pair of handles, which is written to be one program and read from by the next. You'll need to call it twice because you have two sets of connections between child processes.

Ben Voigt
Kedar Soparkar
That should solve your problem, although your files are named very badly. Using ordinary disk files requires running the steps sequentially, while using fifos (pipes) would allow the three programs to run simultaneously. With pipes, you'd still use `dup2` to associate the pipes with stdin and stdout of the child processes, `pipe` is an alternative to `open`.
Ben Voigt