xref: /minix3/tests/lib/libc/sys/t_minherit.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /* $NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $ */
2*0a6a1f1dSLionel Sambuc 
3*0a6a1f1dSLionel Sambuc /*-
4*0a6a1f1dSLionel Sambuc  * Copyright (c) 2014 The NetBSD Foundation, Inc.
5*0a6a1f1dSLionel Sambuc  * All rights reserved.
6*0a6a1f1dSLionel Sambuc  *
7*0a6a1f1dSLionel Sambuc  * This code is derived from software contributed to The NetBSD Foundation
8*0a6a1f1dSLionel Sambuc  * by Christos Zoulas
9*0a6a1f1dSLionel Sambuc  *
10*0a6a1f1dSLionel Sambuc  * Redistribution and use in source and binary forms, with or without
11*0a6a1f1dSLionel Sambuc  * modification, are permitted provided that the following conditions
12*0a6a1f1dSLionel Sambuc  * are met:
13*0a6a1f1dSLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
14*0a6a1f1dSLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
15*0a6a1f1dSLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
16*0a6a1f1dSLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
17*0a6a1f1dSLionel Sambuc  *    documentation and/or other materials provided with the distribution.
18*0a6a1f1dSLionel Sambuc  *
19*0a6a1f1dSLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*0a6a1f1dSLionel Sambuc  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*0a6a1f1dSLionel Sambuc  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*0a6a1f1dSLionel Sambuc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*0a6a1f1dSLionel Sambuc  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*0a6a1f1dSLionel Sambuc  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*0a6a1f1dSLionel Sambuc  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*0a6a1f1dSLionel Sambuc  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*0a6a1f1dSLionel Sambuc  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*0a6a1f1dSLionel Sambuc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*0a6a1f1dSLionel Sambuc  * POSSIBILITY OF SUCH DAMAGE.
30*0a6a1f1dSLionel Sambuc  */
31*0a6a1f1dSLionel Sambuc #include <sys/cdefs.h>
32*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $");
33*0a6a1f1dSLionel Sambuc 
34*0a6a1f1dSLionel Sambuc #include <sys/param.h>
35*0a6a1f1dSLionel Sambuc #include <sys/mman.h>
36*0a6a1f1dSLionel Sambuc #include <sys/sysctl.h>
37*0a6a1f1dSLionel Sambuc #include <sys/wait.h>
38*0a6a1f1dSLionel Sambuc 
39*0a6a1f1dSLionel Sambuc #include <errno.h>
40*0a6a1f1dSLionel Sambuc #include <fcntl.h>
41*0a6a1f1dSLionel Sambuc #include <stdlib.h>
42*0a6a1f1dSLionel Sambuc #include <string.h>
43*0a6a1f1dSLionel Sambuc #include <unistd.h>
44*0a6a1f1dSLionel Sambuc 
45*0a6a1f1dSLionel Sambuc #include <atf-c.h>
46*0a6a1f1dSLionel Sambuc 
47*0a6a1f1dSLionel Sambuc static long page;
48*0a6a1f1dSLionel Sambuc 
49*0a6a1f1dSLionel Sambuc static void *
makemap(int v,int f)50*0a6a1f1dSLionel Sambuc makemap(int v, int f) {
51*0a6a1f1dSLionel Sambuc 	void *map = mmap(NULL, page, PROT_READ|PROT_WRITE,
52*0a6a1f1dSLionel Sambuc 	    MAP_SHARED|MAP_ANON, -1, 0);
53*0a6a1f1dSLionel Sambuc 	ATF_REQUIRE(map != MAP_FAILED);
54*0a6a1f1dSLionel Sambuc 	memset(map, v, page);
55*0a6a1f1dSLionel Sambuc 	if (f != 666)
56*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(minherit(map, page, f) == 0);
57*0a6a1f1dSLionel Sambuc 	else
58*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(minherit(map, page, f) == -1);
59*0a6a1f1dSLionel Sambuc 	return map;
60*0a6a1f1dSLionel Sambuc }
61*0a6a1f1dSLionel Sambuc 
62*0a6a1f1dSLionel Sambuc ATF_TC(minherit_copy);
ATF_TC_HEAD(minherit_copy,tc)63*0a6a1f1dSLionel Sambuc ATF_TC_HEAD(minherit_copy, tc)
64*0a6a1f1dSLionel Sambuc {
65*0a6a1f1dSLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
66*0a6a1f1dSLionel Sambuc 	    "Test for MAP_INHERIT_COPY from minherit(2)");
67*0a6a1f1dSLionel Sambuc }
68*0a6a1f1dSLionel Sambuc 
ATF_TC_BODY(minherit_copy,tc)69*0a6a1f1dSLionel Sambuc ATF_TC_BODY(minherit_copy, tc)
70*0a6a1f1dSLionel Sambuc {
71*0a6a1f1dSLionel Sambuc 	void *map1 = makemap(1, MAP_INHERIT_COPY);
72*0a6a1f1dSLionel Sambuc 	void *map2 = makemap(1, MAP_INHERIT_COPY);
73*0a6a1f1dSLionel Sambuc 	switch (fork()) {
74*0a6a1f1dSLionel Sambuc 	default:
75*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(wait(NULL) != -1);
76*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(memcmp(map1, map2, page) == 0);
77*0a6a1f1dSLionel Sambuc 		break;
78*0a6a1f1dSLionel Sambuc 	case -1:
79*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(0);
80*0a6a1f1dSLionel Sambuc 		break;
81*0a6a1f1dSLionel Sambuc 	case 0:
82*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(memcmp(map1, map2, page) == 0);
83*0a6a1f1dSLionel Sambuc 		memset(map1, 0, page);
84*0a6a1f1dSLionel Sambuc 		exit(0);
85*0a6a1f1dSLionel Sambuc 	}
86*0a6a1f1dSLionel Sambuc }
87*0a6a1f1dSLionel Sambuc 
88*0a6a1f1dSLionel Sambuc ATF_TC(minherit_share);
ATF_TC_HEAD(minherit_share,tc)89*0a6a1f1dSLionel Sambuc ATF_TC_HEAD(minherit_share, tc)
90*0a6a1f1dSLionel Sambuc {
91*0a6a1f1dSLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
92*0a6a1f1dSLionel Sambuc 	    "Test for MAP_INHERIT_SHARE from minherit(2)");
93*0a6a1f1dSLionel Sambuc }
94*0a6a1f1dSLionel Sambuc 
ATF_TC_BODY(minherit_share,tc)95*0a6a1f1dSLionel Sambuc ATF_TC_BODY(minherit_share, tc)
96*0a6a1f1dSLionel Sambuc {
97*0a6a1f1dSLionel Sambuc 	void *map1 = makemap(1, MAP_INHERIT_SHARE);
98*0a6a1f1dSLionel Sambuc 	void *map2 = makemap(1, MAP_INHERIT_SHARE);
99*0a6a1f1dSLionel Sambuc 
100*0a6a1f1dSLionel Sambuc 	switch (fork()) {
101*0a6a1f1dSLionel Sambuc 	default:
102*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(wait(NULL) != -1);
103*0a6a1f1dSLionel Sambuc 		memset(map2, 0, page);
104*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(memcmp(map1, map2, page) == 0);
105*0a6a1f1dSLionel Sambuc 		break;
106*0a6a1f1dSLionel Sambuc 	case -1:
107*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(0);
108*0a6a1f1dSLionel Sambuc 		break;
109*0a6a1f1dSLionel Sambuc 	case 0:
110*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(memcmp(map1, map2, page) == 0);
111*0a6a1f1dSLionel Sambuc 		memset(map1, 0, page);
112*0a6a1f1dSLionel Sambuc 		exit(0);
113*0a6a1f1dSLionel Sambuc 	}
114*0a6a1f1dSLionel Sambuc }
115*0a6a1f1dSLionel Sambuc 
116*0a6a1f1dSLionel Sambuc static void
segv(int n)117*0a6a1f1dSLionel Sambuc segv(int n) {
118*0a6a1f1dSLionel Sambuc 	_exit(n);
119*0a6a1f1dSLionel Sambuc }
120*0a6a1f1dSLionel Sambuc 
121*0a6a1f1dSLionel Sambuc ATF_TC(minherit_none);
ATF_TC_HEAD(minherit_none,tc)122*0a6a1f1dSLionel Sambuc ATF_TC_HEAD(minherit_none, tc)
123*0a6a1f1dSLionel Sambuc {
124*0a6a1f1dSLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
125*0a6a1f1dSLionel Sambuc 	    "Test for MAP_INHERIT_NONE from minherit(2)");
126*0a6a1f1dSLionel Sambuc }
127*0a6a1f1dSLionel Sambuc 
ATF_TC_BODY(minherit_none,tc)128*0a6a1f1dSLionel Sambuc ATF_TC_BODY(minherit_none, tc)
129*0a6a1f1dSLionel Sambuc {
130*0a6a1f1dSLionel Sambuc 	void *map1 = makemap(0, MAP_INHERIT_NONE);
131*0a6a1f1dSLionel Sambuc 	int status;
132*0a6a1f1dSLionel Sambuc 
133*0a6a1f1dSLionel Sambuc 	switch (fork()) {
134*0a6a1f1dSLionel Sambuc 	default:
135*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(wait(&status) != -1);
136*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(WEXITSTATUS(status) == SIGSEGV);
137*0a6a1f1dSLionel Sambuc 		break;
138*0a6a1f1dSLionel Sambuc 	case -1:
139*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(0);
140*0a6a1f1dSLionel Sambuc 		break;
141*0a6a1f1dSLionel Sambuc 	case 0:
142*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(signal(SIGSEGV, segv) != SIG_ERR);
143*0a6a1f1dSLionel Sambuc 		memset(map1, 0, page);
144*0a6a1f1dSLionel Sambuc 		exit(0);
145*0a6a1f1dSLionel Sambuc 	}
146*0a6a1f1dSLionel Sambuc }
147*0a6a1f1dSLionel Sambuc 
148*0a6a1f1dSLionel Sambuc ATF_TC(minherit_zero);
ATF_TC_HEAD(minherit_zero,tc)149*0a6a1f1dSLionel Sambuc ATF_TC_HEAD(minherit_zero, tc)
150*0a6a1f1dSLionel Sambuc {
151*0a6a1f1dSLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
152*0a6a1f1dSLionel Sambuc 	    "Test for MAP_INHERIT_ZERO from minherit(2)");
153*0a6a1f1dSLionel Sambuc }
154*0a6a1f1dSLionel Sambuc 
ATF_TC_BODY(minherit_zero,tc)155*0a6a1f1dSLionel Sambuc ATF_TC_BODY(minherit_zero, tc)
156*0a6a1f1dSLionel Sambuc {
157*0a6a1f1dSLionel Sambuc 	void *map1 = makemap(1, MAP_INHERIT_ZERO);
158*0a6a1f1dSLionel Sambuc 	void *map2 = makemap(0, MAP_INHERIT_SHARE);
159*0a6a1f1dSLionel Sambuc 
160*0a6a1f1dSLionel Sambuc 	switch (fork()) {
161*0a6a1f1dSLionel Sambuc 	default:
162*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(wait(NULL) != -1);
163*0a6a1f1dSLionel Sambuc 		memset(map2, 1, page);
164*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(memcmp(map1, map2, page) == 0);
165*0a6a1f1dSLionel Sambuc 		break;
166*0a6a1f1dSLionel Sambuc 	case -1:
167*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(0);
168*0a6a1f1dSLionel Sambuc 		break;
169*0a6a1f1dSLionel Sambuc 	case 0:
170*0a6a1f1dSLionel Sambuc 		ATF_REQUIRE(memcmp(map1, map2, page) == 0);
171*0a6a1f1dSLionel Sambuc 		memset(map1, 2, page);
172*0a6a1f1dSLionel Sambuc 		exit(0);
173*0a6a1f1dSLionel Sambuc 	}
174*0a6a1f1dSLionel Sambuc }
175*0a6a1f1dSLionel Sambuc 
176*0a6a1f1dSLionel Sambuc ATF_TC(minherit_bad);
ATF_TC_HEAD(minherit_bad,tc)177*0a6a1f1dSLionel Sambuc ATF_TC_HEAD(minherit_bad, tc)
178*0a6a1f1dSLionel Sambuc {
179*0a6a1f1dSLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
180*0a6a1f1dSLionel Sambuc 	    "Test for bad minherit(2)");
181*0a6a1f1dSLionel Sambuc }
182*0a6a1f1dSLionel Sambuc 
ATF_TC_BODY(minherit_bad,tc)183*0a6a1f1dSLionel Sambuc ATF_TC_BODY(minherit_bad, tc)
184*0a6a1f1dSLionel Sambuc {
185*0a6a1f1dSLionel Sambuc 	(void)makemap(0, 666);
186*0a6a1f1dSLionel Sambuc }
187*0a6a1f1dSLionel Sambuc 
ATF_TP_ADD_TCS(tp)188*0a6a1f1dSLionel Sambuc ATF_TP_ADD_TCS(tp)
189*0a6a1f1dSLionel Sambuc {
190*0a6a1f1dSLionel Sambuc 	page = sysconf(_SC_PAGESIZE);
191*0a6a1f1dSLionel Sambuc 	ATF_REQUIRE(page >= 0);
192*0a6a1f1dSLionel Sambuc 
193*0a6a1f1dSLionel Sambuc 	ATF_TP_ADD_TC(tp, minherit_copy);
194*0a6a1f1dSLionel Sambuc 	ATF_TP_ADD_TC(tp, minherit_share);
195*0a6a1f1dSLionel Sambuc 	ATF_TP_ADD_TC(tp, minherit_none);
196*0a6a1f1dSLionel Sambuc 	ATF_TP_ADD_TC(tp, minherit_zero);
197*0a6a1f1dSLionel Sambuc 	ATF_TP_ADD_TC(tp, minherit_bad);
198*0a6a1f1dSLionel Sambuc 
199*0a6a1f1dSLionel Sambuc 	return atf_no_error();
200*0a6a1f1dSLionel Sambuc }
201