Добрый день.
background: есть самописный демон на OCaml. Слушает (select) сокет, отвечает на запросы. Раз в 10 минут сбрасывает резултьтаты работы в файл, что занимает порядка единиц секунд для миллиона записей.
Так вот, с этим и связана проблема: если во время этой операции подловить демона и сделать что-то типа
$ echo "status" | socat - UNIX-CONNECT:/path/to/socket
то демон
дописывает файл дампа,
возвращается на обработку реквестов,
получает из socket backlog'а коннект,
читает из него команду,
обрабатывает,
и пытается отправить ответ обратно.
Но к этому моменту он уже опоздал, клиентский коннект уже отвалился. И демон гибнет от SIGPIPE.
Это не проблема для "настоящих" клиентов, которые _всегда_ ждут ответа и не отваливаются пока его не получат. Но при помощи echo и socat демона можно при достаточном упорстве свалить, просто дождавшись момента сброса дампа.
Так вот, самое странное что конструкция
try
Unix.send client str 0 (String.length str) []
with
Unix_error (EPIPE,_,_) -> ()
Не отрабатывает. Не отрабатывает даже
with
_ -> ()
Т.е. очевидно не происходит возбуждения эксепшена, а сразу прилетает сигнал.
Выход из ситуации очевиден -- устанавливать обработчик сигнала SIGPIPE вокруг данного фрагмента кода в ignore, но как-то это странно.
Сталкивался ли кто-то из уважаемого собрания с чем-то подобным? И ошибка ли это в OCaml или так положено?