Основы программирования в Linux
Часть 212 из 324 Информация о книге
Упражнение 11.9. ФункцияsigactionВнесите приведенные далее изменения, так чтобы сигнал
перехватывалсяSIGINT. Назовите новую программу ctrlc2.c.sigaction#include <signal.h>#include <stdio.h>#include <unistd.h>void ouch(int sig) {printf("OUCH! - I got signal %d\n", sig);}int main() {struct sigaction act;<i> act.sa_handler = ouch;</i><i> sigemptyset(&act.sa_mask);</i><i> act.sa_flags = 0;</i><i> sigaction(SIGINT, &act, 0);</i>while (1) {printf("Hello World!\n");sleep(1);}}Когда вы выполните эту версию программы, то всегда будете получать сообщение при нажатии комбинации клавиш <Ctrl>+<C>, поскольку
обрабатывается неоднократно функциейSIGINT. Для завершения программы следует нажать комбинацию клавиш <Ctrl>+<\>, которая генерирует по умолчанию сигналsigaction.SIIGQUIT$ <b>./ctrlc2</b>Hello World!Hello World!Hello World!<b>^C</b>OUCH! - I got signal 2Hello World!Hello World!<b>^C</b>OUCH! - I got signal 2Hello World!Hello World!<b>^\</b>Quit$Как это работает
Программа вместо функции
вызываетsignalдля задания функцииsigactionкак обработчика сигнала, возникающего при нажатии комбинации клавиш <Ctrl>+<C> (ouch). Прежде всего, она должна определить структуруSIGINT, содержащую обработчик, маску сигналов и флаги, В данном случае вам не нужны никакие флаги, и создается пустая маска сигналов с помощью новой функцииsigaction.sigemptysetПримечаниеПосле выполнения программы вы можете обнаружить дамп ядра (в файле core). Его можно безбоязненно удалить.
Множества сигналов
В заголовочном файле signal.h определены тип
и функции, применяемые для манипулирования множествами сигналов. Эти множества используются вsigset_tи других функциях для изменения поведения процесса при получении сигналов.sigaction<b>#include <signal.h></b><b>int sigaddset(sigset_t *set, int signo);</b><b>int sigemptyset(sigset_t *set);</b><b>int sigfillset(sigset_t *set);</b><b>int sigdelset(sigset_t *set, int signo);</b>Приведенные функции выполняют операции, соответствующие их названиям,
инициализирует пустое множество сигналов. Функцияsigemptysetинициализирует множество сигналов, заполняя его всеми заданными сигналами,sigfillsetиsigaddsetдобавляют заданный сигнал (sigdelset) в множество сигналов и удаляют его из множества. Они все возвращают 0 в случае успешного завершения и -1 в случае ошибки, заданной в переменнойsigno. Единственная определенная ошибкаerrnoописывает сигнал как некорректный.EINVALФункция
определяет, включен ли заданный сигнал в множество сигналов. Она возвращает 1, если сигнал является элементом множества, 0, если нет и -1 сsigismember, равнойerrno, если сигнал неверный.EINVAL<b>#include <signal.h></b><b>int sigismember(sigset_t *set, int signo);</b>Маска сигналов процесса задается и просматривается с помощью функции
. Маска сигналов — это множество сигналов, которые заблокированы в данный момент и не будут приниматься текущим процессом.sigprocmask<b>#include <signal.h></b><b>int sigprocmask(int how, const sigset_t *set, sigset_t *oset);</b>Функция
может изменять маску сигналов процесса разными способами в соответствии с аргументомsigprocmask. Новые значения маски сигналов передаются в аргументеhow, если он не равенset, а предыдущая маска сигналов будет записана в множество сигналовnull.osetАргумент
может принимать одно из следующих значений:how□
— сигналы аргументаSIG_BLOCKдобавляются к маске сигналов;set□
—маска сигналов задается аргументомSIG_SETMASK;set□
— сигналы в аргументеSIG_UNBLOCKудаляются из маски сигналов.setЕсли аргумент
равенset, значениеnullне используется и единственная цель вызова — перенести значение текущей маски сигналов в аргументhow.osetЕсли функция
завершается успешно, она возвращает 0. Функция вернет -1, если параметрsigprocmaskневерен, в этом случае переменнаяhowбудет равнаerrno.EINVAL