Обычно вместо перехвата SIGPIPE
его игнорируют, что приводит к сбою write
с EPIPE
вместо тихого завершения вашей программы.
Однако: Если вы получаете SIGPIPE
при записи в канал, не пытайтесь снова. Это никогда не сработает. SIGPIPE
означает, что у трубы нет считывателя - и если у трубы сейчас нет считывателя, у нее никогда не будет считывателя. (Подумайте об этом так: как труба без читателя получит ее? Это невозможно!)
Ваша проблема в том, что вы закрываете другой конец трубы. Исправьте это, и не беспокойтесь о SIGPIPE
. SIGPIPE
это только симптом.
Редактировать: Здесь есть два вопроса для ответа. Если вы не можете ответить на оба этих вопросов, не беспокойтесь о SIGPIPE
.
Что может заставить мою программу получить SIGPIPE
? Единственный способ получить SIGPIPE
- закрыть конец чтения канала. Это происходит, если происходит сбой процесса чтения или если он запрограммирован на закрытие канала. Если вы пишете сетевой сервер или общаетесь с неизвестным процессом, это может быть обычным явлением. Однако если вы пишете обе программы, обе работают локально, то это, вероятно, указывает на ошибку программирования.
Что бы сделала моя программа, когда она перехватит SIGPIPE
? Если вы пишете клиентский процесс, использующий канал для связи с сервером, то что вы должны делать с SIGPIPE
? Вы не можете повторить попытку, и клиенты обычно не могут перезапустить сервер, к которому они подключены. Просто сделайте разумную вещь по умолчанию и позвольте SIGPIPE
завершить вашу программу. Однако, если сервер отправляет данные клиенту, которым он управляет, и получает SIGPIPE
, он может перезапустить клиент. Но это может быть очень плохой идеей - например, если клиент является детерминированным, он просто снова потерпит крах, и вы получите бесконечный цикл, а не простой сбой.
Таким образом, общий принцип здесь " Только перехватывать ошибки, которые вы готовы обработать. " Не перехватывайте ошибки только ради полноты. Просто позвольте им аварийно завершить работу вашей программы или вызвать сбой операции, и вы сможете вернуться и отладить ее позже.
Фрагмент кода: Это фрагмент кода из одного из моих проектов. Если вы запустите его, SIGPIPE
не остановит ваш процесс. Вместо этого write
сгенерирует ошибку EPIPE
. Если вы пишете сетевой сервер, то EPIPE
- это один из возможных способов внезапного отключения клиента.
void
ignore_sigpipe(void)
{
struct sigaction act;
int r;
memset(&act, 0, sizeof(act));
act.sa_handler = SIG_IGN;
act.sa_flags = SA_RESTART;
r = sigaction(SIGPIPE, &act, NULL);
if (r)
err(1, "sigaction");
}