Hi,

I'm trying to create a simple shell in C for Unix. I've been able to do all the parsing of commands and execution, but I'm having a problem with piping. I think the problem is that I'm not hooking into the correct pipe for the input of the second command.

For example, if I type "ls | wc", it will pause after the "wc" command, which I think is because its waiting for input. I think the problem is when I use dup2(reading,0), and its not hooking into the correct pipe.

I know this is a bit of a broad question, but if there are any pointers I could get, I would appreciate it. Here is the code that creates new processes and tries to pipe them.


int fileds[2];
        int reading[num_cmds];
        int writing[num_cmds];

        int p;
        for(p=0; p < num_cmds; p++)
        {
                reading[p] = -1;
                writing[p] = -1;
        }

        int j;
        for(j=0; j < num_cmds-1; j++)    //Create pipes for commands
        {
                int fileds[2];
                pipe(fileds);
                reading[j+1] = fileds[0];
                writing[j] = fileds[1];
        }

        int i = 0;
        for(i = 0; i < num_cmds;i++)
        {                       
                cmd_args = parse_cmd(cmds[i],output_file,input_file,&run_bg); //Get command and args

                pid_t childpid;
                int status;
                childpid=fork();

                if (childpid >= 0) 
                {
                        if (childpid == 0) 
                        {                               
                                if(writing[i] != -1)
                                {
                                        dup2(writing[i],1);
                                        close(writing[i]);
                                }

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

                                int h;
                                for(h = 0; h < num_cmds; h++)
                                {
                                        close(writing[h]);
                                        close(reading[h]);
                                }

                                if(execvp(cmd_args[0],cmd_args) == -1) 
                                {
                                        perror("Problem with command");
                                        exit(0);
                                }
                        }
                        else 
                        {
                                wait(&status);
                                int m;
                                for(m = 0; m < num_cmds; m++)
                                {
                                        if( writing[m] != -1) close(writing[m]);
                                        if( reading[m] != -1) close(reading[m]);
                                }
                        }
                }
                else 
                {
                         perror("fork"); 
                         continue;
                }


                input_file[0] = 0;
                output_file[0] = 0;
                run_bg = 0;
        }

}

I have this old piping program example...maybe you'll get something out of it.

Usage ./filename ps wc

will pipe the output of ps into wc

#include <unistd.h>

enum PIPES {READ, WRITE};

int main(int argc, char**argv)
{
	if (argv[2])
	{
		int hpipe[2];
		pipe(hpipe);

		if (fork())
		{
			close (hpipe[WRITE]);
			dup2 (hpipe[READ], 0);
			close (hpipe[READ]);
			execlp (argv[2],argv[2],NULL);
		}
		else
		{
			close (hpipe[READ]);
			dup2 (hpipe[WRITE], 1);
			close (hpipe[WRITE]);
			execlp (argv[1],argv[1],NULL);
		}
	}
	return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.