SignalAction(), SignalAction_r()

Определить действие, выполняемое при получении сигнала

Прототип:

#include <sys/neutrino.h>
int SignalAction( pid_t pid,
void (*sigstub)(),
int signo,
const struct sigaction *act,
struct sigaction *oact );
int SignalAction_r( pid_t pid,
void * (*sigstub)(),
int signo,
const struct sigaction *act,
struct sigaction *oact );

Аргументы:

pid
Идентификатор процесса или 0 для текущего процесса.
sigstub
Адрес обработчика заглушки сигнала. Это небольшой фрагмент кода в пространстве пользователя, который связывает пользовательский обработчик сигналов с ядром. Библиотека предоставляет стандартную заглушку __signalstub().
signo
Сигнал, действие которого требуется установить или получить.
act
NULL или указатель на struct sigaction, определяющую новое действие для сигнала.
oact
NULL или указатель на struct sigaction, где функция может хранить старое действие.

Библиотека:

libc

Описание:

Системные вызовы SignalAction() и SignalAction_r() позволяют вызывающему процессу проверить и/или установить действие, которое должно быть связано с конкретным сигналом в процессе pid. Если pid равен нулю, используется вызывающий процесс. Аргумент signo определяет сигнал.


Note: Следует вызывать функцию POSIX sigaction() или функцию ANSI signal() вместо прямого использования этих системных вызовов.

Эти функции идентичны, за исключением способа индикации ошибок.

Сигналы POSIX

Сигналы определены в <signal.h>, как и эти глобальные переменные:

char * const sys_siglist[]
Массив имен сигналов.
int sys_nsig
Количество записей в массиве sys_siglist.

Существует 32 сигнала POSIX 1003.1a, в их числе:

SIGHUP
Зависание.
SIGINT
Прерывание.
SIGQUIT
Завершение.
SIGILL
Некорректная инструкция (не сбрасывается при обнаружении). Одной из возможных причин этого сигнала является попытка выполнить операцию, требующую привилегий ввода-вывода. Поток может запросить эти привилегии, вызвав ThreadCtl(), указав флаг _NTO_TCTL_IO:

ThreadCtl( _NTO_TCTL_IO, 0 );

SIGTRAP
Ловушка трассировки (не сбрасывается при срабатывании).
SIGIOT
инструкция IOT.
SIGABRT
Используется abort().
SIGEMT
инструкция EMT.
SIGFPE
Исключение с плавающей запятой.
SIGKILL
Уничтожить (сигнал не может быть перехвачен или проигнорирован).
SIGBUS
Ошибка шины.
SIGSEGV
Нарушение сегментации.
SIGSYS
Некорректный аргумент для системного вызова.
SIGPIPE
Запись в канал без считывания.
SIGALRM
"Будильник" в реальном времени.
SIGTERM
Сигнал завершения программы от kill.
SIGUSR1
Пользовательский сигнал 1.
SIGUSR2
Пользовательский сигнал 2.
SIGCHLD
Смерть потомка.
SIGPWR
Перезапуск при сбое питания.
SIGWINCH
Смена окна.
SIGURG
Экстренное состояние на канале ввода-вывода.
SIGPOLL
Имя системы V для SIGIO.
SIGIO
Асинхронный ввод-вывод.
SIGSTOP
Отправляемый сигнал остановки не от tty.
SIGTSTP
Стоп-сигнал от tty.
SIGCONT
Продолжить остановленный процесс.
SIGTTIN
Попытка фонового чтения tty.
SIGTTOU
Попытка фоновой записи tty.


Note: Невозможно перехватить или игнорировать SIGCONT, SIGKILL, или SIGSTOP.

Существует 16 POSIX 1003.1b сигналов реального времени, в их числе:

SIGRTMIN
Первый сигнал реального времени.
SIGRTMAX
Последний сигнал реального времени.

Весь диапазон сигналов идет от _SIGMIN (1) до _SIGMAX (64).

Дополнительные сигналы ЗОСРВ «Нейтрино»

ЗОСРВ «Нейтрино» использует первые восемь сигналов для специальных целей. Они всегда маскированы, и попытки их размаскировать игнорируются. Среди них два именованных сигнала (SIGSELECT и SIGPHOTON) и шесть безымянных.

Действия с сигналами

Если act не равен NULL, то указанный сигнал изменяется. Если oact не равен NULL, предыдущее действие сохраняется в структуре, на которую оно указывает. Можно использовать различные комбинации act и oact для запроса или установки (или того и другого) действия для сигнала.

Находясь в обработчике, signo маскируется, предотвращая вложенные сигналы одного и того же типа. Кроме того, любые сигналы, установленные в поле sa_mask структуры act, также объединяются в маске с помощью операции ИЛИ. Когда обработчик завершается штатно, предыдущая маска восстанавливается, и действуют любые ожидающие и теперь размаскированные сигналы. Происходит возврат к тому моменту в программе, где она была прервана. Если поток был заблокирован в ядре, когда произошло прерывание, системный вызов завершается с EINTR (исключения см. в ChannelCreate() и SyncMutexLock()).


Note: Небезопасно использовать операции с плавающей запятой в обработчиках сигналов.

При указании обработчика, необходимо указать адрес обработчика заглушки сигнала для sigstub. Это небольшой фрагмент кода в пространстве пользователя, который связывает пользовательский обработчик сигналов с ядром. Библиотека предоставляет стандартную заглушку __signalstub().

Обработчики сигналов и действия определяются для процесса и влияют на все его потоки. Например, если один поток игнорирует сигнал, то все потоки в процессе также будут игнорировать данный сигнал.

Можно передать сигнал потоку, процесс или группе процессов (см. SignalKill()). При направлении сигнала процессу, сигнал получает не более одного потока. Этот поток должен иметь разблокированный сигнал (см. SignalProcmask()), чтобы быть кандидатом на его получение. Все синхронно сгенерированные сигналы (например, SIGSEGV) всегда доставляются в вызвавший их поток.

В многопоточном процессе, если сигнал завершает поток, то, по умолчанию, все потоки и, следовательно, процесс завершаются. Можно переопределить это стандартное поведение POSIX при создании потока; см. ThreadCreate().


Caution: При использовании longjmp() для возврата из обработчика сигнала, сигнал остается маскированным. Можное использовать siglongjmp() для восстановления маски в состояние, сохраненное предыдущим вызовом sigsetjmp().

Состояния блокировки:

Эти вызовы не блокируются.

Возвращаемое значение:

SignalAction()
Если возникла ошибка функция возвращает -1, код ошибки записывается в errno. Любое другое возвращенное значение считается успешным завершением.
SignalAction_r()
EOK возвращается при успешном завершении. Функция НЕ устанавливает errno. При возникновении ошибки функция возвращает один из представленных ниже кодов.

Коды ошибок:

EAGAIN
Системе не удалось выделить обработчик сигнала. Критически низкий уровень памяти.
EFAULT
Произошла ошибка, при попытке ядра получить доступ к предоставленным буферам.
EINVAL
Значение signo меньше 1 или больше _SIGMAX, либо была произведена попытка установить SIGKILL или SIGSTOP на что-то отличное от SIG_DFL.
EPERM
У процесса нет разрешения на изменение действий сигналов указанного процесса.
ESRCH
Процесс pid не существует.

Классификация:

ЗОСРВ «Нейтрино»

Точка остановки потока
Нет
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Тематические ссылки:

struct sigaction, abort(), ChannelCreate(), kill(), longjmp(), siglongjmp(), signal(), sigaction(), SignalKill(), SignalProcmask(), sigqueue(), sigsetjmp(), SyncMutexLock(), ThreadCreate(), wait(), waitpid()




Предыдущий раздел: Описание API системной библиотеки