Сигналы в заданном параметре sigtimedwait() не доставляются

Недавно я работал над обработкой сигналов в Linux и прочитал все концепции, связанные с обработкой сигналов. Один вопрос, который мучает меня, заключается в том, почему сигнал в наборе sigtimedwait() не доставляется, пока процесс разблокирован. Мой код выглядит следующим образом: -

#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
void sighandler1(int sig)
{
        printf("SIGINT caught\n");
}
void sighandler2(int sig)
{
        printf("SIGTSTP caught\n");
}
void sighandler3(int sig)
{
        printf("SIGALRM caught\n");
}

int main()
{

  sigset_t s1,s2;

  struct sigaction act1,act2,act3;

  int ret;

  sigemptyset(&s1);// The bit-mask s1 is cleared
  sigaddset(&s1,SIGINT);//Add SIGINT to the bit-mask s1

  sigemptyset(&s2);// The bit-mask s2 is cleared
  sigaddset(&s2,SIGALRM);//Add SIGALRM to the bit-mask s2

  sigprocmask(SIG_BLOCK,&s2,NULL);//Signal(s) in s2 blocked

  act1.sa_handler = sighandler1; //function pointer pointing to the signal handler
  act1.sa_flags = 0;        

  sigaction(SIGINT,&act1,NULL);  // installing the action
                                 // for SIGINT

  act2.sa_handler = sighandler2; //function pointer pointing to another signal handler
  act2.sa_flags = 0;         // no flags


  sigaction(SIGTSTP,&act2,NULL);  // installing the action
                                 // for SIGTSTP
  act3.sa_handler = sighandler3; //function pointer pointing to another signal handler
  act3.sa_flags = 0;         // no flags


  sigaction(SIGALRM,&act3,NULL);  // installing the action for SIGALRM

  sigprocmask(SIG_SETMASK,&s1,NULL); //Signals in s1 blocked and other signals unblocked
  printf("sigprocmask() called with SIG_SETMASK on s1,which contains SIGINT\n");
  printf("Blocked on sigtimedwait() with s1\n");
  if(sigtimedwait(&s1,NULL,NULL) < 0)
        {
                if(errno ==  EINTR)
                printf("Some other signal caught\n");
        }
  printf("This is a process. You can pass signal to it\n");

  while(1);

}

Чтобы быть более ясным с вопросом, я вызвал sigtimedwait в приведенном выше коде с «s1» в качестве параметра «установить». Этот набор содержит только сигнал SIGINT. Согласно справочной странице, sigtimedwait() блокирует процесс до тех пор, пока не будет доставлен один из сигналов в его наборе. Меня все устраивает в этом утверждении. Но почему обработчик SIGINT не вызывается, когда я передаю SIGINT для разблокировки процесса? С другой стороны, когда я передаю SIGALRM или SIGTSTP, которых нет в наборе, EINTR возвращается, как и ожидалось, а также вызывается обработчик сигнала.

Любой, кто хочет наблюдать за сценарием, может выполнить приведенный выше код, а затем передать ему SIGINT. Они увидят, что процесс разблокирован без вызова обработчика. Почему обработчик не вызывается? Я неправильно интерпретирую какую-либо часть справочной страницы sigtimedwait()??


person Shubham_K    schedule 17.04.2016    source источник
comment
Кто-нибудь может посмотреть на это? Заранее спасибо.   -  person Shubham_K    schedule 17.04.2016


Ответы (1)


sigtimedwait, кажется, возвращает значение сигнала вместо того, чтобы поймать обработчик сигнала:

switch(sigtimedwait(&s1,NULL,NULL))
{
    default:
        printf ("Some other signal???");
        break;
    case SIGINT:
        printf ("We got SIGINT\n");
        break;
    case -1:
        perror ("sigtimedwait");
        break;
}
person Stian Skjelstad    schedule 22.04.2016
comment
Глядя на справочную страницу, ожидается следующее: sigwaitinfo() удаляет сигнал из набора ожидающих сигналов и возвращает номер сигнала в качестве результата своей функции. Если аргумент info не равен NULL, то буфер, на который он указывает, используется для возврата структуры типа siginfo_t (см. sigaction(2)), содержащей информацию о сигнале. - person Stian Skjelstad; 22.04.2016
comment
Тогда как насчет следующего утверждения, упомянутого в самой первой строке DESCRIPTION на странице руководства: sigwaitinfo() приостанавливает выполнение вызывающего потока до тех пор, пока не будет доставлен один из сигналов в наборе. Он действительно говорит что сигнал должен быть доставлен. Однако я вижу, что сигнал в наборе не доставляется, но сигналы не в наборе доставляются с вызовом обработчика. - person Shubham_K; 22.04.2016
comment
Вы блокируете SIGINT только в своем вызове sigprocmask(), поэтому другие сигналы могут проходить (заставляя sigtimedwait возвращать -1 и устанавливая errno в EINTR). После sigtimedwait сигнал SIGINT по-прежнему заблокирован и не может быть получен. С поставленной формулировкой они означают, что она больше не находится в очереди ядра. В этом случае sigtimedwait является получателем сигнала. - person Stian Skjelstad; 23.04.2016
comment
Хорошо, позвольте мне не блокировать SIGINT. Итак, несмотря на то, что я комментирую следующую строку sigprocmask(SIG_SETMASK,&s1,NULL); , сигнал SIGINT по-прежнему не доставляется, когда процесс разблокирован. Хотя он доставляется позже, когда процесс больше не блокируется на sigtimedwait() . Как это происходит тогда? - person Shubham_K; 23.04.2016
comment
Что вы имеете в виду под утверждением - они означают, что его больше нет в очереди ядра. В этом случае sigtimedwait является получателем сигнала. Означает ли это, что sigtimedwait() отвечает только за перехват сигнала, а не за передачу его обработчику?? Что-то такое? - person Shubham_K; 23.04.2016
comment
Правильно, sigtimedwait не пересылает его обработчику. - person Stian Skjelstad; 23.04.2016