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