using dup,fork,exec communicate b/w process

what happens when ls -l | head -5 | wc is issued in shell. the shell creates processes and uses pipes between them to pass the output 2 other process. to implement this programmatically  we need to map the pipe to stdin/stdout .

1) create 2 pipes. say p1 and p2 .
2)create child process using fork . dup the write end of p1 with stdout and exec with ls -l
3)create other child process to receive ouput of ls -l here. we can do this by using dup with read end of p1 with stdin. to send output to wc again we need to dup write end of pipe p2 with stdout. exec with head -5 process
4)in parent process, receive the output from head -5 command. do this by using dup() on read end of pipe p2 with stdin and exec. output will be displayed on screen .


Program to implement  ls –l | head -5 | wc

#include
#include
#include
#include
#include

#include

#define MAXLEN 1024
  int main()
        {

        int p1[2],p2[2];
        int outfd,infd;int old_infd,old_outfd ; // save old descp
        int pid,pid2,pid3,flag;char str[MAXLEN];
        pipe(p1);

         if(pipe(p2) < 0)

        perror("cannot create pipe p2");
        outfd=p2[1];
        infd=p2[0];
        old_infd=dup(0); // save old descriptors
        old_outfd=dup(1);


        switch(pid=fork()) {
        case 0:
                close(1);dup(p1[1]);
                close(p1[0]);
                dup(p1[1]);
                execl("/usr/bin/ls","ls","-l",NULL);
                break;

        case -1:
                perror("cannot create process");
                break;
        default:
                sleep(2);
        }
        switch(pid3=fork()){
        case 0:
                close(0);
                dup(p1[0]);
                close(p1[0]); close(p1[1]);
                dup2(old_outfd,1);
                close(1);
                dup(outfd);
                close(infd); // close pipes
                close(outfd);
                execl("/usr/bin/head","head","-5",NULL);
                break;
        default:
                sleep(2);
                dup2(old_infd,0);
                close(0);
                dup(infd);
                close(outfd);close(infd);

                 execl("/usr/bin/wc","wc",NULL);

        }
        return 1;

        }

No comments: