0

I am building a simple shell in c using fork and execlp. I will be given a set of commands separated by pipes. eg: ls -l | wc -l .

I want to use pipes for intra process communication. So the output from ls -l is input for wc -l. There can any number of commands separated by pipes. I am not understanding whether to create a pipe between a child process and parent and then when I get a output from a child process somehow transfer that output to another child process... I have parsed the inputs. How can I go about this?

void excueteCommands() {

    int i, j;
    int fd[2];
    int cid1;

    commandNode* ptr = head;

    while (ptr != NULL) {

        for (i = 0; i <= pipeCount; i++) {

            cid1 = fork();

            if (!cid1) {

                if (i != 0) {

                    dup2(fd[i - 1][0], 0);
                }

                if (i != pipeCount) {

                    dup2(fd[i][1], 1);
                }

                for (j = 0; j < pipeCount; j++) {

                    close(fd[j][0]);
                    close(fd[j][1]);
                }

                execlp(ptr->command, ptr->args, NULL);
                exit(0);
            }

            ptr = ptr->next;
        }
    }

    for (i = 0; i < pipeCount; i++) {
        close(fd[i][0]);
        close(fd[i][1]);
    }

} 
jrdnsingh89
  • 215
  • 2
  • 7
  • 18
  • 1
    Check all those "Related" questions on the right of this page. Maybe some of them already cover what you are asking. – hyde Mar 02 '14 at 18:58

1 Answers1

0

I also had same assignment last year. Your need not to handle input and output from one process to another separately. Just initialize pipes between the series of processes and the flow of input and output would take place itself. You only need to give input to first command and take output from the last command.

Following is code snippet I used.

#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <sys/wait.h>

int exit_flag = 0;

#define ARG_SIZE 100



int main ()  
{

    int size = 1000,i,j;
    int pipe_count = 0;
    int fd[100][2],cid1,cid2,length,status;


    char string[][100] = {"ls","wc"};

    pipe_count = 1;

    if(pipe_count)
    {
        for(i = 0;i < pipe_count;i++)
        {
            pipe(fd[i]);
        }

        for(i = 0;i <= pipe_count;i++)
        {
            cid1 = fork();
            if(!cid1)
            {

                if(i!=0)
                {
                    dup2(fd[i-1][0],0);
                }


                if(i!=pipe_count)
                {
                    dup2(fd[i][1],1);
                }


                for(j = 0;j < pipe_count;j++)
                {   
                        close(fd[j][0]);
                        close(fd[j][1]);
                }

                execlp(string[i], string[i], NULL);
                exit(0);
            }


        }
        for(i = 0;i < pipe_count;i++)
        {
            close(fd[i][0]);
            close(fd[i][1]);
        }
        waitpid(cid1,&status,0);


    }
    else
    {
        execlp(string[0], string[0], NULL);
    }


    return 0;
}

In above code string[] array contains all commands separated by '|' in sequence. fd[][2] is array of file descriptors. fd[i][0] is input of i+1 command and fd[i][1] is output of ith command. So output of i goes to input of i+1 using fd[i] pipe.

I don't remember now how the dup2 and close commands were handled. May you may get them since you have done them recently. I there is any doubt then I would try my best to clarify.

Shashwat Kumar
  • 5,159
  • 2
  • 30
  • 66
  • can u explain ur code a little bit? I don't get how the n of these processes will talk to each other. N different commands.... – jrdnsingh89 Mar 02 '14 at 20:58
  • Do you know about dup2, close commands? – Shashwat Kumar Mar 02 '14 at 20:59
  • Yup I do know about them.. My problem is idk how to scale for n different commands – jrdnsingh89 Mar 02 '14 at 21:09
  • I have parsed the info and I have linkedlists of commands. I need to know how I can excuete them and use dup2 to get the final output to the main program. – jrdnsingh89 Mar 02 '14 at 21:09
  • If you want I can post of my parser code... – jrdnsingh89 Mar 02 '14 at 21:12
  • I have updated the answer with some description. Hope you find some hint. – Shashwat Kumar Mar 02 '14 at 21:21
  • Or you do this. Copy the code in your file. Put all your parsed commands in string[] array in sequence. Set pipecount equal to number of pipes in you command. call execlp in place of commandcall. – Shashwat Kumar Mar 02 '14 at 21:23
  • If I put all the parsed commands in an array, how will pass them to the execlp call... I confused is to why am I put the commands in an array. I am not seeing wht u r telling me... – jrdnsingh89 Mar 02 '14 at 22:32
  • I added the implementation as you suggested... there are some errors dup2(fd[i-1][0],0); close(fd[j][0]); subscripted values is neither an array nor a vector... – jrdnsingh89 Mar 02 '14 at 22:34
  • I have update the code according to your requirements. It is working on my system. Just replace string array by your commands variable. Make sure you use execlp properly. – Shashwat Kumar Mar 03 '14 at 05:55