Если сигнал заблокирован процессом, он не будет доставлен, но останется ждать обработки. Программа может определить с помощью функции sigpending, какие из заблокированных ею сигналов ждут обработки.
<b>#include <signal.h></b>
<b>int sigpending(sigset_t *set);</b>
Она записывает множество сигналов, заблокированных от доставки и ждущих обработки, в множество сигналов, на которое указывает аргумент set. Функция возвращает 0 при успешном завершении и -1 в противном случае с переменной errno, содержащей ошибку. Данная функция может пригодиться, когда программе потребуется обрабатывать сигналы и управлять моментом вызова функции обработки.
С помощью функции sigsuspend процесс может приостановить выполнение, пока не будет доставлен один сигнал из множества сигналов. Это более общая форма функции pause, с которой вы уже встречались.
<b>#include <signal.h></b>
<b>int sigsuspend(const sigset_t *sigmask);</b>
Функция sigsuspend замещает маску сигналов процесса множеством сигналов, заданным в аргументе sigmask, и затем приостанавливает выполнение. Оно будет возобновлено после выполнения функции обработки сигнала. Если полученный сигнал завершает программу, sigsuspend никогда не вернет ей управление. Если полученный сигнал не завершает программу, sigsuspend вернет с переменной errno, равной EINTR.
Флаги
sigactionПоле sa_flags структуры sigaction, применяемой в функции sigaction, может содержать значения, изменяющие поведение сигнала (табл. 11.5).
Таблица 11.5
Имя сигнала Описание SA_NOCLDSTOP Не генерируется SIGCHLD, когда дочерние процессы остановлены SA_RESETHAND Восстанавливает при получении действие, соответствующее значению SIG_DFL SA_RESTART Перезапускает прерванные функции вместо ошибки EINTR SA_NODEFER При перехвате сигнала не добавляет его а маску сигналов
Флаг SA_RESETHAND может применяться для автоматической очистки функции сигнала при захвате сигнала, как мы видели раньше.
Многие системные вызовы, которые использует программа, прерываемые, т.е. при получении сигнала они вернутся с ошибкой и переменная errno получит значение EINTR, чтобы указать, что функция вернула управление в результате получения сигнала. Поведение требует повышенного внимания со стороны приложения, использующего сигналы. Если в поле sa_flags функции sigaction установлен флаг SA_RESTART, функция, которая в противном случае могла быть прервана сигналом, вместо этого будет возобновлена, как только выполнится функция обработки сигнала.
Обычно, когда функция обработки сигнала выполняется, полученный сигнал добавляется в маску сигналов процесса во время работы функции обработки. Это препятствует последующему появлению того же сигнала, заставляющему функцию обработки сигнала выполняться снова. Если функция не реентерабельная, вызов ее другим экземпляром сигнала до того, как она завершит обработку первого сигнала, может создать проблемы. Но если установлен флаг SA_NODEFER, маска сигнала не меняется при получении этого сигнала.
Функция обработки сигнала может быть прервана в середине и вызвана снова чем-нибудь еще. Когда вы возвращаетесь к первому вызову функции, крайне важно, чтобы она все еще действовала корректно. Она должна быть не просто рекурсивной (вызывающей саму себя), а реентерабельной (в нее можно войти и выполнить ее снова). Подпрограммы ядра, обслуживающие прерывания и имеющие дело с несколькими устройствами одновременно, должны быть реентерабельными, поскольку высокоприоритетное прерывание может "войти" в тот код, который выполняется.
Функции, которые безопасно вызываются в обработчике сигнала и в стандарте X/Open гарантированно описанные либо как реентерабельные, либо как самостоятельно не возбуждающие сигналов, перечислены в табл. 11.6.
Все функции, не включенные в табл. 11.6, следует считать небезопасными в том, что касается сигналов.
Таблица 11.6
access alarm cfgetispeed cfgetospeed cfsetispeed cfsetospeed chdir chmod chown close creat dup2 dup execle execve exit fcntl fork fstat getegid geteuid getgid getgroups getpgrp getpid getppid getuid kill link lseek mkdir mkfifo open pathconf pause pipe read rename rmdir setgid setpgid setsid setuid sigaction sigaddset sigdelset sigemptyset sigfillset sigismember signal sigpending sigprocmask sigsuspend sleep stat sysconf tcdrain tcflow tcflush tcgetattr tcgetpgrp tcsendbreak tcsetattr tcsetpgrp time times umask uname unlink utime wait waitpid write