труба popen () закрыта от других крайностей, убивает мою программу - PullRequest
1 голос
/ 28 февраля 2020

У меня есть труба, которую я открыл с FILE *telnet = popen("telnet server", "w". Если через некоторое время te lnet выходит из-за того, что сервер не найден, канал закрывается с другой стороны.

Тогда я бы ожидал какую-то ошибку, либо в вызовах fprintf(telnet, ...) или fflush(telnet), но вместо этого , моя программа внезапно умирает на fflush(telnet) без сообщения об ошибке. Это нормальное поведение? Почему это так?

1 Ответ

2 голосов
/ 28 февраля 2020

Преобразование (расширенные) комментарии в ответ.

Если вы пишете в канал, когда на другом конце канала нет процесса для чтения данные, вы получаете сигнал SIGPIPE, чтобы сообщить вам, и поведение по умолчанию для SIGPIPE - выход (без дампа ядра, но выход с предубеждением).

Если вы проверяете состояние выхода в оболочке, вам следует см. $? равно 141 (128 + SIGPIPE, что обычно равно 13).

Если вы не возражаете, что процесс завершается, вам ничего не нужно делать. В качестве альтернативы вы можете установить обработчик сигнала для SIGPIPE на SIG_IGN, и в этом случае ваша операция записи должна завершиться с ошибкой, а не завершать процесс. Или вы можете настроить более сложную обработку сигналов.

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

...