Читаем UNIX: разработка сетевых приложений полностью

1. Мы можем предоставить функцию, которая вызывается при перехвате определенного сигнала. Эта функция называется обработчиком сигнала (signal handler), а действие называется перехватыванием сигнала (catching). Сигналы SIGKILL и SIGSTOP перехватить нельзя. Наша функция вызывается с одним целочисленным аргументом, который является номером сигнала, и ничего не возвращает. Следовательно, прототип этой функции имеет вид:

void handler(int signo);

Для большинства сигналов вызов функции sigaction и задание функции, вызываемой при получении сигнала, — это все, что требуется для обработки сигнала. Но дальше вы увидите, что для перехватывания некоторых сигналов, в частности SIGIO, SIGPOLL и SIGURG, требуются дополнительные действия со стороны процесса.

2. Мы можем игнорировать сигнал, если действие задать как SIG_IGN. Сигналы SIGKILL и SIGSTOP не могут быть проигнорированы.

3. Мы можем установить действие для сигнала по умолчанию, задав его как SIG_DFL. Действие сигнала по умолчанию обычно заключается в завершении процесса по получении сигнала, а некоторые сигналы генерируют копию области памяти процесса в его текущем каталоге (так называемый дампcore dump). Есть несколько сигналов, для которых действием по умолчанию является игнорирование. Например, SIGCHLD и SIGURG (посылается по получении внеполосных данных, см. главу 24) — это два сигнала, игнорируемых по умолчанию, с которыми мы встретимся в тексте.

<p>Функция signal</p>

Согласно POSIX, чтобы определить действие для сигнала, нужно вызвать функцию sigaction. Однако это достаточно сложно, поскольку один аргумент этой функции — это структура, для которой необходимо выделение памяти и заполнение. Поэтому проще задать действие сигнала с помощью функции signal. Первый ее аргумент — это имя сигнала, а второй — либо указатель на функцию, либо одна из констант SIG_IGN и SIG_DFL. Но функция signal существовала еще до появления POSIX.1, и ее различные реализации имеют разную семантику сигналов с целью обеспечения обратной совместимости. В то же время POSIX четко диктует семантику при вызове функции sigaction. Это обеспечивает простой интерфейс с соблюдением семантики POSIX. Мы включили эту функцию в нашу собственную библиотеку вместе функциями err_XXX и функциями-обертками, которые мы используем для построения всех наших программ. Она представлена в листинге 5.5. Функция-обертка Signal здесь не показана, потому что ее вид не зависит от того, какую именно функцию signal она должна вызывать.

Листинг 5.5. Функция signal, вызывающая функцию POSIX sigaction

//lib/signal.c

 1 #include "unp.h"

 2 Sigfunc*

 3 signal(int signo, Sigfunc *func)

 4 {

 5  struct sigaction act, oact;

 6  act.sa_handler = func;

 7  sigemptyset(&act.sa_mask);

 8  act.sa_flags = 0;

 9  if (signo == SIGALRM) {

10 #ifdef SA_INTERRUPT

11   act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */

12 #endif

13  } else {

14 #ifdef SA_RESTART

15   act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */

16 #endif

17  }

18  if (sigaction(signo, &act, &oact) < 0)

19   return (SIG_ERR);

20  return (oact.sa_handler);

21 }

Упрощение прототипа функции при использовании typedef

2-3 Обычный прототип для функции signal усложняется наличием вложенных скобок:

void (*signal(int signo, void (*func)(int)))(int);

Чтобы упростить эту запись, мы определяем тип Sigfunc в нашем заголовочном файле unp.h следующим образом:

typedef void Sigfunc(int);

указывая тем самым, что обработчики сигналов — это функции с целочисленным аргументом, ничего не возвращающие (void). Тогда прототип функции выглядит следующим образом:

Sigfunc *signal(int signo, Sigfunc *func);

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

Установка обработчика

6 Элемент sa_handler структуры sigaction устанавливается равным аргументу func функции signal.

Установка маски сигнала для обработчика
Перейти на страницу:

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги