1 // RUN: %clangxx -std=c++11 -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
2
3 #include <assert.h>
4 #include <climits>
5 #include <errno.h>
6 #include <stdio.h>
7 #include <signal.h>
8
9 #include <initializer_list>
10
11 constexpr int std_signals[] = {
12 SIGHUP,
13 SIGINT,
14 SIGQUIT,
15 SIGILL,
16 SIGTRAP,
17 SIGABRT,
18 SIGIOT,
19 SIGBUS,
20 SIGFPE,
21 SIGUSR1,
22 SIGSEGV,
23 SIGUSR2,
24 SIGPIPE,
25 SIGALRM,
26 SIGTERM,
27 SIGCHLD,
28 SIGCONT,
29 SIGTSTP,
30 SIGTTIN,
31 SIGTTOU,
32 SIGURG,
33 SIGXCPU,
34 SIGXFSZ,
35 SIGVTALRM,
36 SIGPROF,
37 SIGWINCH,
38 SIGIO,
39 SIGSYS,
40 };
41
42 constexpr int no_change_act_signals[] = {
43 SIGKILL,
44 SIGSTOP,
45 };
46
signal_handler(int)47 void signal_handler(int) {}
signal_action_handler(int,siginfo_t *,void *)48 void signal_action_handler(int, siginfo_t*, void*) {}
49
test_signal_custom()50 void test_signal_custom() {
51 for (int signum : std_signals) {
52 auto* ret = signal(signum, &signal_handler);
53 assert(ret != SIG_ERR);
54 }
55 #ifdef SIGRTMIN
56 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
57 auto* ret = signal(signum, &signal_handler);
58 assert(ret != SIG_ERR);
59 }
60 #endif
61 for (int signum : no_change_act_signals) {
62 auto* ret = signal(signum, &signal_handler);
63 int err = errno;
64 assert(ret == SIG_ERR);
65 assert(err == EINVAL);
66 }
67 for (int signum : {
68 0,
69 #ifdef SIGRTMAX
70 SIGRTMAX + 1,
71 #endif
72 INT_MAX}) {
73 auto* ret = signal(signum, &signal_handler);
74 int err = errno;
75 assert(ret == SIG_ERR);
76 assert(err == EINVAL);
77 }
78 }
79
test_signal_ignore()80 void test_signal_ignore() {
81 for (int signum : std_signals) {
82 auto* ret = signal(signum, SIG_IGN);
83 if (signum != SIGCHLD) {
84 // POSIX.1-1990 disallowed setting the action for SIGCHLD to SIG_IGN
85 // though POSIX.1-2001 and later allow this possibility.
86 assert(ret != SIG_ERR);
87 }
88 }
89 #ifdef SIGRTMIN
90 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
91 auto* ret = signal(signum, SIG_IGN);
92 assert(ret != SIG_ERR);
93 }
94 #endif
95 for (int signum : no_change_act_signals) {
96 auto* ret = signal(signum, SIG_IGN);
97 int err = errno;
98 assert(ret == SIG_ERR);
99 assert(err == EINVAL);
100 }
101 for (int signum : {
102 0,
103 #ifdef SIGRTMAX
104 SIGRTMAX + 1,
105 #endif
106 INT_MAX}) {
107 auto* ret = signal(signum, SIG_IGN);
108 int err = errno;
109 assert(ret == SIG_ERR);
110 assert(err == EINVAL);
111 }
112 }
113
test_signal_default()114 void test_signal_default() {
115 for (int signum : std_signals) {
116 auto* ret = signal(signum, SIG_DFL);
117 assert(ret != SIG_ERR);
118 }
119 #ifdef SIGRTMIN
120 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
121 auto* ret = signal(signum, SIG_DFL);
122 assert(ret != SIG_ERR);
123 }
124 #endif
125 for (int signum : {
126 0,
127 #ifdef SIGRTMAX
128 SIGRTMAX + 1,
129 #endif
130 INT_MAX}) {
131 auto* ret = signal(signum, SIG_DFL);
132 int err = errno;
133 assert(ret == SIG_ERR);
134 assert(err == EINVAL);
135 }
136 }
137
test_sigaction_custom()138 void test_sigaction_custom() {
139 struct sigaction act = {}, oldact;
140
141 act.sa_handler = &signal_handler;
142 sigemptyset(&act.sa_mask);
143 act.sa_flags = 0;
144
145 for (int signum : std_signals) {
146 int ret = sigaction(signum, &act, &oldact);
147 assert(ret == 0);
148 }
149 #ifdef SIGRTMIN
150 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
151 int ret = sigaction(signum, &act, &oldact);
152 assert(ret == 0);
153 }
154 #endif
155 for (int signum : no_change_act_signals) {
156 int ret = sigaction(signum, &act, &oldact);
157 int err = errno;
158 assert(ret == -1);
159 assert(err == EINVAL);
160 }
161 for (int signum : {
162 0,
163 #ifdef SIGRTMAX
164 SIGRTMAX + 1,
165 #endif
166 INT_MAX}) {
167 int ret = sigaction(signum, &act, &oldact);
168 int err = errno;
169 assert(ret == -1);
170 assert(err == EINVAL);
171 }
172
173 act.sa_handler = nullptr;
174 act.sa_sigaction = &signal_action_handler;
175 act.sa_flags = SA_SIGINFO;
176
177 for (int signum : std_signals) {
178 int ret = sigaction(signum, &act, &oldact);
179 assert(ret == 0);
180 }
181 #ifdef SIGRTMIN
182 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
183 int ret = sigaction(signum, &act, &oldact);
184 assert(ret == 0);
185 }
186 #endif
187 for (int signum : no_change_act_signals) {
188 int ret = sigaction(signum, &act, &oldact);
189 int err = errno;
190 assert(ret == -1);
191 assert(err == EINVAL);
192 }
193 for (int signum : {
194 0,
195 #ifdef SIGRTMAX
196 SIGRTMAX + 1,
197 #endif
198 INT_MAX}) {
199 int ret = sigaction(signum, &act, &oldact);
200 int err = errno;
201 assert(ret == -1);
202 assert(err == EINVAL);
203 }
204 }
205
test_sigaction_ignore()206 void test_sigaction_ignore() {
207 struct sigaction act = {}, oldact;
208
209 act.sa_handler = SIG_IGN;
210 sigemptyset(&act.sa_mask);
211 act.sa_flags = 0;
212
213 for (int signum : std_signals) {
214 int ret = sigaction(signum, &act, &oldact);
215 if (signum != SIGCHLD) {
216 // POSIX.1-1990 disallowed setting the action for SIGCHLD to SIG_IGN
217 // though POSIX.1-2001 and later allow this possibility.
218 assert(ret == 0);
219 }
220 }
221 #ifdef SIGRTMIN
222 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
223 int ret = sigaction(signum, &act, &oldact);
224 assert(ret == 0);
225 }
226 #endif
227 for (int signum : no_change_act_signals) {
228 int ret = sigaction(signum, &act, &oldact);
229 int err = errno;
230 assert(ret == -1);
231 assert(err == EINVAL);
232 }
233 for (int signum : {
234 0,
235 #ifdef SIGRTMAX
236 SIGRTMAX + 1,
237 #endif
238 INT_MAX}) {
239 int ret = sigaction(signum, &act, &oldact);
240 int err = errno;
241 assert(ret == -1);
242 assert(err == EINVAL);
243 }
244 }
245
test_sigaction_default()246 void test_sigaction_default() {
247 struct sigaction act = {}, oldact;
248
249 act.sa_handler = SIG_DFL;
250 sigemptyset(&act.sa_mask);
251 act.sa_flags = 0;
252
253 for (int signum : std_signals) {
254 int ret = sigaction(signum, &act, &oldact);
255 assert(ret == 0);
256 }
257 #ifdef SIGRTMIN
258 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
259 int ret = sigaction(signum, &act, &oldact);
260 assert(ret == 0);
261 }
262 #endif
263 for (int signum : {
264 0,
265 #ifdef SIGRTMAX
266 SIGRTMAX + 1,
267 #endif
268 INT_MAX}) {
269 int ret = sigaction(signum, &act, &oldact);
270 int err = errno;
271 assert(ret == -1);
272 assert(err == EINVAL);
273 }
274 }
275
main(void)276 int main(void) {
277 printf("sigaction\n");
278
279 test_signal_custom();
280 test_signal_ignore();
281 test_signal_default();
282
283 test_sigaction_custom();
284 test_sigaction_ignore();
285 test_sigaction_default();
286
287 // CHECK: sigaction
288
289 return 0;
290 }
291