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