title: execvp() never finishes on pipe
body: <p>I am taking an OS course and writing a shell. And I encountered a problem about execvp() and pipe. The following code is a simplified version of the code where problem happens.<br/></p>
  
  <pre><code>static pid_t
  command_exec(command_t *cmd, int *pass_pipefd) //the function that executes commands. this function will be called multiple times if the input line contains multiple commands. Ex. "echo abc | cat"
  {
      pid_t pid = 0; //child pid
      int pipefd[2]; //array for pipe
      if(cmd-&gt;controlop == CMD_PIPE){
          //if the control operation of the command is pipe(to the left of a '|'), create a pipe
          pipe(pipefd);
      }
      pid = fork();
  if(pid==0){ //child branch
      dup2(*pass_pipefd,0);//redirect stdin to the pipe from last command
      if(strcmp(cmd-&gt;argv[0],"cd")){ //if the command is not cd
          if(cmd-&gt;controlop == CMD_PIPE){
              dup2(pipefd[1],1); 
              //if command's control operation is pipe(to the left of a '|'), redirect stdout to pipefd[1]
          }
          if(execvp(cmd-&gt;argv[0],cmd-&gt;argv)&lt;0)//execute the command,use stdin as input and stdout as output(but they may be redirected)
              printf("%s fails\n",arg[0]);
      }
      exit(0);
  }else{//if parent
      wait(NULL); //wait for the child
      if(cmd-&gt;controlop == CMD_PIPE){
          *pass_pipefd = pipefd[0];//if command's control operation is pipe(to the left of a '|'), set *pass_pipefd to the output of the pipe array.
          return pid;
      }
  }
  </code></pre>
  
  <p>If the input is "echo a", then the output is no problem. execvp() will finish and wait(NULL) in the parent will not wait forever. However if the input is "echo abc | cat", then "abc" will be output to the terminal but the program will be stuck. the cause is that the execvp() that executes "cat" never finishes so the wait(NULL) in parent waits forever.I know that execvp() doesn't return but it should eventually finish. I think I may mess up the stdin and stdout redirection things but I can't find the bug. </p>