sigwaitinfo(2) синхронное ожидание запрошенных

Other Alias

sigtimedwait, rt_sigtimedwait

ОБЗОР

#include <signal.h>


int sigwaitinfo(const sigset_t *set, siginfo_t *info);

int sigtimedwait(const sigset_t *set, siginfo_t *info,
const struct timespec *timeout);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

sigwaitinfo(), sigtimedwait(): _POSIX_C_SOURCE >= 199309L

ОПИСАНИЕ

sigwaitinfo() приостанавливает исполнение вызывающий нити до тех пор, пока не будет ожидаться один из сигналов из набора set (если один из сигналов в set уже ожидает обработки вызывающей нитью, то sigwaitinfo() завершит работу немедленно с возвратом информации об этом сигнале).

sigwaitinfo() удаляет сигнал из списка сигналов ожидающих обработки и возвращает номер сигнала как результат работы функции. Если аргумент info не равен NULL, то в буфер, на который он указывает, записывается структура типа siginfo_t (см. sigaction(2)), содержащая информацию о сигнале.

Если в set ожидают обработки несколько сигналов, то сигнал, который получит sigwaitinfo(), определяется согласно обычным правилам очерёдности; подробней смотрите в signal(7).

Системный вызов sigtimedwait() работает аналогично sigwaitinfo(), за исключением того, что он имеет дополнительный аргумент timeout, задающий интервал, на который приостанавливается процесс в ожидании сигнала. Данное значение интервала будет округлено до точности системных часов, а из-за задержки при планировании в ядре блокирующий интервал будет немного больше. Этот аргумент имеет следующий тип:

struct timespec {
    long    tv_sec;         /* секунды */
    long    tv_nsec;        /* наносекунды */
}

Если оба поля структуры равны 0, то исполняется опрос: sigtimedwait() немедленно завершает работу, либо с информацией о сигнале, предназначенном вызывающему, либо с ошибкой, если ни один из сигналов в наборе set не ожидает обработки.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При нормальном завершении работы sigwaitinfo() и sigtimedwait() возвращают номер сигнала (т.е. значение больше нуля). При ошибках оба вызова возвращают -1 и переменная errno устанавливается соответственно ошибке.

ОШИБКИ

EAGAIN
Ни одного сигнала в указанном наборе set не появилось для обработки за время timeout, указанном для sigtimedwait().
EINTR
Ожидание было прервано обработчиком сигнала; см. signal(7). (Этот обработчик был для другого сигнала, не из набора set.)
EINVAL
Значение timeout некорректно.

СООТВЕТСТВИЕ СТАНДАРТАМ

POSIX.1-2001, POSIX.1-2008.

ЗАМЕЧАНИЯ

При обычном использовании вызывающая программа блокирует сигналы в наборе set через предыдущий вызов sigprocmask(2) (для того, чтобы не сработали обработчики по умолчанию этих сигналов, если они появятся для обработки между последующими вызовами sigwaitinfo() или sigtimedwait()) и не устанавливает обработчики для этих сигналов. В многонитиевых программах сигнал должен быть заблокирован во всех нитях, чтобы предотвратить возврат сигнала нити, отличной от той, которая вызвала sigwaitinfo() или sigtimedwait()).

Набор сигналов, ожидающих обработки в заданной нити, представляет собой объединение набора сигналов, ожидающих обработки именно в этой нити и набора сигналов, ожидающих обработки всем процессом (см. signal(7)).

Попытки ожидания SIGKILL и SIGSTOP просто игнорируются.

Если несколько нитей процесса заблокированы в ожидании одного сигнала(ов) в sigwaitinfo() или sigtimedwait(), то только одна нить действительно получит сигнал, если он станет доступен для ожидания всему процессу; какая именно нить примет сигнал неизвестно.

POSIX оставляет неопределённое значение NULL в аргументе timeout для sigtimedwait(), допуская возможность того, что он имеет такое же значение, как и у вызова sigwaitinfo(), и в самом деле это именно так в Linux.

Отличия между библиотекой C и ядром

В Linux, sigwaitinfo() реализована в виде библиотечной функции, использующей sigtimedwait().

Обёрточные функции glibc для sigwaitinfo() и sigtimedwait() просто игнорируют попытки ожидания двух сигналов реального времени, которые используются внутри реализации NPTL. Подробности смотрите в nptl(7).

Первоначально, системный вызов Linux назывался sigtimedwait(). Однако, с добавлением сигналов реального времени в Linux 2.2, 32-битный аргумент sigset_t неизменяемого размера, поддерживаемый этим системным вызовом, не мог больше использоваться. В результате был добавлен новый системный вызов rt_sigtimedwait() с увеличенным типом sigset_t. У нового системного вызова появился четвёртый аргумент, size_t sigsetsize, в котором указывается размер (в байтах) набора сигналов set. В настоящее время значение этого аргумента должно быть равно sizeof(sigset_t) (иначе возникает ошибка EINVAL). Обёрточная функция glibc sigtimedwait() скрывает это и вызывает rt_sigtimedwait(), если он есть в ядре.