xref: /freebsd-src/contrib/netbsd-tests/lib/libc/sys/t_wait.c (revision 640235e2c2ba32947f7c59d168437ffa1280f1e6)
1*640235e2SEnji Cooper /* $NetBSD: t_wait.c,v 1.4 2016/04/27 21:14:24 christos Exp $ */
2*640235e2SEnji Cooper 
3*640235e2SEnji Cooper /*-
4*640235e2SEnji Cooper  * Copyright (c) 2016 The NetBSD Foundation, Inc.
5*640235e2SEnji Cooper  * All rights reserved.
6*640235e2SEnji Cooper  *
7*640235e2SEnji Cooper  * This code is derived from software contributed to The NetBSD Foundation
8*640235e2SEnji Cooper  * by Christos Zoulas.
9*640235e2SEnji Cooper  *
10*640235e2SEnji Cooper  * Redistribution and use in source and binary forms, with or without
11*640235e2SEnji Cooper  * modification, are permitted provided that the following conditions
12*640235e2SEnji Cooper  * are met:
13*640235e2SEnji Cooper  * 1. Redistributions of source code must retain the above copyright
14*640235e2SEnji Cooper  *    notice, this list of conditions and the following disclaimer.
15*640235e2SEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
16*640235e2SEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
17*640235e2SEnji Cooper  *    documentation and/or other materials provided with the distribution.
18*640235e2SEnji Cooper  *
19*640235e2SEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*640235e2SEnji Cooper  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*640235e2SEnji Cooper  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*640235e2SEnji Cooper  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*640235e2SEnji Cooper  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*640235e2SEnji Cooper  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*640235e2SEnji Cooper  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*640235e2SEnji Cooper  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*640235e2SEnji Cooper  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*640235e2SEnji Cooper  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*640235e2SEnji Cooper  * POSSIBILITY OF SUCH DAMAGE.
30*640235e2SEnji Cooper  */
31*640235e2SEnji Cooper #include <sys/cdefs.h>
32*640235e2SEnji Cooper __RCSID("$NetBSD: t_wait.c,v 1.4 2016/04/27 21:14:24 christos Exp $");
33*640235e2SEnji Cooper 
34*640235e2SEnji Cooper #include <sys/wait.h>
35*640235e2SEnji Cooper #include <sys/resource.h>
36*640235e2SEnji Cooper 
37*640235e2SEnji Cooper #include <stdio.h>
38*640235e2SEnji Cooper #include <errno.h>
39*640235e2SEnji Cooper #include <limits.h>
40*640235e2SEnji Cooper #include <pwd.h>
41*640235e2SEnji Cooper #include <signal.h>
42*640235e2SEnji Cooper #include <stdlib.h>
43*640235e2SEnji Cooper #include <unistd.h>
44*640235e2SEnji Cooper 
45*640235e2SEnji Cooper #include <atf-c.h>
46*640235e2SEnji Cooper 
47*640235e2SEnji Cooper #ifdef __FreeBSD__
48*640235e2SEnji Cooper #define	wrusage	__wrusage
49*640235e2SEnji Cooper #endif
50*640235e2SEnji Cooper 
51*640235e2SEnji Cooper ATF_TC(wait6_invalid);
52*640235e2SEnji Cooper ATF_TC_HEAD(wait6_invalid, tc)
53*640235e2SEnji Cooper {
54*640235e2SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
55*640235e2SEnji Cooper 	    "Test that wait6(2) returns EINVAL with 0 options");
56*640235e2SEnji Cooper }
57*640235e2SEnji Cooper 
58*640235e2SEnji Cooper ATF_TC_BODY(wait6_invalid, tc)
59*640235e2SEnji Cooper {
60*640235e2SEnji Cooper 	siginfo_t si;
61*640235e2SEnji Cooper 	struct wrusage wru;
62*640235e2SEnji Cooper 	int st;
63*640235e2SEnji Cooper 	ATF_REQUIRE(wait6(P_ALL, 0, &st, 0, &wru, &si) == -1
64*640235e2SEnji Cooper 	    && errno == EINVAL);
65*640235e2SEnji Cooper }
66*640235e2SEnji Cooper 
67*640235e2SEnji Cooper ATF_TC(wait6_noproc);
68*640235e2SEnji Cooper ATF_TC_HEAD(wait6_noproc, tc)
69*640235e2SEnji Cooper {
70*640235e2SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
71*640235e2SEnji Cooper 	    "Test that wait6(2) returns ECHILD with for no processes");
72*640235e2SEnji Cooper }
73*640235e2SEnji Cooper 
74*640235e2SEnji Cooper ATF_TC_BODY(wait6_noproc, tc)
75*640235e2SEnji Cooper {
76*640235e2SEnji Cooper 	siginfo_t si;
77*640235e2SEnji Cooper 	struct wrusage wru;
78*640235e2SEnji Cooper 	int st;
79*640235e2SEnji Cooper 	ATF_REQUIRE(wait6(P_ALL, 0, &st, WEXITED, &wru, &si) == -1
80*640235e2SEnji Cooper 	    && errno == ECHILD);
81*640235e2SEnji Cooper }
82*640235e2SEnji Cooper 
83*640235e2SEnji Cooper ATF_TC(wait6_exited);
84*640235e2SEnji Cooper ATF_TC_HEAD(wait6_exited, tc)
85*640235e2SEnji Cooper {
86*640235e2SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
87*640235e2SEnji Cooper 	    "Test that wait6(2) handled exiting process and code");
88*640235e2SEnji Cooper }
89*640235e2SEnji Cooper 
90*640235e2SEnji Cooper ATF_TC_BODY(wait6_exited, tc)
91*640235e2SEnji Cooper {
92*640235e2SEnji Cooper 	siginfo_t si;
93*640235e2SEnji Cooper 	struct wrusage wru;
94*640235e2SEnji Cooper 	int st;
95*640235e2SEnji Cooper 	pid_t pid;
96*640235e2SEnji Cooper 
97*640235e2SEnji Cooper 	switch (pid = fork()) {
98*640235e2SEnji Cooper 	case -1:
99*640235e2SEnji Cooper 		ATF_REQUIRE(pid > 0);
100*640235e2SEnji Cooper 	case 0:
101*640235e2SEnji Cooper 		exit(0x5a5a5a5a);
102*640235e2SEnji Cooper 		/*NOTREACHED*/
103*640235e2SEnji Cooper 	default:
104*640235e2SEnji Cooper 		ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid);
105*640235e2SEnji Cooper 		ATF_REQUIRE(WIFEXITED(st) && WEXITSTATUS(st) == 0x5a);
106*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_status = 0x5a5a5a5a);
107*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_pid == pid);
108*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_uid == getuid());
109*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_code == CLD_EXITED);
110*640235e2SEnji Cooper #ifdef __NetBSD__
111*640235e2SEnji Cooper 		printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime,
112*640235e2SEnji Cooper 		    (uintmax_t)si.si_utime);
113*640235e2SEnji Cooper #endif
114*640235e2SEnji Cooper 		break;
115*640235e2SEnji Cooper 	}
116*640235e2SEnji Cooper }
117*640235e2SEnji Cooper 
118*640235e2SEnji Cooper ATF_TC(wait6_terminated);
119*640235e2SEnji Cooper ATF_TC_HEAD(wait6_terminated, tc)
120*640235e2SEnji Cooper {
121*640235e2SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
122*640235e2SEnji Cooper 	    "Test that wait6(2) handled terminated process and code");
123*640235e2SEnji Cooper }
124*640235e2SEnji Cooper 
125*640235e2SEnji Cooper ATF_TC_BODY(wait6_terminated, tc)
126*640235e2SEnji Cooper {
127*640235e2SEnji Cooper 	siginfo_t si;
128*640235e2SEnji Cooper 	struct wrusage wru;
129*640235e2SEnji Cooper 	int st;
130*640235e2SEnji Cooper 	pid_t pid;
131*640235e2SEnji Cooper 
132*640235e2SEnji Cooper 	switch (pid = fork()) {
133*640235e2SEnji Cooper 	case 0:
134*640235e2SEnji Cooper 		sleep(100);
135*640235e2SEnji Cooper 		/*FALLTHROUGH*/
136*640235e2SEnji Cooper 	case -1:
137*640235e2SEnji Cooper 		ATF_REQUIRE(pid > 0);
138*640235e2SEnji Cooper 	default:
139*640235e2SEnji Cooper 		ATF_REQUIRE(kill(pid, SIGTERM) == 0);
140*640235e2SEnji Cooper 		ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid);
141*640235e2SEnji Cooper 		ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGTERM);
142*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_status == SIGTERM);
143*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_pid == pid);
144*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_uid == getuid());
145*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_code == CLD_KILLED);
146*640235e2SEnji Cooper #ifdef __NetBSD__
147*640235e2SEnji Cooper 		printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime,
148*640235e2SEnji Cooper 		    (uintmax_t)si.si_utime);
149*640235e2SEnji Cooper #endif
150*640235e2SEnji Cooper 		break;
151*640235e2SEnji Cooper 	}
152*640235e2SEnji Cooper }
153*640235e2SEnji Cooper 
154*640235e2SEnji Cooper ATF_TC(wait6_coredumped);
155*640235e2SEnji Cooper ATF_TC_HEAD(wait6_coredumped, tc)
156*640235e2SEnji Cooper {
157*640235e2SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
158*640235e2SEnji Cooper 	    "Test that wait6(2) handled coredumped process and code");
159*640235e2SEnji Cooper }
160*640235e2SEnji Cooper 
161*640235e2SEnji Cooper ATF_TC_BODY(wait6_coredumped, tc)
162*640235e2SEnji Cooper {
163*640235e2SEnji Cooper 	siginfo_t si;
164*640235e2SEnji Cooper 	struct wrusage wru;
165*640235e2SEnji Cooper 	int st;
166*640235e2SEnji Cooper 	pid_t pid;
167*640235e2SEnji Cooper 	static const struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
168*640235e2SEnji Cooper 
169*640235e2SEnji Cooper 	switch (pid = fork()) {
170*640235e2SEnji Cooper 	case 0:
171*640235e2SEnji Cooper 		ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0);
172*640235e2SEnji Cooper 		*(char *)8 = 0;
173*640235e2SEnji Cooper 		/*FALLTHROUGH*/
174*640235e2SEnji Cooper 	case -1:
175*640235e2SEnji Cooper 		ATF_REQUIRE(pid > 0);
176*640235e2SEnji Cooper 	default:
177*640235e2SEnji Cooper 		ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid);
178*640235e2SEnji Cooper 		ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGSEGV
179*640235e2SEnji Cooper 		    && WCOREDUMP(st));
180*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_status == SIGSEGV);
181*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_pid == pid);
182*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_uid == getuid());
183*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_code == CLD_DUMPED);
184*640235e2SEnji Cooper #ifdef __NetBSD__
185*640235e2SEnji Cooper 		printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime,
186*640235e2SEnji Cooper 		    (uintmax_t)si.si_utime);
187*640235e2SEnji Cooper #endif
188*640235e2SEnji Cooper 		break;
189*640235e2SEnji Cooper 	}
190*640235e2SEnji Cooper }
191*640235e2SEnji Cooper 
192*640235e2SEnji Cooper ATF_TC(wait6_stop_and_go);
193*640235e2SEnji Cooper ATF_TC_HEAD(wait6_stop_and_go, tc)
194*640235e2SEnji Cooper {
195*640235e2SEnji Cooper 	atf_tc_set_md_var(tc, "descr",
196*640235e2SEnji Cooper 	    "Test that wait6(2) handled stopped/continued process and code");
197*640235e2SEnji Cooper }
198*640235e2SEnji Cooper 
199*640235e2SEnji Cooper ATF_TC_BODY(wait6_stop_and_go, tc)
200*640235e2SEnji Cooper {
201*640235e2SEnji Cooper 	siginfo_t si;
202*640235e2SEnji Cooper 	struct wrusage wru;
203*640235e2SEnji Cooper 	int st;
204*640235e2SEnji Cooper 	pid_t pid;
205*640235e2SEnji Cooper 	static const struct rlimit rl = { 0, 0 };
206*640235e2SEnji Cooper 
207*640235e2SEnji Cooper 	ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0);
208*640235e2SEnji Cooper 	switch (pid = fork()) {
209*640235e2SEnji Cooper 	case 0:
210*640235e2SEnji Cooper 		sleep(100);
211*640235e2SEnji Cooper 		/*FALLTHROUGH*/
212*640235e2SEnji Cooper 	case -1:
213*640235e2SEnji Cooper 		ATF_REQUIRE(pid > 0);
214*640235e2SEnji Cooper 	default:
215*640235e2SEnji Cooper 		ATF_REQUIRE(kill(pid, SIGSTOP) == 0);
216*640235e2SEnji Cooper 		ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid);
217*640235e2SEnji Cooper 		ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP);
218*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_status == SIGSTOP);
219*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_pid == pid);
220*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_uid == getuid());
221*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_code == CLD_STOPPED);
222*640235e2SEnji Cooper #ifdef __NetBSD__
223*640235e2SEnji Cooper 		printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime,
224*640235e2SEnji Cooper 		    (uintmax_t)si.si_utime);
225*640235e2SEnji Cooper #endif
226*640235e2SEnji Cooper 
227*640235e2SEnji Cooper 		ATF_REQUIRE(kill(pid, SIGCONT) == 0);
228*640235e2SEnji Cooper 		ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid);
229*640235e2SEnji Cooper 		ATF_REQUIRE(WIFCONTINUED(st));
230*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_status == SIGCONT);
231*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_pid == pid);
232*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_uid == getuid());
233*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_code == CLD_CONTINUED);
234*640235e2SEnji Cooper #ifdef __NetBSD__
235*640235e2SEnji Cooper 		printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime,
236*640235e2SEnji Cooper 		    (uintmax_t)si.si_utime);
237*640235e2SEnji Cooper #endif
238*640235e2SEnji Cooper 
239*640235e2SEnji Cooper 		ATF_REQUIRE(kill(pid, SIGQUIT) == 0);
240*640235e2SEnji Cooper 		ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid);
241*640235e2SEnji Cooper 		ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT);
242*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_status == SIGQUIT);
243*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_pid == pid);
244*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_uid == getuid());
245*640235e2SEnji Cooper 		ATF_REQUIRE(si.si_code == CLD_KILLED);
246*640235e2SEnji Cooper #ifdef __NetBSD__
247*640235e2SEnji Cooper 		printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime,
248*640235e2SEnji Cooper 		    (uintmax_t)si.si_utime);
249*640235e2SEnji Cooper #endif
250*640235e2SEnji Cooper 		break;
251*640235e2SEnji Cooper 	}
252*640235e2SEnji Cooper }
253*640235e2SEnji Cooper 
254*640235e2SEnji Cooper ATF_TP_ADD_TCS(tp)
255*640235e2SEnji Cooper {
256*640235e2SEnji Cooper 
257*640235e2SEnji Cooper 	ATF_TP_ADD_TC(tp, wait6_invalid);
258*640235e2SEnji Cooper 	ATF_TP_ADD_TC(tp, wait6_noproc);
259*640235e2SEnji Cooper 	ATF_TP_ADD_TC(tp, wait6_exited);
260*640235e2SEnji Cooper 	ATF_TP_ADD_TC(tp, wait6_terminated);
261*640235e2SEnji Cooper 	ATF_TP_ADD_TC(tp, wait6_coredumped);
262*640235e2SEnji Cooper 	ATF_TP_ADD_TC(tp, wait6_stop_and_go);
263*640235e2SEnji Cooper 
264*640235e2SEnji Cooper 	return atf_no_error();
265*640235e2SEnji Cooper }
266