sigaction()

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

Прототип:

#include <signal.h>
int sigaction( int sig,
const struct sigaction *act,
struct sigaction *oact );

Аргументы:

sig
Номер сигнала (определенный в <signal.h>). Для получения более подробной информации см. Сигналы POSIX в документации к SignalAction().
act
NULL или указатель на struct sigaction, который указывает, как требуется изменить действие для данного сигнала.
oact
NULL или указатель на struct sigaction, который функция заполняет информацией о текущем действии для сигнала.

Библиотека:

libc

Описание:

Возможно использование sigaction() для проверки или установки (или и того и другого) действия, которое связано с конкретным сигналом:

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


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

Невозможно игнорировать или поймать SIGKILL или SIGSTOP.

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

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


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

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

0
Успешное завершение.
-1
Возникла ошибка. Код ошибки записан в errno.

Коды ошибок:

EAGAIN
Недостаточно системных ресурсов для настройки действия сигнала.
EFAULT
Произошла ошибка при попытке доступа к предоставленным буферам.
EINVAL
Сигнал signo некорректен.

Примеры:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
int main( void )
{
extern void handler();
struct sigaction act;
sigset_t set;
sigemptyset( &set );
sigaddset( &set, SIGUSR1 );
sigaddset( &set, SIGUSR2 );
/*
* Define a handler for SIGUSR1 such that when
* entered both SIGUSR1 and SIGUSR2 are masked.
*/
act.sa_flags = 0;
act.sa_mask = set;
act.sa_handler = &handler;
sigaction( SIGUSR1, &act, NULL );
kill( getpid(), SIGUSR1 );
/* Program will terminate with a SIGUSR2 */
return (EXIT_SUCCESS);
}
void handler( signo )
{
static int first = 1;
if ( first )
{
first = 0;
kill( getpid(), SIGUSR1 ); /* Prove signal masked */
kill( getpid(), SIGUSR2 ); /* Prove signal masked */
}
}
/*
* - SIGUSR1 is set from main(), handler() is called.
* - SIGUSR1 and SIGUSR2 are set from handler().
* - however, signals are masked until we return to main().
* - returning to main() unmasks SIGUSR1 and SIGUSR2.
* - pending SIGUSR1 now occurs, handler() is called.
* - pending SIGUSR2 now occurs. Since we don't have
* a handler for SIGUSR2, we are killed.
*/

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

POSIX 1003.1

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

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

struct sigaction, errno, kill(), pthread_sigmask(), raise(), sigaddset(), sigdelset(), sigemptyset(), sigfillset(), sigismember(), signal(), SignalAction(), SignalKill(), sigpending(), sigprocmask()




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