title: Program crash in forking process with pipes
body: <p>I'm writing a basic shell for course homework that will find a command in the given list of paths, and execute the command. It is also meant to handle pipes.
  However, when I fork a child process, I get a "Write error : Broken Pipe" message in gdb, and the program terminates abruptly.</p>
  
  <p>I cannot seem to understand why this is happening, since I've been cautious about opening and closing correct pipes and process forking seems to work as desired. Can someone with more experience in C and unix programming please help me diagnose the problem? Is there something logically incorrect with my fork implementation / pipe implementation?</p>
  
  <pre><code>//commands is of the format {"ls -al", "more", NULL}
  //it represents commands connected by pipes, ex. ls -al | more
  char **commands = parseArgv(consoleinput, SPECIAL_CHARS[4]);
  
  int numcommands = 0;
  
  while( commands[numcommands]!=NULL )
  {
      numcommands++;
  }
  
  const int  numpipes = 2*(numcommands-1);
  
  int pipefds[numpipes];
  
  int i=0;
  for(i=0; i&lt;numpipes;i=i+2)
  {
      pipe(pipefds+i);
  }
  
  int pipe_w = 1;
  int pipe_r = pipe_w - 3;
  int curcommand = 0;
  
  while(curcommand &lt; numcommands)
  {
      if(pipe_w &lt; numpipes)
      {
          //open write end
          dup2(pipefds[pipe_w], 1);
      }
  
      if(pipe_r &gt; 0)
      {
          //open read end
          dup2(pipefds[pipe_r], 0);
      }
  
      for(i=0;i&lt;numpipes;i++) //close off all pipes
      {
          close(pipefds[i]);
      }
  
      //Parse current command and Arguments into format needed by execv
  
      char **argv = parseArgv(commands[curcommand], SPECIAL_CHARS[0]);
  
      //findpath() replaces argv[0], i.e. command name by its full path ex. ls by /bin/ls
      if(findPath(argv) == 0)
      {
          int child_pid = fork();
  
          //Program crashes after this point
          //Reason: /bin/ls: write error, broken pipe
  
          if(child_pid &lt; 0)
          {
              perror("fork error:");
          }
          else if(child_pid == 0)     //fork success
          {
              if(execv(argv[0], argv) == -1)
              {
                  perror("Bad command or filename:");
              }
  
          }
          else
          {
              int child_status;
              child_pid = waitpid(child_pid, &amp;child_status, 0);
              if(child_pid &lt; 0)
              {
                  perror("waitpid error:");
              }
          }
      }
      else
      {
          printf("Bad command or filename");
      }
      free(argv);
  
      curcommand++;
      pipe_w = pipe_w + 2;
      pipe_r = pipe_r + 2;
  }
  
  //int i=0;
  for(i=0;i&lt;numpipes;i++) //close off all pipes
  {
      close(pipefds[i]);
  }
  
  free(commands);
  </code></pre>