1 /* $OpenBSD: t_wait_noproc.c,v 1.2 2021/12/13 16:56:48 deraadt 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 #ifndef __OpenBSD__ 72 ATF_TC(waitid); 73 ATF_TC_HEAD(waitid, tc) 74 { 75 atf_tc_set_md_var(tc, "descr", 76 "Test that waitid(2) returns ECHILD for P_ALL and option %s", 77 ___STRING(TWAIT_OPTION)); 78 } 79 80 ATF_TC_BODY(waitid, tc) 81 { 82 ATF_REQUIRE_ERRNO(ECHILD, 83 waitid(P_ALL, 0, NULL, 84 WTRAPPED | WEXITED | TWAIT_OPTION) == -1); 85 } 86 #endif 87 88 ATF_TC(wait3); 89 ATF_TC_HEAD(wait3, tc) 90 { 91 atf_tc_set_md_var(tc, "descr", 92 "Test that wait3(2) returns ECHILD for no child"); 93 } 94 95 ATF_TC_BODY(wait3, tc) 96 { 97 ATF_REQUIRE_ERRNO(ECHILD, wait3(NULL, TWAIT_OPTION, NULL) == -1); 98 } 99 100 ATF_TC(wait4); 101 ATF_TC_HEAD(wait4, tc) 102 { 103 atf_tc_set_md_var(tc, "descr", 104 "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s", 105 ___STRING(TWAIT_OPTION)); 106 } 107 108 ATF_TC_BODY(wait4, tc) 109 { 110 ATF_REQUIRE_ERRNO(ECHILD, 111 wait4(WAIT_ANY, NULL, TWAIT_OPTION, NULL) == -1); 112 } 113 114 #ifndef __OpenBSD__ 115 * Adjusted for OpenBSD, not available 116 * ATF_TC(wait6); 117 * ATF_TC_HEAD(wait6, tc) 118 * { 119 * atf_tc_set_md_var(tc, "descr", 120 * "Test that wait6(2) returns ECHILD for P_ALL and option %s", 121 * ___STRING(TWAIT_OPTION)); 122 * } 123 * 124 * ATF_TC_BODY(wait6, tc) 125 * { 126 * ATF_REQUIRE_ERRNO(ECHILD, 127 * wait6(P_ALL, 0, NULL, 128 * WTRAPPED | WEXITED | TWAIT_OPTION, NULL, NULL) == -1); 129 * } 130 */ 131 132 /* 133 * Generator of valid combinations of options 134 * Usage: i = 0; while ((o = get_options_wait6(i++)) != -1) {} 135 */ 136 static int 137 get_options6(size_t pos) 138 { 139 int rv = 0; 140 size_t n; 141 /* 142 * waitid(2) must specify at least one of WEXITED, WUNTRACED, 143 * WSTOPPED, WTRAPPED or WCONTINUED. Single option WNOWAIT 144 * isn't valid. 145 */ 146 const int matrix[] = { 147 WNOWAIT, // First in order to blacklist it easily 148 WEXITED, 149 WUNTRACED, 150 WSTOPPED, // SUS compatibility, equal to WUNTRACED 151 WTRAPPED, 152 WCONTINUED 153 }; 154 155 const size_t M = (1 << __arraycount(matrix)) - 1; 156 /* Skip empty and sole WNOWAIT option */ 157 pos+=2; 158 159 if (pos > M) 160 return -1; 161 162 for (n = 0; n < __arraycount(matrix); n++) { 163 if (pos & __BIT(n)) 164 rv |= matrix[n]; 165 } 166 167 return rv; 168 } 169 #endif 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 #ifndef __OpenBSD__ 247 ATF_TC(waitid_options); 248 ATF_TC_HEAD(waitid_options, tc) 249 { 250 atf_tc_set_md_var(tc, "descr", 251 "Test that waitid(2) returns ECHILD for P_ALL and valid " 252 "combination of options with%s WNOHANG", 253 TWAIT_OPTION == 0 ? "out" : ""); 254 } 255 256 ATF_TC_BODY(waitid_options, tc) 257 { 258 size_t i = 0; 259 int o; 260 261 while((o = get_options6(i++)) != -1) { 262 printf("Testing waitid(2) with options %x\n", o); 263 264 ATF_REQUIRE_ERRNO(ECHILD, 265 waitid(P_ALL, 0, NULL, o | TWAIT_OPTION) == -1); 266 } 267 } 268 #endif 269 270 ATF_TC(wait3_options); 271 ATF_TC_HEAD(wait3_options, tc) 272 { 273 atf_tc_set_md_var(tc, "descr", 274 "Test that wait3(2) returns ECHILD for no child"); 275 } 276 277 ATF_TC_BODY(wait3_options, tc) 278 { 279 size_t i = 0; 280 int o; 281 282 while((o = get_options4(i++)) != -1) { 283 printf("Testing wait3(2) with options %x\n", o); 284 285 ATF_REQUIRE_ERRNO(ECHILD, 286 wait3(NULL, o | TWAIT_OPTION, NULL) == -1); 287 } 288 } 289 290 ATF_TC(wait4_options); 291 ATF_TC_HEAD(wait4_options, tc) 292 { 293 atf_tc_set_md_var(tc, "descr", 294 "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s", 295 ___STRING(TWAIT_OPTION)); 296 } 297 298 ATF_TC_BODY(wait4_options, tc) 299 { 300 size_t i = 0; 301 int o; 302 303 while((o = get_options4(i++)) != -1) { 304 printf("Testing wait4(2) with options %x\n", o); 305 306 ATF_REQUIRE_ERRNO(ECHILD, 307 wait4(WAIT_ANY, NULL, o | TWAIT_OPTION, NULL) == -1); 308 } 309 } 310 311 #ifndef __OpenBSD__ 312 ATF_TC(wait6_options); 313 ATF_TC_HEAD(wait6_options, tc) 314 { 315 atf_tc_set_md_var(tc, "descr", 316 "Test that wait6(2) returns ECHILD for P_ALL and option %s", 317 ___STRING(TWAIT_OPTION)); 318 } 319 320 ATF_TC_BODY(wait6_options, tc) 321 { 322 size_t i = 0; 323 int o; 324 325 while((o = get_options6(i++)) != -1) { 326 printf("Testing wait6(2) with options %x\n", o); 327 328 ATF_REQUIRE_ERRNO(ECHILD, 329 wait6(P_ALL, 0, NULL, o | TWAIT_OPTION, NULL, NULL) == -1); 330 } 331 } 332 #endif 333 334 ATF_TP_ADD_TCS(tp) 335 { 336 337 #if TWAIT_OPTION == 0 338 ATF_TP_ADD_TC(tp, wait); 339 #endif 340 ATF_TP_ADD_TC(tp, waitpid); 341 #ifndef __OpenBSD__ 342 ATF_TP_ADD_TC(tp, waitid); 343 #endif 344 ATF_TP_ADD_TC(tp, wait3); 345 ATF_TP_ADD_TC(tp, wait4); 346 #ifndef __OpenBSD__ 347 ATF_TP_ADD_TC(tp, wait6); 348 #endif 349 350 ATF_TP_ADD_TC(tp, waitpid_options); 351 #ifndef __OpenBSD__ 352 ATF_TP_ADD_TC(tp, waitid_options); 353 #endif 354 ATF_TP_ADD_TC(tp, wait3_options); 355 ATF_TP_ADD_TC(tp, wait4_options); 356 #ifndef __OpenBSD__ 357 ATF_TP_ADD_TC(tp, wait6_options); 358 #endif 359 360 return atf_no_error(); 361 } 362