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

source code of glibc/signal/tst-sigset2.c