LINUX.ORG.RU

SIGPIPE и write() на сокетах

 ,


1

1

Есть приложение (а точнее модуль), которое открывает tcp сокет и затем чередует запись и чтение из сокета. Есть ненулевая вероятность, что на той стороне в любой момент сокет может быть закрыт, соответственно при очередном write() есть вероятность получить sigpipe. Понятно что на sigpipe можно поставить обработчик или заигнорить его, но делать так в модуле плохо, потому как обработчик глобальный. Можно заюзать send() вместо write() с параметром MSG_NOSIGNAL. Кстати, насколько это переносимо?
А есть ли способы, оставив write() и не делая глобавльный обработчик, гарантировать, что приложение не свалится от SIGPIPE?
Схема работы такая:

  • открыть сокет
  • запись
  • чтение
  • запись
  • чтение
    ...

Можно заюзать send() вместо write() с параметром MSG_NOSIGNAL. Кстати, насколько это переносимо?

MSG_NOSIGNAL определён в posix с 2001 года.

Sorcerer ★★★★★
()
Ответ на: комментарий от Olegymous

Я совместимостью с виндой не интересуюсь, так что не знаю. Но в cygwin наверное есть.

Sorcerer ★★★★★
()

Я бы сделал обычным write. SIGPIPE пусть пользователь сам игнорирует.

Reset ★★★★★
()

и не делая глобавльный обработчик, гарантировать, что приложение не свалится от SIGPIPE?

немного оффтоп. Многие либы в доках пишут что они отрубают этот обработчик. И некоторые ЯП, в частности питон. В любом случае write() в закрытый сокет или пайп вернёт ошибку. Да select/poll наверняка покажут что на сокете была ошибка, так что не нужен этот SIGPIPE.

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

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

select/poll наверняка покажут что на сокете была ошибка, так что не нужен этот SIGPIPE.

Он может возникнуть после получения хорошего сокета из select'а, поэтому лучше или блокировать или говорить пользователю, чтоб блокировал. Например, boost::asio блокирует сам, libevent оставляет на усмотрение пользователя.

Reset ★★★★★
()
Ответ на: комментарий от true_admin

И некоторые ЯП, в частности питон.

Пару лет назад, встраивая питон в прогу, которая имела обработчик SIGPIPE, нарвался как раз на это неожиданное поведение (как-то ни разу в доке не заметил Варнинга, а что точно есть?).

gag ★★★★★
()
Ответ на: комментарий от Reset

select/poll наверняка покажут что на сокете была ошибка, так что не нужен этот SIGPIPE.

Он может возникнуть после получения хорошего сокета из select'а

Тоже хотел дать совет с select(). Но подумав, действительно выходит, что он для write() как-то бесполезен ввиду неатомарности для SOCK_STREAM (только ли?).

gag ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.