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