Home | History | Annotate | Line # | Download | only in sh
      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 
     30 atf_test_case basic_wait
     31 basic_wait_head() {
     32 	atf_set "descr" "Tests simple uses of wait"
     33 }
     34 basic_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 
     51 atf_test_case individual
     52 individual_head() {
     53 	atf_set "descr" "Tests that waiting for individual processes works"
     54 }
     55 individual_body() {
     56 	atf_require_prog sleep
     57 
     58 	cat >individualhelper.sh <<\EOF
     59 sleep 3 & P1=$!
     60 sleep 1 & P2=$!
     61 
     62 wait ${P1}
     63 S=$?
     64 if [ $S -ne 0 ]; then
     65     echo "Waiting for first process failed: $S"
     66     exit 1
     67 fi
     68 
     69 wait ${P2}
     70 S=$?
     71 if [ $? -ne 0 ]; then
     72     echo "Waiting for second process failed"
     73     exit 1
     74 fi
     75 
     76 exit 0
     77 EOF
     78 	output=$(${TEST_SH} individualhelper.sh 2>&1)
     79 	[ $? -eq 0 ] || atf_fail "${output}"
     80 }
     81 
     82 atf_test_case jobs
     83 jobs_head() {
     84 	atf_set "descr" "Tests that waiting for individual jobs works"
     85 }
     86 jobs_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
     96 sleep 3 &
     97 sleep 1 &
     98 
     99 wait %1
    100 if [ $? -ne 0 ]; then
    101     echo "Waiting for first job failed"
    102     exit 1
    103 fi
    104 
    105 wait %2
    106 if [ $? -ne 0 ]; then
    107     echo "Waiting for second job failed"
    108     exit 1
    109 fi
    110 
    111 exit 0
    112 EOF
    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 
    120 wait %1
    121 S=$?
    122 if [ $S -ne 3 ]; then
    123     echo "Waiting for first job failed - status: $S != 3 (expected)"
    124     exit 1
    125 fi
    126 
    127 wait %2
    128 S=$?
    129 if [ $S -ne 7 ]; then
    130     echo "Waiting for second job failed - status: $S != 7 (expected)"
    131     exit 1
    132 fi
    133 
    134 exit 0
    135 EOF
    136 
    137 	output=$(${TEST_SH} individualhelper.sh 2>&1)
    138 	[ $? -eq 0 ] || atf_fail "${output}"
    139 }
    140 
    141 atf_test_case kill
    142 kill_head() {
    143 	atf_set "descr" "Tests that killing the shell while in wait calls trap"
    144 }
    145 kill_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 
    162 trap "echo SIGHUP" 1
    163 (sleep 5; exit 3) &
    164 sl=$!
    165 wait
    166 S=$?
    167 echo $S
    168 LS=9999
    169 while [ $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
    174 EOF
    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 
    190 atf_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