C Shell:程序挂在第一个孩子中

时间:2019-03-02 14:55:10

标签: c pipe dup2

我创建了一个C-shell,可以执行用户输入的命令。此Shell的要求之一是在处理管道调用时,第一个子管道将其输出通过pipe1定向到父管道,然后父管道读取输出并将其通过pipe2写入第二个子管道。我面临的问题是,输入带有管道的参数时,程序在第一个子进程中挂起,并且不执行该参数。

下面给出的代码段是负责执行管道命令的功能(我已经标记了它的挂起点):

void execPipeArgs(char** befPipe, char** aftPipe, int n_reads){

  pid_t child_1, child_2;
  int pipe1[2];  // Fd for pipe1
  int pipe2[2]; // Fd for pipe2

  // Create pipe1
  if(pipe(pipe1) < 0){
    printf("%s\n", "Failure! Pipe1 not created" );
    exit(0);
  }
  // Create pipe2
  if(pipe(pipe2) < 0){
    printf("%s\n", "Failure! Pipe2 not created" );
    exit(0);
  }

  // Create first Child
  child_1 = fork();

  // Check if fork successfull
  if(child_1  < 0){
    printf("%s\n", "ERROR! CHILD 1 NOT CREATED" );
    exit(0);
  }

  // In first child
  if(child_1 == 0){
      ***"THIS IS WHERE IT HANGS"***

      dup2(pipe1[1],1);
      close(pipe1[0]);
      close(pipe2[0]);
      close(pipe2[1]);

      if(execvp(befPipe[0],befPipe) < 0){
          printf("%s\n", "Command not executed in child_1" );
          exit(0);
      }
  }

  // In PARENT
  else {
      // Wait for child_1
      wait(NULL);

      int readCalls = 0;
      int charCount = 0;
      int bytesRead = 0;
      char* byteBuffer[500];
      close(pipe1[1]);

      //Get number of bytes, read/write calls
      while((bytesRead = read(pipe1[0],byteBuffer,n_reads)) != NULL){
        readCalls++;
        charCount = charCount + bytesRead;
        //write to pipe2
        write(pipe2[1],byteBuffer,bytesRead);
      }

      // Second Child
      child_2 = fork();

      // In child_2
      if(child_2 == 0){
        dup2(pipe2[0],0);
        close(pipe2[1]);
        close(pipe1[1]);
        close(pipe1[0]);

        if(execvp(aftPipe[0],aftPipe) < 0){
            printf("%s\n", "Command not executed in child_2" );
            exit(0);
        }
      } // if child_2 end
      else{
        // In Parent
        wait(NULL);
      }
  }
} // end of execArgsPipe

我在stackoverflow上发现了类似的问题,但是没有一种解决方案可以帮助我解决问题。最常见的答案是在我尝试过的适当位置关闭管道,但我的程序仍然挂起。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

您如何知道child_1挂起?是因为您尝试添加打印但在stdout上没有看到任何内容吗?根据dup2手册页,'dup2()使newfd成为oldfd的副本,并在必要时首先关闭newfd'。因此,child_1中的stdout现在是pipe1 [1]的副本。因此child_1内部的任何打印语句都不会显示在屏幕上。

您也可以查看以下链接: Pipe implementation stuck at dup2 command