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