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