sigaction()
struct sigaction {
void (*sa_handler)(int); // Обработчик сигнала старого стиля
void (*sa_sigaction)(int, siginfo_t *, void *); // Обработчик сигнала нового стиля
// Обработчик выбирается на основе флага SA_SIGINFO
// в поле sa_flags
sigset_t sa_mask; // Маска блокируемых сигналов
int sa_flags; // Набор флагов
// SA_RESETHAND - сброс обработчика на SIG_DFL после выхода из назначенного обработчика.
// SA_RESTART - восстановление прерванных системных вызовов после выхода из обработчика.
// SA_SIGINFO - вызов sa_sigaction вместо sa_handler
void (*sa_restorer)(void); // Устаревшее поле
}
sa_sigaction()
siginfo_t {
int si_signo; // Номер сигнала
int si_code; // Способ отправки сигнала или уточняющее значение
// SI_USER сигнал отправлен через вызов kill()
// SI_QUEUE сигнал отправлен через вызов sigqueue()
// FPE_FLTDIV - уточнение для сигнала SIGFPE - деление на ноль
// ILL_ILLOPC - уточнение для сигнала SIGILL - недопустимый опкод
// ...
pid_t si_pid; // PID процесса отправителя (дочернего процесса при SIGCHLD)
uid_t si_uid; // UID процесса отправителя
int si_status; // Статус завершения дочернего процесса при SIGCHLD
sigval_t si_value; // Значение, переданое через параметр value при вызове sigqueue()
void * si_addr; // Адрес в памяти
// SIGILL, SIGFPE - адрес сбойной инструкции
// SIGSEGV, SIGBUS - адрес сбойной памяти
}
В Linux структура siginfo_t
содержит больше полей, но они служат для совместимости и не заполняются.
#include <signal.h>
void myhandler(int sig) {
...
}
void myaction(int signum, siginfo_t * siginfo, void *code) {
...
}
main() {
struct sigaction act,oldact;
act.sa_sigaction=myaction;
act.sa_flags=SA_SIGINFO;
sigaction(signum, &act, &oldact);
}