Чтение онлайн

ЖАНРЫ

Шрифт:

Структура

siginfo_t
определена в файле <siginfo.h> и включает следующие поля:

int si_signo
Номер сигнала
int si_errno
Номер ошибки
int si_code
Причина отправления сигнала

В поле

si_signo
хранится номер сигнала. Поле
si_code
имеет следующий смысл: если его значение меньше или равно нулю, значит сигнал был отправлен прикладным процессом, в этом случае структура
siginfo_t
содержит также следующие поля:

pid_t si_pid
Идентификатор процесса PID
uid_t si_uid
Идентификатор пользователя UID

которые адресуют процесс, пославший сигнал; если значение

si_code
больше нуля, то оно указывает на причину отправления сигнала. Список возможных значений
si_code
для некоторых сигналов, соответствующих полю
si_signo
, приведен в табл. 2.19

Таблица 2.19. Значения поля si_code структуры siginfo_t для некоторых сигналов

Значение поля
si_signo
Значение поля
si_code
Описание
SIGILL
Попытка выполнения недопустимой инструкции
ILL_ILLOPC
Недопустимый код операции (opcode)
ILL_ILLOPN
Недопустимый операнд
ILL_ADR
Недопустимый режим адресации
ILL_ILLTRP
Недопустимая ловушка (trap)
ILL_PRVOPC
Привилегированный код операции
ILL_PRVREG
Привилегированный регистр
ILL_COPROC
Ошибка сопроцессора
ILL_BADSTK
Ошибка внутреннего стека
SIGFPE
Особая ситуация операции с плавающей точкой
FPE_INTDIV
Целочисленное деление на ноль
FPE_INTOVF
Целочисленное переполнение
FPE_FLTDIV
Деление на ноль с плавающей точкой
FPE_FLTOVF
Переполнение с плавающей точкой
FPE_FLTUND
Потеря точности с плавающей точкой (underflow)
FPE_FLTRES
Неоднозначный результат операции с плавающей точкой
FPE_FLTINV
Недопустимая операция с плавающей точкой
FPE_FLTSUB
Индекс вне диапазона
SIGSEGV
Нарушение сегментации
SEGV_MAPPER
Адрес не отображается на объект
SEGV_ACCERR
Недостаточно прав на отображаемый объект
SIGBUS
Ошибка адресации
BUS_ADRALN
Недопустимое выравнивание адреса
BUS_ADRERR
Несуществующий физический адрес
BUS_OBJERR
Аппаратная ошибка, связанная с объектом
SIGTRAP
Ловушка
TRAP_BRKPT
Процессом достигнута точка останова
TRAP_TRACE
Ловушка трассирования процесса
SIGCHLD
Завершение выполнения дочернего процесса
CLD_EXITED
Дочерний процесс завершил выполнение
CLD_KILLED
Дочерний процесс был "убит"
CLD_DUMPED
Ненормальное завершение дочернего процесса
CLD_TRAPPED
Трассируемый дочерний процесс находится в ловушке
CLD_STOPPED
Выполнение дочернего процесса было остановлено
CLD_CONTINUED
Выполнение остановленного дочернего процесса было продолжено
SIGPOLL
Событие на опрашиваемом устройстве
POLL_IN
Поступили данные для ввода
POLL_OUT
Свободны буферы данных
POLL_MSG
Сообщение
ожидает ввода
POLL_ERR
Ошибка ввода/вывода
POLL_PRI
Высокоприоритетные данные ожидают ввода
POLL_HUP
Устройство отключено

Уже отмечалось, что при получении сигнала от пользовательского процесса структура

siginfo_t
содержит дополнительные поля (табл. 2.20).

Таблица 2.20. Дополнительные поля структуры siginfo_t

Значение поля
si_signo
Дополнительные поля Значение
SIGILL SIGFPE
caddr_t si_addr
Адрес недопустимой инструкции
SIGSEGV SIGBUS
caddr_t si_addr
Адрес недопустимой области памяти
SIGCHLD
pid_t si_pid
Идентификатор дочернего процесса
int si_status
Код возврата сигнала
SIGPOLL
long si_band
Ошибка канала (для модулей STREAMS)

Установить маску сигналов или получить текущую маску можно с помощью функции sigprocmask(2):

#include <signal.h>

int sigprocmask(int how, sigset_t *set, sigset_t *oset);

Маска сигналов изменяется в соответствии с аргументом

how
, который может принимать следующие значения:

SIG_BLOCK
Результирующая маска получится путем объединения текущей маски и набора
set
SIG_UNBLOCK
Сигналы набора
set
будут удалены из текущей маски
SIG_SETMASK
Текущая маска будет заменена на набор
set

Если указатель

set
равен
NULL
, то аргумент how игнорируется. Если аргумент
oset
не равен
NULL
, то в набор, адресованный этим аргументом, помещается текущая маска сигналов.

Функция sigpending(2) используется для получения набора заблокированных сигналов, ожидающих доставки:

#include <signal.h>

int sigpending(int how, sigset_t *set, sigset_t *oset);

Список сигналов, ожидающих доставки, возвращается в наборе, адресованном аргументом

set
.

Системный вызов sigsuspend(2) замещает текущую маску набором, адресованным аргументом

set
, и приостанавливает выполнение процесса до получения сигналов, диспозиция которых установлена либо на завершение выполнения процесса, либо на вызов функции-обработчика сигнала.

#include <signal.h>

int sigsuspend(const sigset_t *set);

При получении сигнала, завершающего выполнение процесса, возврата из функции sigsuspend(2) не происходит. Если же диспозиция полученного сигнала установлена на вызов функции-обработчика, возврат из sisuspend(2) происходит сразу после завершения обработки сигнала. При этом восстанавливается маска, существовавшая до вызова sigsuspend(2).

Заметим, что в BSD UNIX вызов signal(3) является упрощенным интерфейсом к более общей функции sigaction(2), в то время как в ветви System V signal(3) подразумевает использование старой семантики ненадежных сигналов.

В заключение для иллюстрации изложенных соображений, приведем версию функции signal, позволяющую использовать надежные сигналы. Похожая реализация используется в BSD UNIX. С помощью этой "надежной" версии мы повторим пример, рассмотренный нами выше, в измененном виде.

#include <signal.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

/* Вариант "надежной" функции signal */

void (*mysignal(int signo, void (*hndlr)(int)))(int) {

 struct sigaction act, oact;

 /* Установим маску сигналов */

 act.sa_handler = hndlr;

 sigemptyset(&act.sa_mask);

 act.sa_flags = 0;

 if (signo != SIGALRM)

act.sa_flags = SA_RESTART;

 /* Установим диспозицию */

 if (sigaction(signo, &act, &oact) < 0)

return SIG_ERR;

 return(oact.sa_handler);

}

/* Функция-обработчик сигнала */

static void sig_hndlr(int signo) {

 /* Эта часть кода нам уже не нужна

mysignal(SIGINT, sig_hndlr);

 */

 printf("Получен сигнал SIGINT\n");

Поделиться с друзьями: