Оболочка C: программа зависает у первого ребенка - PullRequest
0 голосов
/ 02 марта 2019

Я создал C-оболочку, которая выполняет команды, введенные пользователем.Одним из требований для этой оболочки является то, что при обработке вызовов канала первый дочерний элемент направляет его вывод родительскому элементу через 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 голосов
/ 02 марта 2019

Откуда вы знаете, что child_1 зависает?Это потому, что вы пытались добавить отпечатки, но ничего не видели на stdout?В соответствии с man-страницей dup2, 'dup2 () делает newfd копией oldfd, сначала закрывая newfd при необходимости' .Следовательно, stdout в child_1 теперь является копией pipe1 [1].Поэтому любые операторы печати внутри child_1 не будут отображаться на вашем экране.

Вы также можете проверить эту ссылку: Реализация конвейера застряла в команде dup2

...