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