1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /* Copyright (c) Jiri Palecek<[email protected]>, 2009 */
3*49cdfc7eSAndroid Build Coastguard Worker
4*49cdfc7eSAndroid Build Coastguard Worker #define TST_NO_DEFAULT_MAIN
5*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
6*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
7*49cdfc7eSAndroid Build Coastguard Worker #include <limits.h>
8*49cdfc7eSAndroid Build Coastguard Worker #include "libsigwait.h"
9*49cdfc7eSAndroid Build Coastguard Worker #include "tst_sig_proc.h"
10*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/syscalls.h"
11*49cdfc7eSAndroid Build Coastguard Worker
test_empty_set(swi_func sigwaitinfo,int signo,enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)12*49cdfc7eSAndroid Build Coastguard Worker void test_empty_set(swi_func sigwaitinfo, int signo,
13*49cdfc7eSAndroid Build Coastguard Worker enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)
14*49cdfc7eSAndroid Build Coastguard Worker {
15*49cdfc7eSAndroid Build Coastguard Worker sigset_t sigs;
16*49cdfc7eSAndroid Build Coastguard Worker siginfo_t si;
17*49cdfc7eSAndroid Build Coastguard Worker pid_t child;
18*49cdfc7eSAndroid Build Coastguard Worker
19*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGEMPTYSET(&sigs);
20*49cdfc7eSAndroid Build Coastguard Worker
21*49cdfc7eSAndroid Build Coastguard Worker /* Run a child that will wake us up */
22*49cdfc7eSAndroid Build Coastguard Worker child = create_sig_proc(signo, INT_MAX, 100000);
23*49cdfc7eSAndroid Build Coastguard Worker
24*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo(&sigs, &si, NULL));
25*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1) {
26*49cdfc7eSAndroid Build Coastguard Worker if (TST_ERR == EINTR)
27*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "Wait interrupted by expected signal");
28*49cdfc7eSAndroid Build Coastguard Worker else
29*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "Expected error number EINTR, got");
30*49cdfc7eSAndroid Build Coastguard Worker } else {
31*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "Expected return value -1, got: %ld", TST_RET);
32*49cdfc7eSAndroid Build Coastguard Worker }
33*49cdfc7eSAndroid Build Coastguard Worker
34*49cdfc7eSAndroid Build Coastguard Worker SAFE_KILL(child, SIGTERM);
35*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAIT(NULL);
36*49cdfc7eSAndroid Build Coastguard Worker }
37*49cdfc7eSAndroid Build Coastguard Worker
test_timeout(swi_func sigwaitinfo,int signo,enum tst_ts_type type)38*49cdfc7eSAndroid Build Coastguard Worker void test_timeout(swi_func sigwaitinfo, int signo, enum tst_ts_type type)
39*49cdfc7eSAndroid Build Coastguard Worker {
40*49cdfc7eSAndroid Build Coastguard Worker sigset_t sigs;
41*49cdfc7eSAndroid Build Coastguard Worker siginfo_t si;
42*49cdfc7eSAndroid Build Coastguard Worker pid_t child;
43*49cdfc7eSAndroid Build Coastguard Worker struct tst_ts ts;
44*49cdfc7eSAndroid Build Coastguard Worker
45*49cdfc7eSAndroid Build Coastguard Worker ts.type = type;
46*49cdfc7eSAndroid Build Coastguard Worker tst_ts_set_sec(&ts, 1);
47*49cdfc7eSAndroid Build Coastguard Worker tst_ts_set_nsec(&ts, 0);
48*49cdfc7eSAndroid Build Coastguard Worker
49*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGEMPTYSET(&sigs);
50*49cdfc7eSAndroid Build Coastguard Worker
51*49cdfc7eSAndroid Build Coastguard Worker /* Run a child that will wake us up */
52*49cdfc7eSAndroid Build Coastguard Worker child = create_sig_proc(signo, INT_MAX, 100000);
53*49cdfc7eSAndroid Build Coastguard Worker
54*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo(&sigs, &si, tst_ts_get(&ts)));
55*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1) {
56*49cdfc7eSAndroid Build Coastguard Worker if (TST_ERR == EAGAIN)
57*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "Wait interrupted by timeout");
58*49cdfc7eSAndroid Build Coastguard Worker else
59*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "Expected error number EAGAIN, got");
60*49cdfc7eSAndroid Build Coastguard Worker } else {
61*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "Expected return value -1, got: %ld", TST_RET);
62*49cdfc7eSAndroid Build Coastguard Worker }
63*49cdfc7eSAndroid Build Coastguard Worker
64*49cdfc7eSAndroid Build Coastguard Worker SAFE_KILL(child, SIGTERM);
65*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAIT(NULL);
66*49cdfc7eSAndroid Build Coastguard Worker }
67*49cdfc7eSAndroid Build Coastguard Worker
68*49cdfc7eSAndroid Build Coastguard Worker /* Note: sigwait-ing for a signal that is not blocked is unspecified
69*49cdfc7eSAndroid Build Coastguard Worker * by POSIX; but works for non-ignored signals under Linux
70*49cdfc7eSAndroid Build Coastguard Worker */
test_unmasked_matching(swi_func sigwaitinfo,int signo,enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)71*49cdfc7eSAndroid Build Coastguard Worker void test_unmasked_matching(swi_func sigwaitinfo, int signo,
72*49cdfc7eSAndroid Build Coastguard Worker enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)
73*49cdfc7eSAndroid Build Coastguard Worker {
74*49cdfc7eSAndroid Build Coastguard Worker sigset_t sigs;
75*49cdfc7eSAndroid Build Coastguard Worker siginfo_t si;
76*49cdfc7eSAndroid Build Coastguard Worker pid_t child;
77*49cdfc7eSAndroid Build Coastguard Worker
78*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGEMPTYSET(&sigs);
79*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, signo);
80*49cdfc7eSAndroid Build Coastguard Worker
81*49cdfc7eSAndroid Build Coastguard Worker /* Run a child that will wake us up */
82*49cdfc7eSAndroid Build Coastguard Worker child = create_sig_proc(signo, INT_MAX, 100000);
83*49cdfc7eSAndroid Build Coastguard Worker
84*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo(&sigs, &si, NULL));
85*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == signo) {
86*49cdfc7eSAndroid Build Coastguard Worker if (si.si_pid == child && si.si_code == SI_USER &&
87*49cdfc7eSAndroid Build Coastguard Worker si.si_signo == signo)
88*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "struct siginfo is correct");
89*49cdfc7eSAndroid Build Coastguard Worker else
90*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "struct siginfo mismatch");
91*49cdfc7eSAndroid Build Coastguard Worker } else {
92*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "sigwaitinfo() failed");
93*49cdfc7eSAndroid Build Coastguard Worker }
94*49cdfc7eSAndroid Build Coastguard Worker
95*49cdfc7eSAndroid Build Coastguard Worker SAFE_KILL(child, SIGTERM);
96*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAIT(NULL);
97*49cdfc7eSAndroid Build Coastguard Worker }
98*49cdfc7eSAndroid Build Coastguard Worker
test_unmasked_matching_noinfo(swi_func sigwaitinfo,int signo,enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)99*49cdfc7eSAndroid Build Coastguard Worker void test_unmasked_matching_noinfo(swi_func sigwaitinfo, int signo,
100*49cdfc7eSAndroid Build Coastguard Worker enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)
101*49cdfc7eSAndroid Build Coastguard Worker {
102*49cdfc7eSAndroid Build Coastguard Worker sigset_t sigs;
103*49cdfc7eSAndroid Build Coastguard Worker pid_t child;
104*49cdfc7eSAndroid Build Coastguard Worker
105*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGEMPTYSET(&sigs);
106*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, signo);
107*49cdfc7eSAndroid Build Coastguard Worker
108*49cdfc7eSAndroid Build Coastguard Worker /* Run a child that will wake us up */
109*49cdfc7eSAndroid Build Coastguard Worker child = create_sig_proc(signo, INT_MAX, 100000);
110*49cdfc7eSAndroid Build Coastguard Worker
111*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo(&sigs, NULL, NULL));
112*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == signo)
113*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "Wait interrupted by expected signal");
114*49cdfc7eSAndroid Build Coastguard Worker else
115*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "sigwaitinfo() failed");
116*49cdfc7eSAndroid Build Coastguard Worker
117*49cdfc7eSAndroid Build Coastguard Worker SAFE_KILL(child, SIGTERM);
118*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAIT(NULL);
119*49cdfc7eSAndroid Build Coastguard Worker }
120*49cdfc7eSAndroid Build Coastguard Worker
test_masked_matching(swi_func sigwaitinfo,int signo,enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)121*49cdfc7eSAndroid Build Coastguard Worker void test_masked_matching(swi_func sigwaitinfo, int signo,
122*49cdfc7eSAndroid Build Coastguard Worker enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)
123*49cdfc7eSAndroid Build Coastguard Worker {
124*49cdfc7eSAndroid Build Coastguard Worker sigset_t sigs, oldmask;
125*49cdfc7eSAndroid Build Coastguard Worker siginfo_t si;
126*49cdfc7eSAndroid Build Coastguard Worker pid_t child;
127*49cdfc7eSAndroid Build Coastguard Worker
128*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGEMPTYSET(&sigs);
129*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, signo);
130*49cdfc7eSAndroid Build Coastguard Worker
131*49cdfc7eSAndroid Build Coastguard Worker /* let's not get interrupted by our dying child */
132*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, SIGCHLD);
133*49cdfc7eSAndroid Build Coastguard Worker
134*49cdfc7eSAndroid Build Coastguard Worker TEST(sigprocmask(SIG_SETMASK, &sigs, &oldmask));
135*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1)
136*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "sigprocmask() failed");
137*49cdfc7eSAndroid Build Coastguard Worker
138*49cdfc7eSAndroid Build Coastguard Worker /* don't wait on a SIGCHLD */
139*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGDELSET(&sigs, SIGCHLD);
140*49cdfc7eSAndroid Build Coastguard Worker
141*49cdfc7eSAndroid Build Coastguard Worker /* Run a child that will wake us up */
142*49cdfc7eSAndroid Build Coastguard Worker child = create_sig_proc(signo, 1, 0);
143*49cdfc7eSAndroid Build Coastguard Worker
144*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo(&sigs, &si, NULL));
145*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == signo) {
146*49cdfc7eSAndroid Build Coastguard Worker if (si.si_pid == child && si.si_code == SI_USER &&
147*49cdfc7eSAndroid Build Coastguard Worker si.si_signo == signo)
148*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "struct siginfo is correct");
149*49cdfc7eSAndroid Build Coastguard Worker else
150*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "struct siginfo mismatch");
151*49cdfc7eSAndroid Build Coastguard Worker } else {
152*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "sigwaitinfo() failed");
153*49cdfc7eSAndroid Build Coastguard Worker }
154*49cdfc7eSAndroid Build Coastguard Worker
155*49cdfc7eSAndroid Build Coastguard Worker TEST(sigprocmask(SIG_SETMASK, &oldmask, &sigs));
156*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1)
157*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "restoring original signal mask failed");
158*49cdfc7eSAndroid Build Coastguard Worker
159*49cdfc7eSAndroid Build Coastguard Worker if (sigismember(&sigs, signo))
160*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "sigwaitinfo restored the original mask");
161*49cdfc7eSAndroid Build Coastguard Worker else
162*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL,
163*49cdfc7eSAndroid Build Coastguard Worker "sigwaitinfo failed to restore the original mask");
164*49cdfc7eSAndroid Build Coastguard Worker
165*49cdfc7eSAndroid Build Coastguard Worker SAFE_KILL(child, SIGTERM);
166*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAIT(NULL);
167*49cdfc7eSAndroid Build Coastguard Worker }
168*49cdfc7eSAndroid Build Coastguard Worker
test_masked_matching_rt(swi_func sigwaitinfo,int signo,enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)169*49cdfc7eSAndroid Build Coastguard Worker void test_masked_matching_rt(swi_func sigwaitinfo, int signo,
170*49cdfc7eSAndroid Build Coastguard Worker enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)
171*49cdfc7eSAndroid Build Coastguard Worker {
172*49cdfc7eSAndroid Build Coastguard Worker sigset_t sigs, oldmask;
173*49cdfc7eSAndroid Build Coastguard Worker siginfo_t si;
174*49cdfc7eSAndroid Build Coastguard Worker pid_t child[2];
175*49cdfc7eSAndroid Build Coastguard Worker int status;
176*49cdfc7eSAndroid Build Coastguard Worker
177*49cdfc7eSAndroid Build Coastguard Worker signo = SIGRTMIN + 1;
178*49cdfc7eSAndroid Build Coastguard Worker
179*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGEMPTYSET(&sigs);
180*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, signo);
181*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, signo + 1);
182*49cdfc7eSAndroid Build Coastguard Worker
183*49cdfc7eSAndroid Build Coastguard Worker /* let's not get interrupted by our dying child */
184*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, SIGCHLD);
185*49cdfc7eSAndroid Build Coastguard Worker
186*49cdfc7eSAndroid Build Coastguard Worker TEST(sigprocmask(SIG_SETMASK, &sigs, &oldmask));
187*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1)
188*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "sigprocmask() failed");
189*49cdfc7eSAndroid Build Coastguard Worker
190*49cdfc7eSAndroid Build Coastguard Worker /* don't wait on a SIGCHLD */
191*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGDELSET(&sigs, SIGCHLD);
192*49cdfc7eSAndroid Build Coastguard Worker
193*49cdfc7eSAndroid Build Coastguard Worker /* Run a child that will wake us up */
194*49cdfc7eSAndroid Build Coastguard Worker child[0] = create_sig_proc(signo, 1, 0);
195*49cdfc7eSAndroid Build Coastguard Worker child[1] = create_sig_proc(signo + 1, 1, 0);
196*49cdfc7eSAndroid Build Coastguard Worker
197*49cdfc7eSAndroid Build Coastguard Worker /* Ensure that the signals have been sent */
198*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAITPID(child[0], &status, 0);
199*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAITPID(child[1], &status, 0);
200*49cdfc7eSAndroid Build Coastguard Worker
201*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo(&sigs, &si, NULL));
202*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == signo) {
203*49cdfc7eSAndroid Build Coastguard Worker if (si.si_pid == child[0] && si.si_code == SI_USER &&
204*49cdfc7eSAndroid Build Coastguard Worker si.si_signo == signo)
205*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "struct siginfo is correct");
206*49cdfc7eSAndroid Build Coastguard Worker else
207*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "struct siginfo mismatch");
208*49cdfc7eSAndroid Build Coastguard Worker } else {
209*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "sigwaitinfo() failed");
210*49cdfc7eSAndroid Build Coastguard Worker }
211*49cdfc7eSAndroid Build Coastguard Worker
212*49cdfc7eSAndroid Build Coastguard Worker /* eat the other signal */
213*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo(&sigs, &si, NULL));
214*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == signo + 1) {
215*49cdfc7eSAndroid Build Coastguard Worker if (si.si_pid == child[1] && si.si_code == SI_USER &&
216*49cdfc7eSAndroid Build Coastguard Worker si.si_signo == signo + 1)
217*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "struct siginfo is correct");
218*49cdfc7eSAndroid Build Coastguard Worker else
219*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "struct siginfo mismatch");
220*49cdfc7eSAndroid Build Coastguard Worker } else {
221*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "sigwaitinfo() failed");
222*49cdfc7eSAndroid Build Coastguard Worker }
223*49cdfc7eSAndroid Build Coastguard Worker
224*49cdfc7eSAndroid Build Coastguard Worker TEST(sigprocmask(SIG_SETMASK, &oldmask, &sigs));
225*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1)
226*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "restoring original signal mask failed");
227*49cdfc7eSAndroid Build Coastguard Worker
228*49cdfc7eSAndroid Build Coastguard Worker if (sigismember(&sigs, signo))
229*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "sigwaitinfo restored the original mask");
230*49cdfc7eSAndroid Build Coastguard Worker else
231*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL,
232*49cdfc7eSAndroid Build Coastguard Worker "sigwaitinfo failed to restore the original mask");
233*49cdfc7eSAndroid Build Coastguard Worker }
234*49cdfc7eSAndroid Build Coastguard Worker
test_masked_matching_noinfo(swi_func sigwaitinfo,int signo,enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)235*49cdfc7eSAndroid Build Coastguard Worker void test_masked_matching_noinfo(swi_func sigwaitinfo, int signo,
236*49cdfc7eSAndroid Build Coastguard Worker enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)
237*49cdfc7eSAndroid Build Coastguard Worker {
238*49cdfc7eSAndroid Build Coastguard Worker sigset_t sigs, oldmask;
239*49cdfc7eSAndroid Build Coastguard Worker pid_t child;
240*49cdfc7eSAndroid Build Coastguard Worker
241*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGEMPTYSET(&sigs);
242*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, signo);
243*49cdfc7eSAndroid Build Coastguard Worker
244*49cdfc7eSAndroid Build Coastguard Worker /* let's not get interrupted by our dying child */
245*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, SIGCHLD);
246*49cdfc7eSAndroid Build Coastguard Worker
247*49cdfc7eSAndroid Build Coastguard Worker TEST(sigprocmask(SIG_SETMASK, &sigs, &oldmask));
248*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1)
249*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "sigprocmask() failed");
250*49cdfc7eSAndroid Build Coastguard Worker
251*49cdfc7eSAndroid Build Coastguard Worker /* don't wait on a SIGCHLD */
252*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGDELSET(&sigs, SIGCHLD);
253*49cdfc7eSAndroid Build Coastguard Worker
254*49cdfc7eSAndroid Build Coastguard Worker /* Run a child that will wake us up */
255*49cdfc7eSAndroid Build Coastguard Worker child = create_sig_proc(signo, 1, 0);
256*49cdfc7eSAndroid Build Coastguard Worker
257*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo(&sigs, NULL, NULL));
258*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == signo)
259*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "Wait interrupted by expected signal");
260*49cdfc7eSAndroid Build Coastguard Worker else
261*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "sigwaitinfo() failed");
262*49cdfc7eSAndroid Build Coastguard Worker
263*49cdfc7eSAndroid Build Coastguard Worker TEST(sigprocmask(SIG_SETMASK, &oldmask, &sigs));
264*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1)
265*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "restoring original signal mask failed");
266*49cdfc7eSAndroid Build Coastguard Worker
267*49cdfc7eSAndroid Build Coastguard Worker if (sigismember(&sigs, signo))
268*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "sigwaitinfo restored the original mask");
269*49cdfc7eSAndroid Build Coastguard Worker else
270*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL,
271*49cdfc7eSAndroid Build Coastguard Worker "sigwaitinfo failed to restore the original mask");
272*49cdfc7eSAndroid Build Coastguard Worker
273*49cdfc7eSAndroid Build Coastguard Worker SAFE_KILL(child, SIGTERM);
274*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAIT(NULL);
275*49cdfc7eSAndroid Build Coastguard Worker }
276*49cdfc7eSAndroid Build Coastguard Worker
test_bad_address(swi_func sigwaitinfo,int signo,enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)277*49cdfc7eSAndroid Build Coastguard Worker void test_bad_address(swi_func sigwaitinfo, int signo,
278*49cdfc7eSAndroid Build Coastguard Worker enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)
279*49cdfc7eSAndroid Build Coastguard Worker {
280*49cdfc7eSAndroid Build Coastguard Worker sigset_t sigs, oldmask;
281*49cdfc7eSAndroid Build Coastguard Worker pid_t child;
282*49cdfc7eSAndroid Build Coastguard Worker
283*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGEMPTYSET(&sigs);
284*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, signo);
285*49cdfc7eSAndroid Build Coastguard Worker
286*49cdfc7eSAndroid Build Coastguard Worker /* let's not get interrupted by our dying child */
287*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGADDSET(&sigs, SIGCHLD);
288*49cdfc7eSAndroid Build Coastguard Worker
289*49cdfc7eSAndroid Build Coastguard Worker TEST(sigprocmask(SIG_SETMASK, &sigs, &oldmask));
290*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1)
291*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "sigprocmask() failed");
292*49cdfc7eSAndroid Build Coastguard Worker
293*49cdfc7eSAndroid Build Coastguard Worker /* don't wait on a SIGCHLD */
294*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGDELSET(&sigs, SIGCHLD);
295*49cdfc7eSAndroid Build Coastguard Worker
296*49cdfc7eSAndroid Build Coastguard Worker /* Run a child that will wake us up */
297*49cdfc7eSAndroid Build Coastguard Worker child = create_sig_proc(signo, 1, 0);
298*49cdfc7eSAndroid Build Coastguard Worker
299*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo(&sigs, (void *)1, NULL));
300*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1) {
301*49cdfc7eSAndroid Build Coastguard Worker if (TST_ERR == EFAULT)
302*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "Fault occurred while accessing the buffers");
303*49cdfc7eSAndroid Build Coastguard Worker else
304*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "Expected error number EFAULT, got");
305*49cdfc7eSAndroid Build Coastguard Worker } else {
306*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "Expected return value -1, got: %ld", TST_RET);
307*49cdfc7eSAndroid Build Coastguard Worker }
308*49cdfc7eSAndroid Build Coastguard Worker
309*49cdfc7eSAndroid Build Coastguard Worker TEST(sigprocmask(SIG_SETMASK, &oldmask, NULL));
310*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1)
311*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "restoring original signal mask failed");
312*49cdfc7eSAndroid Build Coastguard Worker
313*49cdfc7eSAndroid Build Coastguard Worker SAFE_KILL(child, SIGTERM);
314*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAIT(NULL);
315*49cdfc7eSAndroid Build Coastguard Worker }
316*49cdfc7eSAndroid Build Coastguard Worker
test_bad_address2(swi_func sigwaitinfo,int signo LTP_ATTRIBUTE_UNUSED,enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)317*49cdfc7eSAndroid Build Coastguard Worker void test_bad_address2(swi_func sigwaitinfo, int signo LTP_ATTRIBUTE_UNUSED,
318*49cdfc7eSAndroid Build Coastguard Worker enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)
319*49cdfc7eSAndroid Build Coastguard Worker {
320*49cdfc7eSAndroid Build Coastguard Worker pid_t pid;
321*49cdfc7eSAndroid Build Coastguard Worker int status;
322*49cdfc7eSAndroid Build Coastguard Worker
323*49cdfc7eSAndroid Build Coastguard Worker pid = SAFE_FORK();
324*49cdfc7eSAndroid Build Coastguard Worker if (pid == 0) {
325*49cdfc7eSAndroid Build Coastguard Worker signal(SIGSEGV, SIG_DFL);
326*49cdfc7eSAndroid Build Coastguard Worker
327*49cdfc7eSAndroid Build Coastguard Worker /*
328*49cdfc7eSAndroid Build Coastguard Worker * depending on glibc implementation we should
329*49cdfc7eSAndroid Build Coastguard Worker * either crash or get EFAULT
330*49cdfc7eSAndroid Build Coastguard Worker */
331*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo((void *)1, NULL, NULL));
332*49cdfc7eSAndroid Build Coastguard Worker
333*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1 && TST_ERR == EFAULT)
334*49cdfc7eSAndroid Build Coastguard Worker _exit(0);
335*49cdfc7eSAndroid Build Coastguard Worker
336*49cdfc7eSAndroid Build Coastguard Worker tst_res(TINFO | TTERRNO, "swi_func returned: %ld", TST_RET);
337*49cdfc7eSAndroid Build Coastguard Worker _exit(1);
338*49cdfc7eSAndroid Build Coastguard Worker }
339*49cdfc7eSAndroid Build Coastguard Worker
340*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAITPID(pid, &status, 0);
341*49cdfc7eSAndroid Build Coastguard Worker
342*49cdfc7eSAndroid Build Coastguard Worker if ((WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)
343*49cdfc7eSAndroid Build Coastguard Worker || (WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
344*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "Child exited with expected code");
345*49cdfc7eSAndroid Build Coastguard Worker return;
346*49cdfc7eSAndroid Build Coastguard Worker }
347*49cdfc7eSAndroid Build Coastguard Worker
348*49cdfc7eSAndroid Build Coastguard Worker if (WIFEXITED(status)) {
349*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "Unrecognised child exit code: %d",
350*49cdfc7eSAndroid Build Coastguard Worker WEXITSTATUS(status));
351*49cdfc7eSAndroid Build Coastguard Worker }
352*49cdfc7eSAndroid Build Coastguard Worker if (WIFSIGNALED(status)) {
353*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "Unrecognised child termsig: %d",
354*49cdfc7eSAndroid Build Coastguard Worker WTERMSIG(status));
355*49cdfc7eSAndroid Build Coastguard Worker }
356*49cdfc7eSAndroid Build Coastguard Worker }
357*49cdfc7eSAndroid Build Coastguard Worker
test_bad_address3(swi_func sigwaitinfo,int signo LTP_ATTRIBUTE_UNUSED,enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)358*49cdfc7eSAndroid Build Coastguard Worker void test_bad_address3(swi_func sigwaitinfo, int signo LTP_ATTRIBUTE_UNUSED,
359*49cdfc7eSAndroid Build Coastguard Worker enum tst_ts_type type LTP_ATTRIBUTE_UNUSED)
360*49cdfc7eSAndroid Build Coastguard Worker {
361*49cdfc7eSAndroid Build Coastguard Worker sigset_t sigs;
362*49cdfc7eSAndroid Build Coastguard Worker
363*49cdfc7eSAndroid Build Coastguard Worker SAFE_SIGEMPTYSET(&sigs);
364*49cdfc7eSAndroid Build Coastguard Worker TEST(sigwaitinfo(&sigs, NULL, (void *)1));
365*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1) {
366*49cdfc7eSAndroid Build Coastguard Worker if (TST_ERR == EFAULT)
367*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "Fault occurred while accessing the buffers");
368*49cdfc7eSAndroid Build Coastguard Worker else
369*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TTERRNO, "Expected error number EFAULT, got");
370*49cdfc7eSAndroid Build Coastguard Worker } else {
371*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "Expected return value -1, got: %ld", TST_RET);
372*49cdfc7eSAndroid Build Coastguard Worker }
373*49cdfc7eSAndroid Build Coastguard Worker }
374*49cdfc7eSAndroid Build Coastguard Worker
empty_handler(int sig LTP_ATTRIBUTE_UNUSED)375*49cdfc7eSAndroid Build Coastguard Worker static void empty_handler(int sig LTP_ATTRIBUTE_UNUSED)
376*49cdfc7eSAndroid Build Coastguard Worker {
377*49cdfc7eSAndroid Build Coastguard Worker }
378*49cdfc7eSAndroid Build Coastguard Worker
sigwait_setup(void)379*49cdfc7eSAndroid Build Coastguard Worker void sigwait_setup(void)
380*49cdfc7eSAndroid Build Coastguard Worker {
381*49cdfc7eSAndroid Build Coastguard Worker signal(SIGUSR1, empty_handler);
382*49cdfc7eSAndroid Build Coastguard Worker signal(SIGALRM, empty_handler);
383*49cdfc7eSAndroid Build Coastguard Worker signal(SIGUSR2, SIG_IGN);
384*49cdfc7eSAndroid Build Coastguard Worker }
385