Что делать, если хвост не удается при чтении из трубы - PullRequest
3 голосов
/ 13 августа 2011

отличить стандартный вывод от стандартного на трубе

Итак, в связи с приведенной выше ссылкой, у меня есть ребенок, который выполняет tail, а родитель читает его через pipe.

dup2(pipefd[1], STDOUT_FILENO);
dup2(pipefd[1], STDERR_FILENO);

Мой вопрос: если каким-то образом tail не сработает, что произойдет с каналом, из которого я читаю? Я получаю что-нибудь на stderr? tail самоуничтожается? или это может зависать там как defunct?

Ответы [ 3 ]

2 голосов
/ 13 августа 2011

Ядро отправит сигнал SIGPIPE другому процессу в канале, когда tail завершится. Действие по умолчанию для этого сигнала (если не установлен обработчик) - завершить процесс.

Если вы не хотите иметь дело с сигналами, вы можете игнорировать SIGPIPE в родительском элементе (таким образом, он не завершается после завершения tail), и вместо этого проверить, является ли значение errno EPIPE после каждого read. Кроме того, вам придется позвонить wait или waitpid от родителя, чтобы пожинать зомби-ребенка.

1 голос
/ 14 августа 2011

Если tail завершится неудачно, любое чтение на конце чтения канала вернет EOF.Если хвост завершился неудачей, он уже завершился, определение «сбой» состоит в том, что он завершился с ненулевым статусом выхода.Он останется в таблице процессов (т. Е. «Несуществующий») до тех пор, пока его не будет ожидать родительский элемент.

Но почему у вас tail использует один и тот же канал для stderr и stdout?Почему бы просто не сделать две трубы?Кажется, что это устранит проблему различения двух выходных потоков.

1 голос
/ 13 августа 2011

вы не получите EPIPE при чтении, только запись вернет EPIPE.Вы получите EOF, обозначенное как чтение, возвращающее 0, и так как вы прочитаете stderr, вы также получите сообщение об ошибке (до EOF).

Процесс станет зомби, и вы можете использоватьwait / waitpid для получения статуса выхода, который будет ненулевым, если произошла ошибка.

...