Thread: Implementation of Shell -- Problem in multiple piping

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    3

    Implementation of Shell -- Problem in multiple piping

    Hey i have been trying to implement multiple piping in a shell but it is not working. Can anyone help me in finding out the problems.

    It is working properly if there is no pipe in the input command.

    here is the code that i have written so far:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <errno.h>
    #include <fcntl.h>
    
    
    
    
    int main(int argc, char *argv[])
    {
      
        int status, k = 0, count = 0;
        char input[512], *cmd, *sepcmd[256], *cm;
          pid_t pid;
      
        
        while (1) 
        {            
            printf("\nshell:");
            cmd = fgets (input, 512, stdin);  
            char *p = cmd;
        
            if (strchr(cmd, '|')) {    //pipe present in input command
                strsep(&p,"|");
            char ** arg;
            int fd[256][2];
            pipe(fd[k]);
            if (pipe(fd[k]) == -1)
                {
                       perror("pipe");
                }
            switch (fork())                     //executing first command
            {
                      case -1:
                     perror("fork"); exit(1);
                      case 0:
                close(fd[k][0]);
                dup2(fd[k][1],1);
                close(fd[k][1]);
                parseline(cmd, argv);
                execvp(argv[0], argv);
                perror("error");
                exit(1);
            }
            for(k=1; k<=count-2;k++)   //executing all commands except first and last
            {
                close(fd[k-1][1]);
                pipe(fd[k]);
                if (pipe(fd[k]) == -1)
                   {
                          perror("pipe");
                   }
                switch (fork())
                {
                          case -1:
                         perror("fork"); exit(1);
                          case 0:
                    close(fd[k][0]);
                    dup2(fd[k-1][0],0);
                    close(fd[k-1][0]);
                    dup2(fd[k][1],1);
                    close(fd[k][1]);
                      
                    parseline(cmd, argv);
                    execvp(argv[0], argv);
                    perror("error");
                    exit(1);
                }
            }
    
    
            k = count - 1;
              close(fd[k-1][1]);
              switch (fork())
              {
                   case -1:
                   perror("fork"); exit(1);
                   case 0:
                  close(fd[k][1]);
                  dup2(fd[k-1][0],0);
                  close(fd[k-1][0]);
                  parseline(cmd, argv);              
                  execvp(argv[0], argv);
                  perror("error");
                  exit(0);
              }    
    }
            else {                              //no pipe in input command
            
                parseline(cmd, argv);
                printf("%s\n", argv[0]);
    
    
                if(strcmp(argv[0], "exit") == 0) 
                {
                    exit(0);
                }
            
    
    
                   pid = fork();                    
                    if(pid == -1)                     
                    {
                          perror("child process creation failed");
                          exit(1);
                    } 
                    else if(pid == 0)                    
                    {  
                        if(execvp(argv[0], argv)<0)            
                        {
                               printf("command not found");
                          }
                    } 
                    else 
                    {  
                           wait(&status);                        
                    }    
            }
        }
    }
    
    
    int parseline(char *cmd, char**argv) {
        int argc =0; char *cmdprsr = " \n\t\r";
        for (argc = 0; argc < 100; argc++) 
        {
            if ((argv[argc] = strtok(cmd, cmdprsr)) == NULL)
            break;
            cmd = NULL;
        }
    }
    Last edited by ani_pwl; 10-22-2011 at 01:21 AM.

  2. #2
    Registered User
    Join Date
    Oct 2011
    Posts
    3
    is any one going to reply o this thread?

  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    I think we need more detail... what are you feeding this thing? What do you expect to happen?

  4. #4
    Registered User
    Join Date
    Oct 2011
    Posts
    3
    What the program should do is to take command from user and then execute it as it is done in shell. I am not implementing redirection feature now. But the command can have multiple pipes.

    'cmd' takes input from the user using fgets(). This command is parsed into tokens using parseline function defined in the end.

    Any other information you want?

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Yes, somebody will answer this question when we get to it. We volunteer our time for free. You posted at a time that is late on a Friday night, or mid-day Saturday for many of us. We do have lives outside cprogramming.com. Please be patient.

    You need to compile with warnings turned all the way up. The compiler should remind you that you need a prototype for parseline at the top of your program, and that parseline actually needs to return a value (the number of arguments seems like a good thing to return).

    Also, you keep modifying argv in main. That's the same argv that the shell gave you in the first place when your shell program was invoked. It's generally a very bad idea to go messing with it, especially since your program is invoked without options, and thus argv doesn't have a lot of working space. Try creating an array of char * or array of char arrays:
    Code:
    char foo[100][256];  // 100 tokens, up to 256 chars each
    // or
    char *foo[100];  // 100 tokens that you point to tokens, or that you allocate and copy into (free them when you're done)
    That's what I got at a first glance. Remember, work in small steps and test as you go so it's easier to track down your problem.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with piping in my simple UNIX shell
    By Integral Birth in forum C Programming
    Replies: 0
    Last Post: 11-28-2010, 07:37 PM
  2. Windows shell commands - multiple files
    By Magos in forum Tech Board
    Replies: 3
    Last Post: 02-28-2006, 01:56 AM
  3. programming unix shell piping problem
    By Kyro in forum Linux Programming
    Replies: 2
    Last Post: 08-28-2003, 07:52 AM
  4. Shell execute... but piping
    By nickname_changed in forum C++ Programming
    Replies: 2
    Last Post: 05-21-2003, 07:39 AM