Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
20952096 raise(sig); /* Повторно послать сигнал */2097 }Вот код в
main()2214 #ifdef SA_NOCLDSTOP /* На системе POSIX... */2215 {2216 unsigned i;2217 sigemptyset(&caught_signals);2218 for (i = 0; i < nsigs; i++) /* - Блокировать все сигналы */2219 sigaddset(&caught_signals, sigs[i]);2220 newact.sa_handler = sighandler; /* - Функция обработки сигнала */2221 newact.sa_mask = caught_signals; /* - Установить для обработчика маску сигналов процесса */2222 newact.sa_flags =0; /* - Особых флагов нет */2223 }2224 #endif22252226 {2227 unsigned i;2228 for (i = 0; i < nsigs; i++) /* Для всех сигналов... */2229 {2230 int sig = sigs[i];2231 #ifdef SA_NOCLDSTOP2232 sigaction(sig, NULL, &oldact); /* - Получить старый обработчик */2233 if (oldact.sa_handler != SIG_IGN) /* - Если этот сигнал не игнорируется */2234 sigaction(sig, &newact, NULL); /* - Установить наш обработчик */2235 #else2236 if (signal(sig, SIG_IGN) != SIG_IGN)2237 signal(sig, sighandler); /* - Та же логика со старым API */2238 #endif2239 }2240 }Мы заметили, что строки 2216–2219 и 2221 могут быть замещены одним вызовом:
sigfillset(&newact.sa_mask)Мы не знаем, почему код написан именно таким способом.
Интерес представляют также строки 2233–2234 и 2236–2237, которые показывают правильный способ проверки того, игнорируется ли сигнал, и для установки обработчика лишь в том случае, если сигнал не игнорируется.
ЗАМЕЧАНИЕ. Функции API
sigaction()signal()signal()struct sigactionsignal()10.6.5. Извлечение ожидающих сигналов:
sigpending()Описанный ранее системный вызов
sigpending()#include <signal.h> /* POSIX */int sigpending(sigset_t *set);Помимо разблокировки ожидающих сигналов, чтобы они могли быть доставлены, вы можете решить их игнорировать. Установка действия сигнала
SIG_IGNSIG_DFL10.6.6. Создание возможности для прерывания функций:
siginterrupt()Чтобы сделать определенную функцию прерываемой или повторно запускаемой в зависимости от значения второго аргумента, в качестве удобного средства может использоваться функция
siginterrupt()#include <signal.h> /* XSI */int siginterrupt(int sig, int flag);В соответствии со стандартом POSIX поведение
siginterrupt()int siginterrupt(int sig, int flag) { int ret; struct sigaction act; (void)sigaction(sig, NULL, &act); /* Получить старые установки */ if (flag) /* Если flag равен true... */ act.sa_flags &= ~SA_RESTART; /* Запретить повторный запуск */ else /* В противном случае... */ act.sa_flags |= SA_RESTART; /* Разрешить повторный запуск */ ret = sigaction(sig, &act, NULL); /* Поместить новые установки на место */ return ret; /* Вернуть результат */}В случае успеха возвращаемое значение равно 0 и -1 при ошибке.
10.6.7. Передача сигналов:
kill()killpg()Традиционная функция Unix для передачи сигналов называется
kill()killpg()#include <sys/types.h> /* POSIX */#include <signal.h>int kill(pid_t pid, int sig);int killpg(int pgrp, int sig); /* XSI */Аргумент
sigkill()errno