2017-01-04 3 views
3

Я нашел этот фрагмент кода, используемый несколько раз (также аналогичный, где он используется open() вместо write()).Проверка, если errno! = EINTR: что это значит?

int c = write(fd, &v, sizeof(v)); 
if (c == -1 && errno != EINTR) { 
    perror("Write to output file"); 
    exit(EXIT_FAILURE); 
} 

Почему это проверяется, если && errno != EINTR здесь?

В поисках errno на человека я нашел следующий текст о EINTR, но даже если я посетил man 7 signal, не просветить меня.

EINTR Прерывание вызова функции (POSIX.1); см. сигнал (7).

+2

Вместо этого проверьте страницу руководства для 'write'. Он должен сказать вам, на что errno настроено на определенные ошибки. – Kevin

+1

Обратите внимание, что 'write()' возвращает 'ssize_t' и ** NOT **' int'. Они не одинаковы. –

+1

Спасибо вам всем! @AndrewHenle Я это знаю, я просто решил скопировать часть кода, как я ее нашел :) как вы думаете, я должен все время редактировать вопрос с 'ssize_t' вместо' int'? – Robb1

ответ

7

Многие системные вызовы будут сообщать код EINTR об ошибке, если сигнал произошел время системный вызов продолжался. На самом деле ошибка не происходила, об этом просто сообщается, потому что система не может автоматически возобновить системный вызов. Этот шаблон кодирования просто повторяет системный вызов, когда это происходит, чтобы игнорировать прерывание.

Например, это может произойти, если программа использует alarm() для запуска некоторого кода асинхронно, когда заканчивается таймер. Если время ожидания происходит во время вызова программы write(), мы просто хотим ее перезапустить.

1

Из man page на write:

вызов был прерван сигналом до того, данные были записаны

+0

Этот ответ на самом деле не достаточен; он не объясняет ситуации, при которых «EINTR» может (или, что более важно, не может) произойти. Я считаю последнее более важным, потому что неспособность понять, что это обычно не может случиться, является причиной бесконечного грузооборота. –

+0

@R .. * Этот ответ на самом деле не достаточен; он не объясняет ситуации, при которых «EINTR» может (или, что более важно, не может) произойти. Я считаю последнее более важным, потому что неспособность понять, что это обычно не может случиться, является причиной бесконечного грубого грубости. * Если вы не совершаете системные вызовы «грузовой культ», изменение чего-то вроде сигнальной маски процесса может нарушить вещи где угодно. Если вам нравится писать хрупкий код, который можно сломать чем-то совершенно не связанным, это ваш выбор. Но, пожалуйста, не охарактеризуйте надежный код как «грузило». –

+0

@AndrewHenle: Установка прерывания обработчика сигнала - это инвазивная и преднамеренная вещь, которую вы делаете, когда вы * хотите * к ошибке из блокировки системных вызовов, которые прерываются. Цикл повторения, когда это происходит, не имеет смысла вообще, только когда вы знаете, что действительно хотите этого поведения. –