Проблема перенаправления трубы Fork-exec

Может ли кто-нибудь сказать мне, что не так с этим кодом?

Таким образом, он создает входные и выходные каналы и программу sort forkexec. Родитель читает словарь /usr/share/dict/words и записывает его в канал, который является dup2() ‘d, для sort стандарту и, также, считывает вывод из него, печатает его на терминале (стандартный выход родителя). Или, по крайней мере, это то, что должно было произойти.

Обратный путь говорит, что родительский висит на строке read() в строке 130 (помечен комментарием «XXX»). Это pipeIn sort что sort не знает о конце файла, но закрытие конца записи pipeIn должно «сигнализировать» об этом, верно?

 #include  #include  #include  #include  #include  #include  #include  #include  int main(int argc, char** argv) { int pipeIn[2]; int pipeOut[2]; if ((pipe(pipeIn)) == -1) { perror("pipe"); exit(EXIT_FAILURE); } if ((pipe(pipeOut)) == -1) { perror("pipe"); exit(EXIT_FAILURE); } pid_t child = fork(); if (child == 0) { // This is child! if ((dup2(pipeIn[0], STDIN_FILENO)) == -1) { perror("dup2"); exit(EXIT_FAILURE); } if ((dup2(pipeOut[1], STDOUT_FILENO)) == -1) { perror("dup2"); exit(EXIT_FAILURE); } if ((dup2(pipeOut[1], STDERR_FILENO)) == -1) { perror("dup2"); exit(EXIT_FAILURE); } if ((close(pipeIn[0])) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((close(pipeOut[1])) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((execlp("sort", "-r", NULL)) == -1) { perror("execlp"); exit(EXIT_FAILURE); } } else if (child == -1) { perror("fork"); exit(EXIT_FAILURE); } else { // This is parent! if ((close(pipeIn[0])) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((close(pipeOut[1])) == -1) { perror("close"); exit(EXIT_FAILURE); } int dict = open("/usr/share/dict/words", O_RDONLY); if (dict == -1) { perror("open"); exit(EXIT_FAILURE); } char buf[1024]; int count; while ((count = read(dict, buf, sizeof(char) * 1024)) > 0) { putchar('.'); if ((write(pipeIn[1], buf, count)) == -1) { perror("write 1"); exit(EXIT_FAILURE); } } if (count == -1) { perror("read"); exit(EXIT_FAILURE); } if ((close(dict)) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((close(pipeIn[1])) == -1) { perror("close"); exit(EXIT_FAILURE); } while ((count = read(pipeOut[0], buf, sizeof(char) * 1024)) > 0) // XXX { putchar('!'); if ((write(STDOUT_FILENO, buf, count)) == -1) { perror("write 2"); exit(EXIT_FAILURE); } } if (count == -1) { perror("read"); exit(EXIT_FAILURE); } if ((close(pipeOut[0])) == -1) { perror("close"); exit(EXIT_FAILURE); } } return EXIT_SUCCESS; } эти #include  #include  #include  #include  #include  #include  #include  #include  int main(int argc, char** argv) { int pipeIn[2]; int pipeOut[2]; if ((pipe(pipeIn)) == -1) { perror("pipe"); exit(EXIT_FAILURE); } if ((pipe(pipeOut)) == -1) { perror("pipe"); exit(EXIT_FAILURE); } pid_t child = fork(); if (child == 0) { // This is child! if ((dup2(pipeIn[0], STDIN_FILENO)) == -1) { perror("dup2"); exit(EXIT_FAILURE); } if ((dup2(pipeOut[1], STDOUT_FILENO)) == -1) { perror("dup2"); exit(EXIT_FAILURE); } if ((dup2(pipeOut[1], STDERR_FILENO)) == -1) { perror("dup2"); exit(EXIT_FAILURE); } if ((close(pipeIn[0])) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((close(pipeOut[1])) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((execlp("sort", "-r", NULL)) == -1) { perror("execlp"); exit(EXIT_FAILURE); } } else if (child == -1) { perror("fork"); exit(EXIT_FAILURE); } else { // This is parent! if ((close(pipeIn[0])) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((close(pipeOut[1])) == -1) { perror("close"); exit(EXIT_FAILURE); } int dict = open("/usr/share/dict/words", O_RDONLY); if (dict == -1) { perror("open"); exit(EXIT_FAILURE); } char buf[1024]; int count; while ((count = read(dict, buf, sizeof(char) * 1024)) > 0) { putchar('.'); if ((write(pipeIn[1], buf, count)) == -1) { perror("write 1"); exit(EXIT_FAILURE); } } if (count == -1) { perror("read"); exit(EXIT_FAILURE); } if ((close(dict)) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((close(pipeIn[1])) == -1) { perror("close"); exit(EXIT_FAILURE); } while ((count = read(pipeOut[0], buf, sizeof(char) * 1024)) > 0) // XXX { putchar('!'); if ((write(STDOUT_FILENO, buf, count)) == -1) { perror("write 2"); exit(EXIT_FAILURE); } } if (count == -1) { perror("read"); exit(EXIT_FAILURE); } if ((close(pipeOut[0])) == -1) { perror("close"); exit(EXIT_FAILURE); } } return EXIT_SUCCESS; } имеют #include  #include  #include  #include  #include  #include  #include  #include  int main(int argc, char** argv) { int pipeIn[2]; int pipeOut[2]; if ((pipe(pipeIn)) == -1) { perror("pipe"); exit(EXIT_FAILURE); } if ((pipe(pipeOut)) == -1) { perror("pipe"); exit(EXIT_FAILURE); } pid_t child = fork(); if (child == 0) { // This is child! if ((dup2(pipeIn[0], STDIN_FILENO)) == -1) { perror("dup2"); exit(EXIT_FAILURE); } if ((dup2(pipeOut[1], STDOUT_FILENO)) == -1) { perror("dup2"); exit(EXIT_FAILURE); } if ((dup2(pipeOut[1], STDERR_FILENO)) == -1) { perror("dup2"); exit(EXIT_FAILURE); } if ((close(pipeIn[0])) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((close(pipeOut[1])) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((execlp("sort", "-r", NULL)) == -1) { perror("execlp"); exit(EXIT_FAILURE); } } else if (child == -1) { perror("fork"); exit(EXIT_FAILURE); } else { // This is parent! if ((close(pipeIn[0])) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((close(pipeOut[1])) == -1) { perror("close"); exit(EXIT_FAILURE); } int dict = open("/usr/share/dict/words", O_RDONLY); if (dict == -1) { perror("open"); exit(EXIT_FAILURE); } char buf[1024]; int count; while ((count = read(dict, buf, sizeof(char) * 1024)) > 0) { putchar('.'); if ((write(pipeIn[1], buf, count)) == -1) { perror("write 1"); exit(EXIT_FAILURE); } } if (count == -1) { perror("read"); exit(EXIT_FAILURE); } if ((close(dict)) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((close(pipeIn[1])) == -1) { perror("close"); exit(EXIT_FAILURE); } while ((count = read(pipeOut[0], buf, sizeof(char) * 1024)) > 0) // XXX { putchar('!'); if ((write(STDOUT_FILENO, buf, count)) == -1) { perror("write 2"); exit(EXIT_FAILURE); } } if (count == -1) { perror("read"); exit(EXIT_FAILURE); } if ((close(pipeOut[0])) == -1) { perror("close"); exit(EXIT_FAILURE); } } return EXIT_SUCCESS; } 

Благодарим вас за любой вклад (прошу прощения за каламбур).

Ваша проблема заключается в том, что вы не закрываете неиспользуемые концы своей трубы в процессе чили. Поэтому вам нужно добавить следующий код где-нибудь перед exec

  if ((close(pipeIn[1])) == -1) { perror("close"); exit(EXIT_FAILURE); } if ((close(pipeOut[0])) == -1) { perror("close"); exit(EXIT_FAILURE); }