1# $NetBSD: t_wait.sh,v 1.8 2016/03/31 16:22:54 christos Exp $ 2# 3# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27# the implementation of "sh" to test 28: ${TEST_SH:="/bin/sh"} 29 30atf_test_case basic_wait 31basic_wait_head() { 32 atf_set "descr" "Tests simple uses of wait" 33} 34basic_wait_body() { 35 atf_require_prog sleep 36 37 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 38 '(echo nothing >/dev/null) & wait' 39 40 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 41 '(exit 3) & wait $!; S=$?; test $S -eq 3 || { 42 echo "status: $S"; exit 1; }' 43 44 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 45 'sleep 3 & sleep 2 & sleep 1 & wait' 46 47 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 48 'sleep 3 & (exit 2) & sleep 1 & wait' 49} 50 51atf_test_case individual 52individual_head() { 53 atf_set "descr" "Tests that waiting for individual processes works" 54} 55individual_body() { 56 atf_require_prog sleep 57 58 cat >individualhelper.sh <<\EOF 59sleep 3 & P1=$! 60sleep 1 & P2=$! 61 62wait ${P1} 63S=$? 64if [ $S -ne 0 ]; then 65 echo "Waiting for first process failed: $S" 66 exit 1 67fi 68 69wait ${P2} 70S=$? 71if [ $? -ne 0 ]; then 72 echo "Waiting for second process failed" 73 exit 1 74fi 75 76exit 0 77EOF 78 output=$(${TEST_SH} individualhelper.sh 2>&1) 79 [ $? -eq 0 ] || atf_fail "${output}" 80} 81 82atf_test_case jobs 83jobs_head() { 84 atf_set "descr" "Tests that waiting for individual jobs works" 85} 86jobs_body() { 87 # atf-sh confuses wait for some reason; work it around by creating 88 # a helper script that executes /bin/sh directly. 89 90 if ! ${TEST_SH} -c 'sleep 1 & wait %1' 2>/dev/null 91 then 92 atf_skip "No job control support in this shell" 93 fi 94 95 cat >individualhelper.sh <<\EOF 96sleep 3 & 97sleep 1 & 98 99wait %1 100if [ $? -ne 0 ]; then 101 echo "Waiting for first job failed" 102 exit 1 103fi 104 105wait %2 106if [ $? -ne 0 ]; then 107 echo "Waiting for second job failed" 108 exit 1 109fi 110 111exit 0 112EOF 113 output=$(${TEST_SH} individualhelper.sh 2>&1) 114 [ $? -eq 0 ] || atf_fail "${output}" 115 116 cat >individualhelper.sh <<\EOF 117{ sleep 3; exit 3; } & 118{ sleep 1; exit 7; } & 119 120wait %1 121S=$? 122if [ $S -ne 3 ]; then 123 echo "Waiting for first job failed - status: $S != 3 (expected)" 124 exit 1 125fi 126 127wait %2 128S=$? 129if [ $S -ne 7 ]; then 130 echo "Waiting for second job failed - status: $S != 7 (expected)" 131 exit 1 132fi 133 134exit 0 135EOF 136 137 output=$(${TEST_SH} individualhelper.sh 2>&1) 138 [ $? -eq 0 ] || atf_fail "${output}" 139} 140 141atf_test_case kill 142kill_head() { 143 atf_set "descr" "Tests that killing the shell while in wait calls trap" 144} 145kill_body() { 146 atf_require_prog sleep 147 atf_require_prog kill 148 149 s=killhelper.sh 150 z=killhelper.$$ 151 pid= 152 153 # waiting for a specific process that is not a child 154 # should return exit status of 127 according to the spec 155 # This test is here before the next, to avoid that one 156 # entering an infinite loop should the shell have a bug here. 157 158 atf_check -s exit:127 -o empty -e ignore ${TEST_SH} -c 'wait 1' 159 160 cat > "${s}" <<'EOF' 161 162trap "echo SIGHUP" 1 163(sleep 5; exit 3) & 164sl=$! 165wait 166S=$? 167echo $S 168LS=9999 169while [ $S -ne 0 ] && [ $S != 127 ]; do 170 wait $sl; S=$?; echo $S 171 test $S = $LS && { echo "wait repeats..."; exit 2; } 172 LS=$S 173 done 174EOF 175 176 ${TEST_SH} $s > $z & 177 pid=$! 178 sleep 1 179 180 kill -HUP "${pid}" 181 wait 182 183 output="$(cat $z | tr '\n' ' ')" 184 185 if [ "$output" != "SIGHUP 129 3 127 " ]; then 186 atf_fail "${output} != 'SIGHUP 129 3 127 '" 187 fi 188} 189 190atf_init_test_cases() { 191 atf_add_test_case basic_wait 192 atf_add_test_case individual 193 atf_add_test_case jobs 194 atf_add_test_case kill 195} 196