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
11constexpr 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
42constexpr int no_change_act_signals[] = {
43 SIGKILL,
44 SIGSTOP,
45};
46
47void signal_handler(int) {}
48void signal_action_handler(int, siginfo_t*, void*) {}
49
50void test_signal_custom() {
51 for (int signum : std_signals) {
52 auto* ret = signal(sig: signum, handler: &signal_handler);
53 assert(ret != SIG_ERR);
54 }
55#ifdef SIGRTMIN
56 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
57 auto* ret = signal(sig: signum, handler: &signal_handler);
58 assert(ret != SIG_ERR);
59 }
60#endif
61 for (int signum : no_change_act_signals) {
62 auto* ret = signal(sig: signum, handler: &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(sig: signum, handler: &signal_handler);
74 int err = errno;
75 assert(ret == SIG_ERR);
76 assert(err == EINVAL);
77 }
78}
79
80void test_signal_ignore() {
81 for (int signum : std_signals) {
82 auto* ret = signal(sig: 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(sig: signum, SIG_IGN);
92 assert(ret != SIG_ERR);
93 }
94#endif
95 for (int signum : no_change_act_signals) {
96 auto* ret = signal(sig: 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(sig: signum, SIG_IGN);
108 int err = errno;
109 assert(ret == SIG_ERR);
110 assert(err == EINVAL);
111 }
112}
113
114void test_signal_default() {
115 for (int signum : std_signals) {
116 auto* ret = signal(sig: signum, SIG_DFL);
117 assert(ret != SIG_ERR);
118 }
119#ifdef SIGRTMIN
120 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
121 auto* ret = signal(sig: 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(sig: signum, SIG_DFL);
132 int err = errno;
133 assert(ret == SIG_ERR);
134 assert(err == EINVAL);
135 }
136}
137
138void test_sigaction_custom() {
139 struct sigaction act = {}, oldact;
140
141 act.sa_handler = &signal_handler;
142 sigemptyset(set: &act.sa_mask);
143 act.sa_flags = 0;
144
145 for (int signum : std_signals) {
146 int ret = sigaction(sig: signum, act: &act, oact: &oldact);
147 assert(ret == 0);
148 }
149#ifdef SIGRTMIN
150 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
151 int ret = sigaction(sig: signum, act: &act, oact: &oldact);
152 assert(ret == 0);
153 }
154#endif
155 for (int signum : no_change_act_signals) {
156 int ret = sigaction(sig: signum, act: &act, oact: &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(sig: signum, act: &act, oact: &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(sig: signum, act: &act, oact: &oldact);
179 assert(ret == 0);
180 }
181#ifdef SIGRTMIN
182 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
183 int ret = sigaction(sig: signum, act: &act, oact: &oldact);
184 assert(ret == 0);
185 }
186#endif
187 for (int signum : no_change_act_signals) {
188 int ret = sigaction(sig: signum, act: &act, oact: &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(sig: signum, act: &act, oact: &oldact);
200 int err = errno;
201 assert(ret == -1);
202 assert(err == EINVAL);
203 }
204}
205
206void test_sigaction_ignore() {
207 struct sigaction act = {}, oldact;
208
209 act.sa_handler = SIG_IGN;
210 sigemptyset(set: &act.sa_mask);
211 act.sa_flags = 0;
212
213 for (int signum : std_signals) {
214 int ret = sigaction(sig: signum, act: &act, oact: &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(sig: signum, act: &act, oact: &oldact);
224 assert(ret == 0);
225 }
226#endif
227 for (int signum : no_change_act_signals) {
228 int ret = sigaction(sig: signum, act: &act, oact: &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(sig: signum, act: &act, oact: &oldact);
240 int err = errno;
241 assert(ret == -1);
242 assert(err == EINVAL);
243 }
244}
245
246void test_sigaction_default() {
247 struct sigaction act = {}, oldact;
248
249 act.sa_handler = SIG_DFL;
250 sigemptyset(set: &act.sa_mask);
251 act.sa_flags = 0;
252
253 for (int signum : std_signals) {
254 int ret = sigaction(sig: signum, act: &act, oact: &oldact);
255 assert(ret == 0);
256 }
257#ifdef SIGRTMIN
258 for (int signum = SIGRTMIN; signum <= SIGRTMAX; ++signum) {
259 int ret = sigaction(sig: signum, act: &act, oact: &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(sig: signum, act: &act, oact: &oldact);
270 int err = errno;
271 assert(ret == -1);
272 assert(err == EINVAL);
273 }
274}
275
276int main(void) {
277 printf(format: "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

source code of compiler-rt/test/sanitizer_common/TestCases/Posix/signal.cpp