struct sigaction act;
while (1) {
printf("Hello World!\n");
sleep(1);
}
}
Когда вы выполните эту версию программы, то всегда будете получать сообщение при нажатии комбинации клавиш SIGINT обрабатывается неоднократно функцией sigaction. Для завершения программы следует нажать комбинацию клавиш SIIGQUIT.
$ ./ctrlc2
Hello World!
Hello World!
Hello World!
^C
OUCH! - I got signal 2
Hello World!
Hello World!
^C
OUCH! - I got signal 2
Hello World!
Hello World!
^\
Quit
$
Как это работает
Программа вместо функции signal вызывает sigaction для задания функции ouch как обработчика сигнала, возникающего при нажатии комбинации клавиш SIGINT). Прежде всего, она должна определить структуру sigaction, содержащую обработчик, маску сигналов и флаги, В данном случае вам не нужны никакие флаги, и создается пустая маска сигналов с помощью новой функции sigemptyset.
После выполнения программы вы можете обнаружить дамп ядра (в файле core). Его можно безбоязненно удалить.
Множества сигналов
В заголовочном файле signal.h определены тип sigset_t и функции, применяемые для манипулирования множествами сигналов. Эти множества используются в sigaction и других функциях для изменения поведения процесса при получении сигналов.
#include
int sigaddset(sigset_t *set, int signo);
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigdelset(sigset_t *set, int signo);
Приведенные функции выполняют операции, соответствующие их названиям, sigemptyset инициализирует пустое множество сигналов. Функция sigfillset инициализирует множество сигналов, заполняя его всеми заданными сигналами, sigaddset и sigdelset добавляют заданный сигнал (signo) в множество сигналов и удаляют его из множества. Они все возвращают 0 в случае успешного завершения и -1 в случае ошибки, заданной в переменной errno. Единственная определенная ошибка EINVAL описывает сигнал как некорректный.
Функция sigismember определяет, включен ли заданный сигнал в множество сигналов. Она возвращает 1, если сигнал является элементом множества, 0, если нет и -1 с errno, равной EINVAL, если сигнал неверный.
#include
int sigismember(sigset_t *set, int signo);
Маска сигналов процесса задается и просматривается с помощью функции sigprocmask. Маска сигналов — это множество сигналов, которые заблокированы в данный момент и не будут приниматься текущим процессом.
#include
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
Функция sigprocmask может изменять маску сигналов процесса разными способами в соответствии с аргументом how. Новые значения маски сигналов передаются в аргументе set, если он не равен null, а предыдущая маска сигналов будет записана в множество сигналов oset.
Аргумент how может принимать одно из следующих значений:
□ SIG_BLOCK — сигналы аргумента set добавляются к маске сигналов;
□ SIG_SETMASK —маска сигналов задается аргументом set;
□ SIG_UNBLOCK — сигналы в аргументе set удаляются из маски сигналов.
Если аргумент set равен null, значение how не используется и единственная цель вызова — перенести значение текущей маски сигналов в аргумент oset.
Если функция sigprocmask завершается успешно, она возвращает 0. Функция вернет -1, если параметр how неверен, в этом случае переменная errno будет равна EINVAL.
Если сигнал заблокирован процессом, он не будет доставлен, но останется ждать обработки. Программа может определить с помощью функции sigpending, какие из заблокированных ею сигналов ждут обработки.
#include
int sigpending(sigset_t *set);