通过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 }