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