Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
/* Обработка прерываний и отсоединений. Упрощена для представления */static void sighandler(int sig) { signal(sig, SIG_IGN); /* Отныне этот сигнал игнорировать */ cleanup(); /* Очистка после себя */ signal(sig, SIG_DFL); /* Восстановление действия по умолчанию */ raise(sig); /* Повторно отправить сигнал */}Установка действия
SIG_IGNSIGINTcleanup()SIG_DFLraise()sort.c10.4.4. Системные вызовы, допускающие повторный запуск
Значение
EINTRerrnoread()write()void handler(int signal) { /* обработка сигналов */ }int main(int argc, char **argv) { signal(SIGINT, handler); ... while ((count = read(fd, buf, sizeof buf)) > 0) { /* Обработка буфера */ } if (count == 0) /* конец файла, очистка и т.п. */ else if (count == -1) /* ошибка */ ...}Предположим, что система успешно прочла (и заполнила) часть буфера, когда возник
SIGINTread()handler()read()read()В былые времена (V7, более ранние системы System V)
read()errnoEINTRМедленные устройства
«Медленное устройство» является в сущности терминалом или почти всяким другим устройством, кроме обычного файла. В этом случае
read()EINTRread()Обычные файлы
Системный вызов был бы запущен повторно В этом случае
read()Поведение BSD несомненно полезно; вы всегда можете сказать, сколько данных было прочитано.
Поведение POSIX сходно, но не идентично первоначальному поведению BSD. POSIX указывает, что
read()EINTRВ противном случае, если сигнал прерывает частично выполненную
read()read()sigaction()10.4.4.1. Пример: GNU Coreutils
safe_read()safe_write()Для обработки случая EINTR в традиционных системах GNU Coreutils использует две функции,
safe_read()safe_write()lib/safe-read.c1 /* Интерфейс read и write для .повторных запусков после прерываний.2 Copyright (С) 1993, 1994, 1998, 2002 Free Software Foundation, Inc. /* ... куча шаблонного материала опущена... */5657 #ifdef SAFE_WRITE58 # include "safe-write.h"59 # define safe_rw safe_write /* Создание safe_write() */60 # define rw write /* Использование системного вызова write() */61 #else62 # include "safe-read.h"63 # define safe_rw safe_read /* Создание safe_read() */64 # define rw read /* Использование системного вызова read() */65 # undef const66 # define const /* пусто */67 #endif6869 /* Прочесть (записать) вплоть до COUNT байтов в BUF из(в) дескриптора FD, повторно запуская вызов при