Время ожидания recvfrom () с сигнализацией () - PullRequest
7 голосов
/ 08 мая 2011

Я отлаживаю следующий код:

signal(SIGALRM, testt);                                                  
alarm(1);                                                                
result = recvfrom( listening_socket, buf, maxlen, 0, &from, &fromlen );  
printf("stoped\n");          

Как описано в man 3 siginterrupt, сигнал тревоги должен прерывать системный вызов, но в моем случае это не так. Обработчик тревоги вызывается, но recvfrom не прерывается.

Однако, когда новый обработчик сигнала указан с помощью функции signal (2), системный вызов по умолчанию прерывается.

Если я добавлю siginterrupt(SIGALRM, 1); после установки обработчика тревоги, то recvfrom будет прерван, как и ожидалось.

Чего мне не хватает? Что не так с моим кодом?

ПРИМЕЧАНИЯ. Замена signal на sigaction - это не то, что я ищу.

1 Ответ

9 голосов
/ 08 мая 2011

Страница man siginterrupt(3) неверна ( версия 3.33 из набора страниц man Linux исправляет ошибку). Поведение по умолчанию signal в glibc заключается в установлении сигнала, который не прерывает системные вызовы. Вы можете убедиться в этом сами с помощью strace:

void handler(int unused) {}
int main(void)
{
  signal(SIGALRM, handler);
}

& Longrightarrow;

$ strace -e trace=rt_sigaction ./a.out
rt_sigaction(SIGALRM, 
             {0x4005b4, [ALRM], SA_RESTORER|SA_RESTART, 0x7fe732d3d490}, 
             {SIG_DFL, [], 0}, 8) = 0

Обратите внимание на SA_RESTART там. Вы можете либо продолжать делать то, что делаете - позвоните по номеру siginterrupt(SIGALRM, 1) после установки обработчика - либо вы можете переключиться на использование sigaction, что позволит вам сначала установить флаги так, как вы хотите. Вы сказали, что не хотите этого делать (почему?), Но тем не менее это то, что я бы порекомендовал.

...