test sigsetjmp with savesigs=0
[libc-test] / src / functional / setjmp.c
1 #include <string.h>
2 #include <signal.h>
3 #include <setjmp.h>
4 #include "test.h"
5
6 #define TEST(c, ...) ((c) ? 1 : (t_error(#c" failed: " __VA_ARGS__),0))
7
8 int main(void)
9 {
10         volatile int x = 0, r;
11         jmp_buf jb;
12         sigjmp_buf sjb;
13         volatile sigset_t oldset;
14         sigset_t set;
15
16         if (!setjmp(jb)) {
17                 x = 1;
18                 longjmp(jb, 1);
19         }
20         TEST(x==1, "setjmp/longjmp seems to have been bypassed\n");
21
22         x = 0;
23         r = setjmp(jb);
24         if (!x) {
25                 x = 1;
26                 longjmp(jb, 0);
27         }
28         TEST(r==1, "longjmp(jb, 0) caused setjmp to return %d\n", r);
29
30         sigemptyset(&set);
31         sigaddset(&set, SIGUSR1);
32         sigprocmask(SIG_UNBLOCK, &set, &set);
33         oldset = set;
34
35         /* Improve the chances of catching failure of sigsetjmp to
36          * properly save the signal mask in the sigjmb_buf. */
37         memset(&sjb, -1, sizeof sjb);
38
39         if (!sigsetjmp(sjb, 1)) {
40                 sigemptyset(&set);
41                 sigaddset(&set, SIGUSR1);
42                 sigprocmask(SIG_BLOCK, &set, 0);
43                 siglongjmp(sjb, 1);
44         }
45         set = oldset;
46         sigprocmask(SIG_SETMASK, &set, &set);
47         TEST(sigismember(&set, SIGUSR1)==0, "siglongjmp failed to restore mask\n");
48
49         sigemptyset(&set);
50         sigaddset(&set, SIGUSR1);
51         sigprocmask(SIG_UNBLOCK, &set, &set);
52         oldset = set;
53
54         if (!sigsetjmp(sjb, 0)) {
55                 sigemptyset(&set);
56                 sigaddset(&set, SIGUSR1);
57                 sigprocmask(SIG_BLOCK, &set, 0);
58                 siglongjmp(sjb, 1);
59         }
60         set = oldset;
61         sigprocmask(SIG_SETMASK, &set, &set);
62         TEST(sigismember(&set, SIGUSR1)==1, "siglongjmp incorrectly restored mask\n");
63
64         return t_status;
65 }