Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

13

14 /* Пройти через это испытание , чтобы избежать fprintf. */

15 strcpy(buf, "handler: caught signal ");

16 cp = buf + strlen(buf); /* cp указывает на завершающий '\0' */

17 if (signum > 100) /* маловероятно */

18 offset = 3;

19 else if (signum > 10)

20 offset = 2;

21 else

22 offset = 1;

23 cp += offset;

24

25 *cp-- = '\0'; /* завершить строку */

26 while (signum >0) { /* work backwards, filling in digits */

27 *cp-- = (signum % 10) + '0';

28 signum /= 10;

29 }

30 strcat(buf, "\n");

31 (void)write(2, buf, strlen(buf));

32 }

33

34 /* main --- установить обработку сигнала и войти в бесконечный цикл */

35

36 int main(void)

37 {

38 (void)signal(SIGINT, handler);

39

40 for(;;)

41 pause; /* ждать сигнал, см. далее в главе */

42

43 return 0;

44 }

Строки 9–22 определяют функцию обработки сигнала (остроумно названную

handler
[106] ). Все, что эта функция делает, — выводит номер перехваченного сигнала и возвращается. Для вывода этого сообщения она выполняет множество ручной работы, поскольку
fprintf
не является «безопасной» для вызова из обработчика сигнала. (Вскоре это будет описано в разделе 10.4.6 «Дополнительные предостережения».)

106

Handler (англ.) — обработчик — Примеч. перев.

Функция

main
устанавливает обработчик сигнала (строка 38), а затем входит в бесконечный цикл (строки 40–41). Вот что происходит при запуске:

$ ssh solaris.example.com

 /* Зарегистрироваться на доступной системе Solaris */

Last login: Fri Sep 19 04:33:25 2003 from 4.3.2.1.

Sun Microsystems Inc. SunOS 5.9 Generic May 2002

$ gcc ch10-catchint.c /* Откомпилировать программу */

$ a.out /* Запустить ее */

^C handler: caught signal 2 /* Набрать ^C, вызывается обработчик */

^C /* Попробовать снова, но на этот раз... */

$ /* Программа завершается */

Поскольку V7 и другие традиционные системы восстанавливают действие сигнала по умолчанию, поэтому когда вы хотите снова получить сигнал в будущем, функция обработчика должна немедленно переустановить саму себя:

void handler(int signum) {

 char buf[200], *cp;

 int offset;

 (void)signal(signum, handler); /* переустановить обработчик */

 /* ...оставшаяся часть функции как прежде... */

}

10.4.2. BSD и GNU/Linux

BSD 4.2 изменила способ работы

signal
. [107] На системах BSD обработчик сигнала после его возвращения остается на месте. Системы GNU/Linux следуют поведению BSD. Вот что происходит под GNU/Linux:

107

Изменение поведения было плохой мыслью, сильно критиковавшейся в свое время, но было слишком поздно. Изменение семантики определенного интерфейса всегда ведет к проблеме, как было в этом случае. Хотя это особенно относится к проектировщикам операционных систем, любой, кто разрабатывает библиотеки общего назначения, также должен помнить этот урок. — Примеч. автора.

$ ch10-catchint /* Запустить программу */

handler: caught signal 2 /* Набираем ^C, вызывается обработчик */

handler: caught signal 2 /* И снова... */

handler: caught signal 2 /* И снова! */

handler: caught signal 2 /* Помогите! */

handler: caught signal 2 /* Как нам это остановить?! */

Quit (core dumped) /* ^\, генерирует SIGQUIT. Bay */

На системе BSD или GNU/Linux обработчик сигнала не должен дополнительно использовать '

signal(signum, handler)
' для переустановки обработчика. Однако, лишний вызов не причиняет никакого вреда, поэтому сохраняется статус-кво.

В действительности, POSIX предоставляет функцию

bsd_signal
, которая идентична
signal
за тем исключением, что она гарантирует, что обработчик сигнала останется установленным:

#include <signal.h> /* XSI, устаревает */

void (*bsd_signal(int sig, void (*func)(int)))(int);

Это устраняет проблемы переносимости. Если вы знаете, что ваша программа будет работать лишь на системах POSIX, вы можете воспользоваться

bsd_signal
вместо
signal
.

Одно предостережение — эта функция также помечена как «устаревающая», что означает возможность отказа от нее в будущем стандарте. На практике, даже если от нее откажутся, поставщики скорее всего долгое время будут ее поддерживать. (Как мы увидим, функция API POSIX

sigaction
предоставляет достаточно возможностей для написания рабочей версии, если это вам нужно.)

10.4.3. Игнорирование сигналов

Более практично, когда вызывается обработчик сигнала, это означает, что программа должна завершиться и выйти. Было бы раздражающим, если бы большинство программ по получении

SIGINT
выводили бы сообщение и продолжали работу; смысл сигнала в том, что они должны остановиться!

Например, рассмотрите программу

sort
.
sort
, возможно, создала любое число временных файлов для использования на промежуточных этапах процесса сортировки. По получении
SIGINT
,
sort
должна удалить временные файлы и выйти. Вот упрощенная версия обработчика сигнала из GNU Coreutils
sort.c
:

Поделиться:
Популярные книги

Хозяин Теней 7

Петров Максим Николаевич
7. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Хозяин Теней 7

Гримуар темного лорда II

Грехов Тимофей
2. Гримуар темного лорда
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Гримуар темного лорда II

Последний Герой. Том 1

Дамиров Рафаэль
1. Последний герой
Фантастика:
попаданцы
альтернативная история
фантастика: прочее
5.00
рейтинг книги
Последний Герой. Том 1

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Гримуар темного лорда IX

Грехов Тимофей
9. Гримуар темного лорда
Фантастика:
попаданцы
альтернативная история
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда IX

Кодекс Охотника. Книга XIII

Винокуров Юрий
13. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XIII

Железный Воин Империи II

Зот Бакалавр
2. Железный Воин Империи
Фантастика:
фэнтези
попаданцы
аниме
5.75
рейтинг книги
Железный Воин Империи II

Бастард Императора. Том 11

Орлов Андрей Юрьевич
11. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 11

Вернувшийся: Первые шаги. Том II

Vector
2. Вернувшийся
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Первые шаги. Том II

Прапорщик. Назад в СССР. Книга 6

Гаусс Максим
6. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прапорщик. Назад в СССР. Книга 6

Родословная. Том 4

Ткачев Андрей Юрьевич
4. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Родословная. Том 4

Офицер

Земляной Андрей Борисович
1. Офицер
Фантастика:
боевая фантастика
7.21
рейтинг книги
Офицер

Мастер решений

Земляной Андрей Борисович
3. Специалист по выживанию
Фантастика:
боевая фантастика
космическая фантастика
6.20
рейтинг книги
Мастер решений

Эволюционер из трущоб. Том 9

Панарин Антон
9. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 9