Читать интересную книгу Основы программирования в Linux - Мэтью Нейл

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 208 209 210 211 212 213 214 215 216 ... 324
Упражнение 11.9. Функция sigaction

Внесите приведенные далее изменения, так чтобы сигнал SIGINT перехватывался sigaction. Назовите новую программу ctrlc2.c.

#include <signal.h>

#include <stdio.h>

#include <unistd.h>

void ouch(int sig) {

 printf("OUCH! - I got signal %dn", sig);

}

int main() {

 struct sigaction act;

<i> act.sa_handler = ouch;</i>

<i> sigemptyset(&amp;act.sa_mask);</i>

<i> act.sa_flags = 0;</i>

<i> sigaction(SIGINT, &amp;act, 0);</i>

 while (1) {

  printf(&quot;Hello World!n&quot;);

  sleep(1);

 }

}

Когда вы выполните эту версию программы, то всегда будете получать сообщение при нажатии комбинации клавиш <Ctrl>+<C>, поскольку SIGINT обрабатывается неоднократно функцией sigaction. Для завершения программы следует нажать комбинацию клавиш <Ctrl>+<>, которая генерирует по умолчанию сигнал SIIGQUIT.

$ <b>./ctrlc2</b>

Hello World!

Hello World!

Hello World!

<b>^C</b>

OUCH! - I got signal 2

Hello World!

Hello World!

<b>^C</b>

OUCH! - I got signal 2

Hello World!

Hello World!

<b>^</b>

Quit

$

Как это работает

Программа вместо функции signal вызывает sigaction для задания функции ouch как обработчика сигнала, возникающего при нажатии комбинации клавиш <Ctrl>+<C> (SIGINT). Прежде всего, она должна определить структуру sigaction, содержащую обработчик, маску сигналов и флаги, В данном случае вам не нужны никакие флаги, и создается пустая маска сигналов с помощью новой функции sigemptyset.

Примечание

После выполнения программы вы можете обнаружить дамп ядра (в файле core). Его можно безбоязненно удалить.

Множества сигналов

В заголовочном файле signal.h определены тип sigset_t и функции, применяемые для манипулирования множествами сигналов. Эти множества используются в sigaction и других функциях для изменения поведения процесса при получении сигналов.

<b>#include &lt;signal.h&gt;</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 добавляют заданный сигнал (signo) в множество сигналов и удаляют его из множества. Они все возвращают 0 в случае успешного завершения и -1 в случае ошибки, заданной в переменной errno. Единственная определенная ошибка EINVAL описывает сигнал как некорректный.

Функция sigismember определяет, включен ли заданный сигнал в множество сигналов. Она возвращает 1, если сигнал является элементом множества, 0, если нет и -1 с errno, равной EINVAL, если сигнал неверный.

<b>#include &lt;signal.h&gt;</b>

<b>int sigismember(sigset_t *set, int signo);</b>

Маска сигналов процесса задается и просматривается с помощью функции sigprocmask. Маска сигналов — это множество сигналов, которые заблокированы в данный момент и не будут приниматься текущим процессом.

<b>#include &lt;signal.h&gt;</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.

Если функция sigprocmask завершается успешно, она возвращает 0. Функция вернет -1, если параметр how неверен, в этом случае переменная errno будет равна EINVAL.

1 ... 208 209 210 211 212 213 214 215 216 ... 324
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Основы программирования в Linux - Мэтью Нейл.

Оставить комментарий