xref: /openbsd-src/regress/lib/libc/sys/t_wait_noproc.c (revision 4e1ee0786f11cc571bd0be17d38e46f635c719fc)
1 /*	$OpenBSD: t_wait_noproc.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $	*/
2 /* $NetBSD: t_wait_noproc.c,v 1.5 2016/11/09 17:50:19 kamil Exp $ */
3 
4 /*-
5  * Copyright (c) 2016 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "macros.h"
31 
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: t_wait_noproc.c,v 1.5 2016/11/09 17:50:19 kamil Exp $");
34 
35 #include <sys/wait.h>
36 #include <sys/resource.h>
37 
38 #include <errno.h>
39 #include <stdio.h>
40 
41 #include "atf-c.h"
42 
43 #ifndef TWAIT_OPTION
44 #define TWAIT_OPTION 0
45 #endif
46 
47 #if TWAIT_OPTION == 0
48 ATF_TC(wait);
49 ATF_TC_HEAD(wait, tc)
50 {
51 	atf_tc_set_md_var(tc, "descr",
52 	    "Test that wait(2) returns ECHILD for no child");
53 }
54 
55 ATF_TC_BODY(wait, tc)
56 {
57 	ATF_REQUIRE_ERRNO(ECHILD, wait(NULL) == -1);
58 }
59 #endif
60 
61 ATF_TC(waitpid);
62 ATF_TC_HEAD(waitpid, tc)
63 {
64 	atf_tc_set_md_var(tc, "descr",
65 	    "Test that waitpid(2) returns ECHILD for WAIT_ANY and option %s",
66 	    ___STRING(TWAIT_OPTION));
67 }
68 
69 ATF_TC_BODY(waitpid, tc)
70 {
71 	ATF_REQUIRE_ERRNO(ECHILD, waitpid(WAIT_ANY, NULL, TWAIT_OPTION) == -1);
72 }
73 
74 #ifndef __OpenBSD__
75 ATF_TC(waitid);
76 ATF_TC_HEAD(waitid, tc)
77 {
78 	atf_tc_set_md_var(tc, "descr",
79 	    "Test that waitid(2) returns ECHILD for P_ALL and option %s",
80 	    ___STRING(TWAIT_OPTION));
81 }
82 
83 ATF_TC_BODY(waitid, tc)
84 {
85 	ATF_REQUIRE_ERRNO(ECHILD,
86 	    waitid(P_ALL, 0, NULL,
87 	        WTRAPPED | WEXITED | TWAIT_OPTION) == -1);
88 }
89 #endif
90 
91 ATF_TC(wait3);
92 ATF_TC_HEAD(wait3, tc)
93 {
94 	atf_tc_set_md_var(tc, "descr",
95 	    "Test that wait3(2) returns ECHILD for no child");
96 }
97 
98 ATF_TC_BODY(wait3, tc)
99 {
100 	ATF_REQUIRE_ERRNO(ECHILD, wait3(NULL, TWAIT_OPTION, NULL) == -1);
101 }
102 
103 ATF_TC(wait4);
104 ATF_TC_HEAD(wait4, tc)
105 {
106 	atf_tc_set_md_var(tc, "descr",
107 	    "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s",
108 	    ___STRING(TWAIT_OPTION));
109 }
110 
111 ATF_TC_BODY(wait4, tc)
112 {
113 	ATF_REQUIRE_ERRNO(ECHILD,
114 	    wait4(WAIT_ANY, NULL, TWAIT_OPTION, NULL) == -1);
115 }
116 
117 #ifndef __OpenBSD__
118  * Adjusted for OpenBSD, not available
119  * ATF_TC(wait6);
120  * ATF_TC_HEAD(wait6, tc)
121  * {
122  * 	atf_tc_set_md_var(tc, "descr",
123  * 	    "Test that wait6(2) returns ECHILD for P_ALL and option %s",
124  * 	    ___STRING(TWAIT_OPTION));
125  * }
126  *
127  * ATF_TC_BODY(wait6, tc)
128  * {
129  * 	ATF_REQUIRE_ERRNO(ECHILD,
130  * 	    wait6(P_ALL, 0, NULL,
131  * 	        WTRAPPED | WEXITED | TWAIT_OPTION, NULL, NULL) == -1);
132  * }
133  */
134 
135 /*
136  * Generator of valid combinations of options
137  * Usage: i = 0; while ((o = get_options_wait6(i++)) != -1) {}
138  */
139 static int
140 get_options6(size_t pos)
141 {
142 	int rv = 0;
143 	size_t n;
144 	/*
145 	 * waitid(2) must specify at least one of WEXITED, WUNTRACED,
146 	 * WSTOPPED, WTRAPPED or WCONTINUED. Single option WNOWAIT
147 	 * isn't valid.
148 	 */
149 	const int matrix[] = {
150 		WNOWAIT,	// First in order to blacklist it easily
151 		WEXITED,
152 		WUNTRACED,
153 		WSTOPPED,	// SUS compatibility, equal to WUNTRACED
154 		WTRAPPED,
155 		WCONTINUED
156 	};
157 
158 	const size_t M = (1 << __arraycount(matrix)) - 1;
159 	/* Skip empty and sole WNOWAIT option */
160 	pos+=2;
161 
162 	if (pos > M)
163 		return -1;
164 
165 	for (n = 0; n < __arraycount(matrix); n++) {
166 		if (pos & __BIT(n))
167 			rv |= matrix[n];
168 	}
169 
170 	return rv;
171 }
172 #endif
173 
174 /*
175  * Generator of valid combinations of options
176  * Usage: i = 0; while ((o = get_options_wait4(i++)) != -1) {}
177  */
178 static int
179 get_options4(size_t pos)
180 {
181 	int rv = 0;
182 	size_t n;
183 
184 	const int special[] = {
185 		0,
186 #ifndef __OpenBSD__
187 		WALLSIG,
188 		WALTSIG,
189 		__WALL,		// Linux compatibility, equal to WALLSIG
190 		__WCLONE	// Linux compatibility, equal to WALTSIG
191 #endif
192 	};
193 
194 	const int matrix[] = {
195 #ifndef __OpenBSD__
196 		WNOWAIT,
197 		WEXITED,
198 #endif
199 		WUNTRACED,
200 #ifndef __OpenBSD__
201 		WSTOPPED,	// SUS compatibility, equal to WUNTRACED
202 		WTRAPPED,
203 #endif
204 		WCONTINUED
205 	};
206 
207 	const size_t M = (1 << __arraycount(special)) - 1;
208 
209 	if (pos < __arraycount(special))
210 		return special[pos];
211 
212 	pos -= __arraycount(special);
213 
214 	++pos; /* Don't start with empty mask */
215 
216 	if (pos > M)
217 		return -1;
218 
219 	for (n = 0; n < __arraycount(special); n++) {
220 		if (pos & __BIT(n))
221 			rv |= matrix[n];
222 	}
223 
224 	return rv;
225 }
226 
227 ATF_TC(waitpid_options);
228 ATF_TC_HEAD(waitpid_options, tc)
229 {
230 	atf_tc_set_md_var(tc, "descr",
231 	    "Test that waitpid(2) returns ECHILD for WAIT_ANY and valid "
232 	    "combination of options with%s WNOHANG",
233 	    TWAIT_OPTION == 0 ? "out" : "");
234 }
235 
236 ATF_TC_BODY(waitpid_options, tc)
237 {
238 	size_t i = 0;
239 	int o;
240 
241 	while((o = get_options4(i++)) != -1) {
242 		printf("Testing waitpid(2) with options %x\n", o);
243 
244 		ATF_REQUIRE_ERRNO(ECHILD,
245 		    waitpid(WAIT_ANY, NULL, o | TWAIT_OPTION) == -1);
246 	}
247 }
248 
249 #ifndef __OpenBSD__
250 ATF_TC(waitid_options);
251 ATF_TC_HEAD(waitid_options, tc)
252 {
253 	atf_tc_set_md_var(tc, "descr",
254 	    "Test that waitid(2) returns ECHILD for P_ALL and valid "
255 	    "combination of options with%s WNOHANG",
256 	    TWAIT_OPTION == 0 ? "out" : "");
257 }
258 
259 ATF_TC_BODY(waitid_options, tc)
260 {
261 	size_t i = 0;
262 	int o;
263 
264 	while((o = get_options6(i++)) != -1) {
265 		printf("Testing waitid(2) with options %x\n", o);
266 
267 		ATF_REQUIRE_ERRNO(ECHILD,
268 		    waitid(P_ALL, 0, NULL, o | TWAIT_OPTION) == -1);
269 	}
270 }
271 #endif
272 
273 ATF_TC(wait3_options);
274 ATF_TC_HEAD(wait3_options, tc)
275 {
276 	atf_tc_set_md_var(tc, "descr",
277 	    "Test that wait3(2) returns ECHILD for no child");
278 }
279 
280 ATF_TC_BODY(wait3_options, tc)
281 {
282 	size_t i = 0;
283 	int o;
284 
285 	while((o = get_options4(i++)) != -1) {
286 		printf("Testing wait3(2) with options %x\n", o);
287 
288 		ATF_REQUIRE_ERRNO(ECHILD,
289 		    wait3(NULL, o | TWAIT_OPTION, NULL) == -1);
290 	}
291 }
292 
293 ATF_TC(wait4_options);
294 ATF_TC_HEAD(wait4_options, tc)
295 {
296 	atf_tc_set_md_var(tc, "descr",
297 	    "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s",
298 	    ___STRING(TWAIT_OPTION));
299 }
300 
301 ATF_TC_BODY(wait4_options, tc)
302 {
303 	size_t i = 0;
304 	int o;
305 
306 	while((o = get_options4(i++)) != -1) {
307 		printf("Testing wait4(2) with options %x\n", o);
308 
309 		ATF_REQUIRE_ERRNO(ECHILD,
310 		    wait4(WAIT_ANY, NULL, o | TWAIT_OPTION, NULL) == -1);
311 	}
312 }
313 
314 #ifndef __OpenBSD__
315 ATF_TC(wait6_options);
316 ATF_TC_HEAD(wait6_options, tc)
317 {
318 	atf_tc_set_md_var(tc, "descr",
319 	    "Test that wait6(2) returns ECHILD for P_ALL and option %s",
320 	    ___STRING(TWAIT_OPTION));
321 }
322 
323 ATF_TC_BODY(wait6_options, tc)
324 {
325 	size_t i = 0;
326 	int o;
327 
328 	while((o = get_options6(i++)) != -1) {
329 		printf("Testing wait6(2) with options %x\n", o);
330 
331 		ATF_REQUIRE_ERRNO(ECHILD,
332 		    wait6(P_ALL, 0, NULL, o | TWAIT_OPTION, NULL, NULL) == -1);
333 	}
334 }
335 #endif
336 
337 ATF_TP_ADD_TCS(tp)
338 {
339 
340 #if TWAIT_OPTION == 0
341 	ATF_TP_ADD_TC(tp, wait);
342 #endif
343 	ATF_TP_ADD_TC(tp, waitpid);
344 #ifndef __OpenBSD__
345 	ATF_TP_ADD_TC(tp, waitid);
346 #endif
347 	ATF_TP_ADD_TC(tp, wait3);
348 	ATF_TP_ADD_TC(tp, wait4);
349 #ifndef __OpenBSD__
350 	ATF_TP_ADD_TC(tp, wait6);
351 #endif
352 
353 	ATF_TP_ADD_TC(tp, waitpid_options);
354 #ifndef __OpenBSD__
355 	ATF_TP_ADD_TC(tp, waitid_options);
356 #endif
357 	ATF_TP_ADD_TC(tp, wait3_options);
358 	ATF_TP_ADD_TC(tp, wait4_options);
359 #ifndef __OpenBSD__
360 	ATF_TP_ADD_TC(tp, wait6_options);
361 #endif
362 
363 	return atf_no_error();
364 }
365