1*640235e2SEnji Cooper# $NetBSD: t_wait.sh,v 1.8 2016/03/31 16:22:54 christos Exp $ 257718be8SEnji Cooper# 357718be8SEnji Cooper# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc. 457718be8SEnji Cooper# All rights reserved. 557718be8SEnji Cooper# 657718be8SEnji Cooper# Redistribution and use in source and binary forms, with or without 757718be8SEnji Cooper# modification, are permitted provided that the following conditions 857718be8SEnji Cooper# are met: 957718be8SEnji Cooper# 1. Redistributions of source code must retain the above copyright 1057718be8SEnji Cooper# notice, this list of conditions and the following disclaimer. 1157718be8SEnji Cooper# 2. Redistributions in binary form must reproduce the above copyright 1257718be8SEnji Cooper# notice, this list of conditions and the following disclaimer in the 1357718be8SEnji Cooper# documentation and/or other materials provided with the distribution. 1457718be8SEnji Cooper# 1557718be8SEnji Cooper# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1657718be8SEnji Cooper# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1757718be8SEnji Cooper# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1857718be8SEnji Cooper# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 1957718be8SEnji Cooper# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2057718be8SEnji Cooper# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2157718be8SEnji Cooper# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2257718be8SEnji Cooper# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2357718be8SEnji Cooper# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2457718be8SEnji Cooper# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2557718be8SEnji Cooper# POSSIBILITY OF SUCH DAMAGE. 2657718be8SEnji Cooper# 27*640235e2SEnji Cooper# the implementation of "sh" to test 28*640235e2SEnji Cooper: ${TEST_SH:="/bin/sh"} 29*640235e2SEnji Cooper 30*640235e2SEnji Cooperatf_test_case basic_wait 31*640235e2SEnji Cooperbasic_wait_head() { 32*640235e2SEnji Cooper atf_set "descr" "Tests simple uses of wait" 33*640235e2SEnji Cooper} 34*640235e2SEnji Cooperbasic_wait_body() { 35*640235e2SEnji Cooper atf_require_prog sleep 36*640235e2SEnji Cooper 37*640235e2SEnji Cooper atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 38*640235e2SEnji Cooper '(echo nothing >/dev/null) & wait' 39*640235e2SEnji Cooper 40*640235e2SEnji Cooper atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 41*640235e2SEnji Cooper '(exit 3) & wait $!; S=$?; test $S -eq 3 || { 42*640235e2SEnji Cooper echo "status: $S"; exit 1; }' 43*640235e2SEnji Cooper 44*640235e2SEnji Cooper atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 45*640235e2SEnji Cooper 'sleep 3 & sleep 2 & sleep 1 & wait' 46*640235e2SEnji Cooper 47*640235e2SEnji Cooper atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 48*640235e2SEnji Cooper 'sleep 3 & (exit 2) & sleep 1 & wait' 49*640235e2SEnji Cooper} 5057718be8SEnji Cooper 5157718be8SEnji Cooperatf_test_case individual 5257718be8SEnji Cooperindividual_head() { 53*640235e2SEnji Cooper atf_set "descr" "Tests that waiting for individual processes works" 5457718be8SEnji Cooper} 5557718be8SEnji Cooperindividual_body() { 56*640235e2SEnji Cooper atf_require_prog sleep 5757718be8SEnji Cooper 58*640235e2SEnji Cooper cat >individualhelper.sh <<\EOF 59*640235e2SEnji Coopersleep 3 & P1=$! 60*640235e2SEnji Coopersleep 1 & P2=$! 61*640235e2SEnji Cooper 62*640235e2SEnji Cooperwait ${P1} 63*640235e2SEnji CooperS=$? 64*640235e2SEnji Cooperif [ $S -ne 0 ]; then 65*640235e2SEnji Cooper echo "Waiting for first process failed: $S" 6657718be8SEnji Cooper exit 1 6757718be8SEnji Cooperfi 6857718be8SEnji Cooper 69*640235e2SEnji Cooperwait ${P2} 70*640235e2SEnji CooperS=$? 71*640235e2SEnji Cooperif [ $? -ne 0 ]; then 72*640235e2SEnji Cooper echo "Waiting for second process failed" 7357718be8SEnji Cooper exit 1 7457718be8SEnji Cooperfi 7557718be8SEnji Cooper 7657718be8SEnji Cooperexit 0 7757718be8SEnji CooperEOF 78*640235e2SEnji Cooper output=$(${TEST_SH} individualhelper.sh 2>&1) 7957718be8SEnji Cooper [ $? -eq 0 ] || atf_fail "${output}" 8057718be8SEnji Cooper} 8157718be8SEnji Cooper 82*640235e2SEnji Cooperatf_test_case jobs 83*640235e2SEnji Cooperjobs_head() { 84*640235e2SEnji Cooper atf_set "descr" "Tests that waiting for individual jobs works" 85*640235e2SEnji Cooper} 86*640235e2SEnji Cooperjobs_body() { 87*640235e2SEnji Cooper # atf-sh confuses wait for some reason; work it around by creating 88*640235e2SEnji Cooper # a helper script that executes /bin/sh directly. 89*640235e2SEnji Cooper 90*640235e2SEnji Cooper if ! ${TEST_SH} -c 'sleep 1 & wait %1' 2>/dev/null 91*640235e2SEnji Cooper then 92*640235e2SEnji Cooper atf_skip "No job control support in this shell" 93*640235e2SEnji Cooper fi 94*640235e2SEnji Cooper 95*640235e2SEnji Cooper cat >individualhelper.sh <<\EOF 96*640235e2SEnji Coopersleep 3 & 97*640235e2SEnji Coopersleep 1 & 98*640235e2SEnji Cooper 99*640235e2SEnji Cooperwait %1 100*640235e2SEnji Cooperif [ $? -ne 0 ]; then 101*640235e2SEnji Cooper echo "Waiting for first job failed" 102*640235e2SEnji Cooper exit 1 103*640235e2SEnji Cooperfi 104*640235e2SEnji Cooper 105*640235e2SEnji Cooperwait %2 106*640235e2SEnji Cooperif [ $? -ne 0 ]; then 107*640235e2SEnji Cooper echo "Waiting for second job failed" 108*640235e2SEnji Cooper exit 1 109*640235e2SEnji Cooperfi 110*640235e2SEnji Cooper 111*640235e2SEnji Cooperexit 0 112*640235e2SEnji CooperEOF 113*640235e2SEnji Cooper output=$(${TEST_SH} individualhelper.sh 2>&1) 114*640235e2SEnji Cooper [ $? -eq 0 ] || atf_fail "${output}" 115*640235e2SEnji Cooper 116*640235e2SEnji Cooper cat >individualhelper.sh <<\EOF 117*640235e2SEnji Cooper{ sleep 3; exit 3; } & 118*640235e2SEnji Cooper{ sleep 1; exit 7; } & 119*640235e2SEnji Cooper 120*640235e2SEnji Cooperwait %1 121*640235e2SEnji CooperS=$? 122*640235e2SEnji Cooperif [ $S -ne 3 ]; then 123*640235e2SEnji Cooper echo "Waiting for first job failed - status: $S != 3 (expected)" 124*640235e2SEnji Cooper exit 1 125*640235e2SEnji Cooperfi 126*640235e2SEnji Cooper 127*640235e2SEnji Cooperwait %2 128*640235e2SEnji CooperS=$? 129*640235e2SEnji Cooperif [ $S -ne 7 ]; then 130*640235e2SEnji Cooper echo "Waiting for second job failed - status: $S != 7 (expected)" 131*640235e2SEnji Cooper exit 1 132*640235e2SEnji Cooperfi 133*640235e2SEnji Cooper 134*640235e2SEnji Cooperexit 0 135*640235e2SEnji CooperEOF 136*640235e2SEnji Cooper 137*640235e2SEnji Cooper output=$(${TEST_SH} individualhelper.sh 2>&1) 138*640235e2SEnji Cooper [ $? -eq 0 ] || atf_fail "${output}" 139*640235e2SEnji Cooper} 140*640235e2SEnji Cooper 141*640235e2SEnji Cooperatf_test_case kill 142*640235e2SEnji Cooperkill_head() { 143*640235e2SEnji Cooper atf_set "descr" "Tests that killing the shell while in wait calls trap" 144*640235e2SEnji Cooper} 145*640235e2SEnji Cooperkill_body() { 146*640235e2SEnji Cooper atf_require_prog sleep 147*640235e2SEnji Cooper atf_require_prog kill 148*640235e2SEnji Cooper 149*640235e2SEnji Cooper s=killhelper.sh 150*640235e2SEnji Cooper z=killhelper.$$ 151*640235e2SEnji Cooper pid= 152*640235e2SEnji Cooper 153*640235e2SEnji Cooper # waiting for a specific process that is not a child 154*640235e2SEnji Cooper # should return exit status of 127 according to the spec 155*640235e2SEnji Cooper # This test is here before the next, to avoid that one 156*640235e2SEnji Cooper # entering an infinite loop should the shell have a bug here. 157*640235e2SEnji Cooper 158*640235e2SEnji Cooper atf_check -s exit:127 -o empty -e ignore ${TEST_SH} -c 'wait 1' 159*640235e2SEnji Cooper 160*640235e2SEnji Cooper cat > "${s}" <<'EOF' 161*640235e2SEnji Cooper 162*640235e2SEnji Coopertrap "echo SIGHUP" 1 163*640235e2SEnji Cooper(sleep 5; exit 3) & 164*640235e2SEnji Coopersl=$! 165*640235e2SEnji Cooperwait 166*640235e2SEnji CooperS=$? 167*640235e2SEnji Cooperecho $S 168*640235e2SEnji CooperLS=9999 169*640235e2SEnji Cooperwhile [ $S -ne 0 ] && [ $S != 127 ]; do 170*640235e2SEnji Cooper wait $sl; S=$?; echo $S 171*640235e2SEnji Cooper test $S = $LS && { echo "wait repeats..."; exit 2; } 172*640235e2SEnji Cooper LS=$S 173*640235e2SEnji Cooper done 174*640235e2SEnji CooperEOF 175*640235e2SEnji Cooper 176*640235e2SEnji Cooper ${TEST_SH} $s > $z & 177*640235e2SEnji Cooper pid=$! 178*640235e2SEnji Cooper sleep 1 179*640235e2SEnji Cooper 180*640235e2SEnji Cooper kill -HUP "${pid}" 181*640235e2SEnji Cooper wait 182*640235e2SEnji Cooper 183*640235e2SEnji Cooper output="$(cat $z | tr '\n' ' ')" 184*640235e2SEnji Cooper 185*640235e2SEnji Cooper if [ "$output" != "SIGHUP 129 3 127 " ]; then 186*640235e2SEnji Cooper atf_fail "${output} != 'SIGHUP 129 3 127 '" 187*640235e2SEnji Cooper fi 188*640235e2SEnji Cooper} 189*640235e2SEnji Cooper 19057718be8SEnji Cooperatf_init_test_cases() { 191*640235e2SEnji Cooper atf_add_test_case basic_wait 19257718be8SEnji Cooper atf_add_test_case individual 193*640235e2SEnji Cooper atf_add_test_case jobs 194*640235e2SEnji Cooper atf_add_test_case kill 19557718be8SEnji Cooper} 196