CShell: 程序挂在第一个child

C Shell: Program hanging in first child

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

下面给出的代码片段是负责执行管道命令的函数(我已经标出了它挂起的地方):

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

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

如有任何帮助,我们将不胜感激。

你怎么知道 child_1 挂起的?是因为您曾尝试添加打印件但在标准输出上没有看到任何内容吗?根据 dup2 手册页,'dup2() makes newfd be the copy of oldfd, closing newfd first if necessary'。因此 child_1 中的标准输出现在是 pipe1[1] 的副本。因此 child_1 中的任何打印语句都不会显示在您的屏幕上。

您也可以查看此 link: