if (dup2(fd[0],0) == -1)
error("Dup2 failed in get_format()");
if (waitpid(pid, &status, 0) == -1)
error("Waitpid failed in get_format()");
while (fgets(line, LINE_LEN, stdin)) {
if (strstr(line, "(best)") != NULL)
dl_best(line, url);
}
Это распространенная ошибка при передаче по каналу от ребенка к родителю в C. С помощью этого кода дочерний процесс заполняет буфер канала и затем блокирует ожидание, пока родительский процесс опустошит канал, но родитель никогда не сделает этого, потому что он заблокирован в ожидании выхода дочернего элемента, поэтому вся программа будет заблокирована. (Вы не попадете в тупик для вызовов, когда полный вывод дочернего объекта меньше размера буфера канала. Возможно, поэтому он работает только для первого аргумента командной строки.) Вам необходимо прочитать все данные произведенный ребенком до вы ждете, когда ребенок прекратит свое существование. Для этой программы это так же просто, как перемещение waitpid
и его условное выражение ниже while
l oop.
Ваша повторная замена дескриптора файла 0 также может привести к нарушению правила C99, которое заканчивается -файл-это липкое состояние. (Это также может объяснить, почему он работает только для первого аргумента командной строки.) Вы могли бы решить эту проблему, вызвав clearerr
после dup2
, но было бы лучше не связываться с stdin совсем. Вместо этого используйте fdopen
, чтобы преобразовать fd[0]
в ФАЙЛ.
Соединяя оба этих исправления, ваш родительский код в get_format должен выглядеть примерно так:
} else { //parent
if (close(fd[1]) != 0)
error("Parent failed to close writing pipe");
FILE *fp = fdopen(fd[0], "rt");
if (!fp)
error("Parent failed to allocate a FILE");
while (fgets(line, LINE_LEN, fp)) {
if (strstr(line, "(best)") != NULL)
dl_best(line, url);
}
if (fclose(fp) != 0)
error("Parent failed to close reading pipe");
if (waitpid(pid, &status, 0) != pid)
error("Waitpid failed in get_format()");
}
(Обратите внимание, что fd[0]
закрывается вместе с fp
, с помощью fclose
; нет необходимости (на самом деле, это будет неправильно ) для вызова close
для него.)
Я бы также рассмотрел вопрос о том, чтобы dl_best
дочерний процесс мог работать асинхронно - то есть, чтобы dl_best
возвращал дочерний PID, а не ожидал его сам, а затем get_format
ждет обоих дети через некоторое время l oop - но это оптимизация, а не исправление.