2.5-18.1
[jlayton/glibc.git] / signal / tst-sigset2.c
1 /* sigset_SIG_HOLD_bug.c [BZ #1951] */
2 #include <errno.h>
3 #include <error.h>
4 #include <inttypes.h>
5 #include <signal.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <sys/types.h>
11 #include <sys/wait.h>
12
13 #define TEST_SIG SIGINT
14
15
16 /* Print mask of blocked signals for this process */
17 static void
18 printSigMask (const char *msg)
19 {
20   sigset_t currMask;
21   int sig;
22   int cnt;
23
24   if (msg != NULL)
25     printf ("%s", msg);
26
27   if (sigprocmask (SIG_BLOCK, NULL, &currMask) == -1)
28     error (1, errno, "sigaction");
29
30   cnt = 0;
31   for (sig = 1; sig < NSIG; sig++)
32     {
33       if (sigismember (&currMask, sig))
34         {
35           cnt++;
36           printf ("\t\t%d (%s)\n", sig, strsignal (sig));
37         }
38     }
39
40   if (cnt == 0)
41     printf ("\t\t<empty signal set>\n");
42 } /* printSigMask */
43
44 static void
45 handler (int sig)
46 {
47   printf ("Caught signal %d\n", sig);
48   printSigMask ("Signal mask in handler\n");
49   printf ("Handler returning\n");
50   _exit (1);
51 } /* handler */
52
53 static void
54 printDisposition (sighandler_t disp)
55 {
56   if (disp == SIG_HOLD)
57     printf ("SIG_HOLD");
58   else if (disp == SIG_DFL)
59     printf ("SIG_DFL");
60   else if (disp == SIG_IGN)
61     printf ("SIG_IGN");
62   else
63     printf ("handled at %" PRIxPTR, (uintptr_t) disp);
64 } /* printDisposition */
65
66 static int
67 returnTest1 (void)
68 {
69   sighandler_t prev;
70
71   printf ("===== TEST 1 =====\n");
72   printf ("Blocking signal with sighold()\n");
73   if (sighold (TEST_SIG) == -1)
74     error (1, errno, "sighold");
75   printSigMask ("Signal mask after sighold()\n");
76
77   printf ("About to use sigset() to establish handler\n");
78   prev = sigset (TEST_SIG, handler);
79   if (prev == SIG_ERR)
80     error(1, errno, "sigset");
81
82   printf ("Previous disposition: ");
83   printDisposition (prev);
84   printf (" (should be SIG_HOLD)\n");
85   if (prev != SIG_HOLD)
86     {
87       printf("TEST FAILED!!!\n");
88       return 1;
89     }
90   return 0;
91 } /* returnTest1 */
92
93 static int
94 returnTest2 (void)
95 {
96   sighandler_t prev;
97
98   printf ("\n===== TEST 2 =====\n");
99
100   printf ("About to use sigset() to set SIG_HOLD\n");
101   prev = sigset (TEST_SIG, SIG_HOLD);
102   if (prev == SIG_ERR)
103     error (1, errno, "sigset");
104
105   printf ("Previous disposition: ");
106   printDisposition (prev);
107   printf (" (should be SIG_DFL)\n");
108   if (prev != SIG_DFL)
109     {
110       printf("TEST FAILED!!!\n");
111       return 1;
112     }
113   return 0;
114 } /* returnTest2 */
115
116 static int
117 returnTest3 (void)
118 {
119   sighandler_t prev;
120
121   printf ("\n===== TEST 3 =====\n");
122
123   printf ("About to use sigset() to set SIG_HOLD\n");
124   prev = sigset (TEST_SIG, SIG_HOLD);
125   if (prev == SIG_ERR)
126     error (1, errno, "sigset");
127
128   printf ("About to use sigset() to set SIG_HOLD (again)\n");
129   prev = sigset (TEST_SIG, SIG_HOLD);
130   if (prev == SIG_ERR)
131     error (1, errno, "sigset");
132
133   printf ("Previous disposition: ");
134   printDisposition (prev);
135   printf (" (should be SIG_HOLD)\n");
136   if (prev != SIG_HOLD)
137     {
138       printf("TEST FAILED!!!\n");
139       return 1;
140     }
141   return 0;
142 } /* returnTest3 */
143
144 int
145 main (int argc, char *argv[])
146 {
147   pid_t childPid;
148
149   childPid = fork();
150   if (childPid == -1)
151     error (1, errno, "fork");
152
153   if (childPid == 0)
154     exit (returnTest1 ());
155
156   int status;
157   if (TEMP_FAILURE_RETRY (waitpid (childPid, &status, 0)) != childPid)
158     error (1, errno, "waitpid");
159   int result = !WIFEXITED (status) || WEXITSTATUS (status) != 0;
160
161   childPid = fork();
162   if (childPid == -1)
163     error (1, errno, "fork");
164
165   if (childPid == 0)
166     exit (returnTest2 ());
167
168   if (TEMP_FAILURE_RETRY (waitpid (childPid, &status, 0)) != childPid)
169     error (1, errno, "waitpid");
170   result |= !WIFEXITED (status) || WEXITSTATUS (status) != 0;
171
172   childPid = fork();
173   if (childPid == -1)
174     error (1, errno, "fork");
175
176   if (childPid == 0)
177     exit (returnTest3 ());
178
179   if (TEMP_FAILURE_RETRY (waitpid (childPid, &status, 0)) != childPid)
180     error (1, errno, "waitpid");
181   result |= !WIFEXITED (status) || WEXITSTATUS (status) != 0;
182
183   return result;
184 } /* main */