ILL_ILLADR — Недопустимый режим адресации
ILL_ILLOPC — Недопустимый код операции
ILL_ILLOPN — Недопустимый операнд
ILL_ILLTRP — Недопустимая ловушка
ILL_PRVOPC — Привилегированный код операции
ILL_PRVREG — Привилегированный регистр
SIGPOLL/SIGIO
POLL_ERR — Ошибка ввода-вывода
POLL_HUP — Устройство отключено
POLL_IN — Доступны данные ввода
POLL_MSG — Доступно сообщение ввода
POLL_OUT — Доступны буферы вывода
POLL_PRI — Доступен высокоприоритетный ввод
SIGSEGV
SEGV_ACCERR — Нарушение прав доступа к странице памяти
SEGV_MAPERR — Искомый адрес незадействован
SIGTRAP
TRAP_BRANCH — Ловушка ветвления процессов
TRAP_BRKPT — Точка останова процесса
TRAP_HWBKPT — Аппаратная точка остановки/наблюдения процесса
TRAP_TRACE — Ловушка трассировки процесса
Стандартом SUSv4 определяется функция psiginfo(), предназначение которой аналогично функции psignal() (раздел 20.8). Функция psiginfo() принимает два аргумента: указатель на структуру siginfo_t и строку сообщения. Функция распечатывает строку сообщения при возникновении стандартной ошибки, а также дополнительную информацию о сигнале, описываемом в структуре siginfo_t. Функция psiginfo() предоставляется в библиотеке glibc, начиная с версии 2.10. Реализация из библиотеки glibc распечатывает описание сигнала, место происхождения сигнала (в соответствии со значением поля si_code), а также, для некоторых сигналов, содержимое других полей структуры siginfo_t. Функция psiginfo() — это нововведение стандарта SUSv4, поэтому она может доступной не во всех системах.
Последний аргумент, передаваемый обработчику, установленному с флагом SA_SIGINFO, ucontext, — это указатель на структуру типа ucontext_t (определена в файле
Еще один вариант применения структур ucontext_t — это функции getcontext(), makecontext(), setcontext(), и swapcontext(), позволяющие процессу соответственно получать, создавать, изменять или заменять контексты выполнения. (Эти операции аналогичны функциям setjump() и longjump(), но менее специфичны.) Эти функции могут применяться для реализации сопрограмм (coroutine), когда поток выполнения переключается между двумя (или более) функциями. В SUSv3 эти функции указаны, но отмечены как устаревшие. Из стандарта SUSv4 эти функции изъяты с указанием, что приложения должны быть переписаны с использованием потоков POSIX. Более подробная информация об этих функциях содержится в справочнике glibc.
Рассмотрим следующий сценарий.
1. Мы устанавливаем обработчик некоего сигнала.
2. С устройства терминала мы совершаем блокирующий системный вызов, например, read(), который блокируется до момента предоставления ввода.
3. Пока системный вызов заблокирован, осуществляется доставка сигнала, для которого мы установили обработчик, и, соответственно, активация обработчика этого сигнала.
Что случится после возврата из обработчика сигнала? По умолчанию, системный вызов завершается неудачно с ошибкой EINTR («Функция прервана»). Это может быть полезной особенностью. В разделе 23.3 мы рассмотрим, как использовать таймер (результатом чего будет доставка сигнала SIGALRM) для установки тайм-аута блокирующих системных вызовов, таких как read().
Однако зачастую мы предпочли бы продолжить выполнение прерванного системного вызова. Для этого мы можем воспользоваться кодом, например приведенным ниже, позволяющим вручную перезапустить системный вызов, если он был прерван обработчиком сигнала:
while ((cnt = read(fd, buf, BUF_SIZE)) == –1 && errno == EINTR)
continue; /* Тело цикла без действий */
if (cnt == –1) /* read() завершился с ошибкой, не равной EINTR */
errExit("read");
Если мы часто пишем такой код, то может быть удобно определить некий макрос, например, так:
#define NO_EINTR(stmt) while ((stmt) == –1 && errno == EINTR);
С его помощью мы можем переписать ранее упомянутый вызов read():
NO_EINTR(cnt = read(fd, buf, BUF_SIZE));