用sigsetjmp和siglongjmp 解决从信号处理程序返回后信号仍被屏蔽问题

来源:互联网 发布:淘宝怎么改差评为好评 编辑:程序博客网 时间:2024/05/19 12:12

通过canjump变量提供一种保护机制,使得在jmpbuf尚未由sigsetjmp初始化时,防止调用信号处理函数。

一、源代码:

:cat -n 10_14.c 10_20.c
     1  #include "apue.h"
     2  #include <errno.h>
     3
     4  void pr_mask(const char *str)
     5  {
     6          int saved_errno;
     7          sigset_t sigset;
     8
     9          saved_errno = errno;
    10          if (sigprocmask(0,NULL,&sigset) < 0){
    11                  err_ret("sigpromask error");
    12          }
    13          else{
    14                  printf("%s",str);
    15                  if(sigismember(&sigset,SIGINT))
    16                          printf(" SIGINT");
    17                  if(sigismember(&sigset,SIGQUIT))
    18                          printf(" SIGQUIT");
    19                 if(sigismember(&sigset,SIGUSR1))
    20                          printf(" SIGUSR1");
    21                  if (sigismember(&sigset,SIGALRM))
    22                          printf(" SIGALRM");
    23
    24
    25                  printf("\n");
    26          }
    27          errno = saved_errno;
    28  }
     1  #include "apue.h"
     2  #include <setjmp.h>
     3  #include <time.h>
     4
     5  static void sig_user1(int signo);
     6  static void sig_alarm(int signo);
     7  static sigjmp_buf jmpbuf;
     8  static volatile sig_atomic_t canjump;
     9
    10  int main(void)
    11  {
    12          if (signal(SIGUSR1,sig_user1) == SIG_ERR)
    13                  err_sys("SIGUSER1 handler establish error");
    14          if (signal(SIGALRM,sig_alarm) == SIG_ERR)
    15                  err_sys("SIGALARM handler eatablish error");
    16
    17          pr_mask("starting main:");
    18
    19          if (sigsetjmp(jmpbuf,1)){
    20                  pr_mask("Ending main:");
    21                  exit(0);
    22          }
    23          canjump = 1;
    24
    25          for (;;){
    26                  pause();
    27          }
    28  }
    29
    30
    31  static void sig_user1(int signo)
    32  {
    33          time_t start_time;
    34          if (canjump == 0){
    35                  return;
    36          }
    37
    38          pr_mask("starting sig_user1:");
    39          alarm(3);
    40          start_time = time(NULL);
    41          for(;;){
    42                  if (time(NULL) > start_time + 5)
    43                          break;
    44          }
    45          pr_mask("ending sig_user1:");
    46          canjump = 0;
    47          siglongjmp(jmpbuf,1);
    48
    49  }
    50
    51
    52  static void sig_alarm(int signo)
    53  {
    54          pr_mask("sig_alarm:");
    55  }

0 0
原创粉丝点击