1 /* $OpenBSD: t_wait_noproc.c,v 1.4 2022/12/19 22:44:54 guenther 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/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 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 #ifndef __OpenBSD__ 113 * Adjusted for OpenBSD, not available 114 * ATF_TC(wait6); 115 * ATF_TC_HEAD(wait6, tc) 116 * { 117 * atf_tc_set_md_var(tc, "descr", 118 * "Test that wait6(2) returns ECHILD for P_ALL and option %s", 119 * ___STRING(TWAIT_OPTION)); 120 * } 121 * 122 * ATF_TC_BODY(wait6, tc) 123 * { 124 * ATF_REQUIRE_ERRNO(ECHILD, 125 * wait6(P_ALL, 0, NULL, 126 * WTRAPPED | WEXITED | TWAIT_OPTION, NULL, NULL) == -1); 127 * } 128 */ 129 #endif 130 131 /* 132 * Generator of valid combinations of options 133 * Usage: i = 0; while ((o = get_options_wait6(i++)) != -1) {} 134 */ 135 static int 136 get_options6(size_t pos) 137 { 138 int rv = 0; 139 size_t n; 140 /* 141 * waitid(2) must specify at least one of WEXITED, WUNTRACED, 142 * WSTOPPED, WTRAPPED or WCONTINUED. Single option WNOWAIT 143 * isn't valid. 144 */ 145 const int matrix[] = { 146 WNOWAIT, // First in order to blacklist it easily 147 WEXITED, 148 #ifndef __OpenBSD__ 149 WUNTRACED, 150 #endif 151 WSTOPPED, // SUS compatibility, equal to WUNTRACED 152 WTRAPPED, 153 WCONTINUED 154 }; 155 156 const size_t M = (1 << __arraycount(matrix)) - 1; 157 /* Skip empty and sole WNOWAIT option */ 158 pos+=2; 159 160 if (pos > M) 161 return -1; 162 163 for (n = 0; n < __arraycount(matrix); n++) { 164 if (pos & __BIT(n)) 165 rv |= matrix[n]; 166 } 167 168 return rv; 169 } 170 171 /* 172 * Generator of valid combinations of options 173 * Usage: i = 0; while ((o = get_options_wait4(i++)) != -1) {} 174 */ 175 static int 176 get_options4(size_t pos) 177 { 178 int rv = 0; 179 size_t n; 180 181 const int special[] = { 182 0, 183 #ifndef __OpenBSD__ 184 WALLSIG, 185 WALTSIG, 186 __WALL, // Linux compatibility, equal to WALLSIG 187 __WCLONE // Linux compatibility, equal to WALTSIG 188 #endif 189 }; 190 191 const int matrix[] = { 192 #ifndef __OpenBSD__ 193 WNOWAIT, 194 WEXITED, 195 #endif 196 WUNTRACED, 197 #ifndef __OpenBSD__ 198 WSTOPPED, // SUS compatibility, equal to WUNTRACED 199 WTRAPPED, 200 #endif 201 WCONTINUED 202 }; 203 204 const size_t M = (1 << __arraycount(special)) - 1; 205 206 if (pos < __arraycount(special)) 207 return special[pos]; 208 209 pos -= __arraycount(special); 210 211 ++pos; /* Don't start with empty mask */ 212 213 if (pos > M) 214 return -1; 215 216 for (n = 0; n < __arraycount(special); n++) { 217 if (pos & __BIT(n)) 218 rv |= matrix[n]; 219 } 220 221 return rv; 222 } 223 224 ATF_TC(waitpid_options); 225 ATF_TC_HEAD(waitpid_options, tc) 226 { 227 atf_tc_set_md_var(tc, "descr", 228 "Test that waitpid(2) returns ECHILD for WAIT_ANY and valid " 229 "combination of options with%s WNOHANG", 230 TWAIT_OPTION == 0 ? "out" : ""); 231 } 232 233 ATF_TC_BODY(waitpid_options, tc) 234 { 235 size_t i = 0; 236 int o; 237 238 while((o = get_options4(i++)) != -1) { 239 printf("Testing waitpid(2) with options %x\n", o); 240 241 ATF_REQUIRE_ERRNO(ECHILD, 242 waitpid(WAIT_ANY, NULL, o | TWAIT_OPTION) == -1); 243 } 244 } 245 246 ATF_TC(waitid_options); 247 ATF_TC_HEAD(waitid_options, tc) 248 { 249 atf_tc_set_md_var(tc, "descr", 250 "Test that waitid(2) returns ECHILD for P_ALL and valid " 251 "combination of options with%s WNOHANG", 252 TWAIT_OPTION == 0 ? "out" : ""); 253 } 254 255 ATF_TC_BODY(waitid_options, tc) 256 { 257 size_t i = 0; 258 int o; 259 260 while((o = get_options6(i++)) != -1) { 261 printf("Testing waitid(2) with options %x\n", o); 262 263 ATF_REQUIRE_ERRNO(ECHILD, 264 waitid(P_ALL, 0, NULL, o | TWAIT_OPTION) == -1); 265 } 266 } 267 268 ATF_TC(wait3_options); 269 ATF_TC_HEAD(wait3_options, tc) 270 { 271 atf_tc_set_md_var(tc, "descr", 272 "Test that wait3(2) returns ECHILD for no child"); 273 } 274 275 ATF_TC_BODY(wait3_options, tc) 276 { 277 size_t i = 0; 278 int o; 279 280 while((o = get_options4(i++)) != -1) { 281 printf("Testing wait3(2) with options %x\n", o); 282 283 ATF_REQUIRE_ERRNO(ECHILD, 284 wait3(NULL, o | TWAIT_OPTION, NULL) == -1); 285 } 286 } 287 288 ATF_TC(wait4_options); 289 ATF_TC_HEAD(wait4_options, tc) 290 { 291 atf_tc_set_md_var(tc, "descr", 292 "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s", 293 ___STRING(TWAIT_OPTION)); 294 } 295 296 ATF_TC_BODY(wait4_options, tc) 297 { 298 size_t i = 0; 299 int o; 300 301 while((o = get_options4(i++)) != -1) { 302 printf("Testing wait4(2) with options %x\n", o); 303 304 ATF_REQUIRE_ERRNO(ECHILD, 305 wait4(WAIT_ANY, NULL, o | TWAIT_OPTION, NULL) == -1); 306 } 307 } 308 309 #ifndef __OpenBSD__ 310 ATF_TC(wait6_options); 311 ATF_TC_HEAD(wait6_options, tc) 312 { 313 atf_tc_set_md_var(tc, "descr", 314 "Test that wait6(2) returns ECHILD for P_ALL and option %s", 315 ___STRING(TWAIT_OPTION)); 316 } 317 318 ATF_TC_BODY(wait6_options, tc) 319 { 320 size_t i = 0; 321 int o; 322 323 while((o = get_options6(i++)) != -1) { 324 printf("Testing wait6(2) with options %x\n", o); 325 326 ATF_REQUIRE_ERRNO(ECHILD, 327 wait6(P_ALL, 0, NULL, o | TWAIT_OPTION, NULL, NULL) == -1); 328 } 329 } 330 #endif 331 332 ATF_TP_ADD_TCS(tp) 333 { 334 335 #if TWAIT_OPTION == 0 336 ATF_TP_ADD_TC(tp, wait); 337 #endif 338 ATF_TP_ADD_TC(tp, waitpid); 339 ATF_TP_ADD_TC(tp, waitid); 340 ATF_TP_ADD_TC(tp, wait3); 341 ATF_TP_ADD_TC(tp, wait4); 342 #ifndef __OpenBSD__ 343 ATF_TP_ADD_TC(tp, wait6); 344 #endif 345 346 ATF_TP_ADD_TC(tp, waitpid_options); 347 ATF_TP_ADD_TC(tp, waitid_options); 348 ATF_TP_ADD_TC(tp, wait3_options); 349 ATF_TP_ADD_TC(tp, wait4_options); 350 #ifndef __OpenBSD__ 351 ATF_TP_ADD_TC(tp, wait6_options); 352 #endif 353 354 return atf_no_error(); 355 } 356