+ 1 К Грегу Хьюгиллу за то, что он направил мой мыслительный процесс в правильном направлении, чтобы найти ответ.
Реальная причина для SIGPIPE
в сокетах и трубах - это идиома / шаблон фильтра, который применяется к типичным операциям ввода-вывода в системах Unix.
Начиная с труб. Программы фильтрации, такие как grep, обычно записывают в STDOUT
и читают из STDIN
, что может быть перенаправлено оболочкой в канал. Например:
cat someVeryBigFile | grep foo | doSomeThingErrorProne
Оболочка, когда она разветвляется, а затем исполняет эти программы, вероятно, использует системный вызов dup2
для перенаправления STDIN
, STDOUT
и STDERR
на соответствующие каналы.
Поскольку программа-фильтр grep
не знает и не может знать, что ее выходные данные были перенаправлены, единственный способ заставить ее прекратить запись в сломанный канал, если doSomeThingErrorProne
падает, - с помощью сигнала, поскольку возвращаемые значения записей в STDOUT
редко, если вообще проверяются.
Аналогом с сокетами будет сервер inetd
, занимающий место оболочки.
В качестве примера я предполагаю, что вы могли бы превратить grep
в сетевой сервис, который работает через TCP
сокетов. Например, с inetd
, если вы хотите иметь сервер grep
на TCP
порту 8000, добавьте это к /etc/services
:
grep 8000/tcp # grep server
Затем добавьте это к /etc/inetd.conf
:
grep stream tcp nowait root /usr/bin/grep grep foo
Отправьте SIGHUP
на inetd
и подключитесь к порту 8000 с помощью telnet. Это должно вызвать inetd
для разветвления, дублировать сокет на STDIN
, STDOUT
и STDERR
и затем выполнить exec grep
с аргументом foo. Если вы начнете вводить строки в telnet, grep
отобразит те строки, которые содержат foo.
Теперь замените telnet на программу ticker
, которая, например, записывает поток биржевых котировок в реальном времени в STDOUT
и получает команды для STDIN
. Кто-то связывается с портом 8000 и набирает «start java», чтобы получить кавычки для Sun Microsystems. Затем они встают и идут на обед. Телнет необъяснимым образом вылетает. Если бы не было SIGPIPE
для отправки, то ticker
продолжал бы отправлять кавычки навсегда, никогда не зная, что процесс на другом конце завершился сбоем, и без необходимости тратить системные ресурсы.