t_redir.sh revision 1.14 1 1.14 kre # $NetBSD: t_redir.sh,v 1.14 2021/11/21 20:50:35 kre Exp $
2 1.1 christos #
3 1.1 christos # Copyright (c) 2016 The NetBSD Foundation, Inc.
4 1.1 christos # All rights reserved.
5 1.1 christos #
6 1.1 christos # Redistribution and use in source and binary forms, with or without
7 1.1 christos # modification, are permitted provided that the following conditions
8 1.1 christos # are met:
9 1.1 christos # 1. Redistributions of source code must retain the above copyright
10 1.1 christos # notice, this list of conditions and the following disclaimer.
11 1.1 christos # 2. Redistributions in binary form must reproduce the above copyright
12 1.1 christos # notice, this list of conditions and the following disclaimer in the
13 1.1 christos # documentation and/or other materials provided with the distribution.
14 1.1 christos #
15 1.1 christos # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16 1.1 christos # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 1.1 christos # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 1.1 christos # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19 1.1 christos # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 1.1 christos # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 1.1 christos # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 1.1 christos # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 1.1 christos # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 1.1 christos # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 1.1 christos # POSSIBILITY OF SUCH DAMAGE.
26 1.1 christos #
27 1.2 christos # the implementation of "sh" to test
28 1.2 christos : ${TEST_SH:="/bin/sh"}
29 1.1 christos
30 1.4 christos # Any failures in this first test means it is not worth bothering looking
31 1.4 christos # for causes of failures in any other tests, make this one work first.
32 1.4 christos
33 1.4 christos # Problems with this test usually mean inadequate ATF_SHELL used for testing.
34 1.4 christos # (though if all pass but the last, it might be a TEST_SH problem.)
35 1.4 christos
36 1.4 christos atf_test_case basic_test_method_test
37 1.4 christos basic_test_method_test_head()
38 1.4 christos {
39 1.4 christos atf_set "descr" "Tests that test method works as expected"
40 1.4 christos }
41 1.4 christos basic_test_method_test_body()
42 1.4 christos {
43 1.4 christos cat <<- 'DONE' |
44 1.4 christos DONE
45 1.14 kre atf_check -s exit:0 -o empty -e empty ${TEST_SH} ||
46 1.14 kre atf_fail 'empty piped input'
47 1.4 christos cat <<- 'DONE' |
48 1.4 christos DONE
49 1.14 kre atf_check -s exit:0 -o match:0 -e empty ${TEST_SH} -c 'wc -l' ||
50 1.14 kre atf_fail 'empty piped input line count'
51 1.4 christos
52 1.4 christos cat <<- 'DONE' |
53 1.4 christos echo hello
54 1.4 christos DONE
55 1.14 kre atf_check -s exit:0 -o match:hello -e empty ${TEST_SH} ||
56 1.14 kre atf_fail 'piped hello'
57 1.4 christos cat <<- 'DONE' |
58 1.4 christos echo hello
59 1.4 christos DONE
60 1.14 kre atf_check -s exit:0 -o match:1 -e empty ${TEST_SH} -c 'wc -l' ||
61 1.14 kre atf_fail 'piped hello line count'
62 1.4 christos
63 1.4 christos cat <<- 'DONE' |
64 1.4 christos echo hello\
65 1.4 christos world
66 1.4 christos DONE
67 1.14 kre atf_check -s exit:0 -o match:helloworld -e empty ${TEST_SH} ||
68 1.14 kre atf_fail 'piped hello world'
69 1.4 christos cat <<- 'DONE' |
70 1.4 christos echo hello\
71 1.4 christos world
72 1.4 christos DONE
73 1.14 kre atf_check -s exit:0 -o match:2 -e empty ${TEST_SH} -c 'wc -l' ||
74 1.14 kre atf_fail 'piped hello world line check'
75 1.4 christos
76 1.4 christos printf '%s\n%s\n%s\n' Line1 Line2 Line3 > File
77 1.4 christos atf_check -s exit:0 -o inline:'Line1\nLine2\nLine3\n' -e empty \
78 1.4 christos ${TEST_SH} -c 'cat File'
79 1.4 christos
80 1.4 christos cat <<- 'DONE' |
81 1.4 christos set -- X "" '' Y
82 1.4 christos echo ARGS="${#}"
83 1.4 christos echo '' -$1- -$2- -$3- -$4-
84 1.4 christos cat <<EOF
85 1.4 christos X=$1
86 1.4 christos EOF
87 1.4 christos cat <<\EOF
88 1.4 christos Y=$4
89 1.4 christos EOF
90 1.4 christos DONE
91 1.4 christos atf_check -s exit:0 -o match:ARGS=4 -o match:'-X- -- -- -Y-' \
92 1.14 kre -o match:X=X -o match:'Y=\$4' -e empty ${TEST_SH} ||
93 1.14 kre atf_fail "complex piped input"
94 1.14 kre
95 1.14 kre cat <<- 'DONE' |
96 1.14 kre echo expect to see a non-detected failure here
97 1.14 kre DONE
98 1.14 kre atf_check -s exit:1 -o empty -e empty ${TEST_SH} &&
99 1.14 kre atf_fail "Failed to fail as expected"
100 1.14 kre
101 1.14 kre return 0
102 1.4 christos }
103 1.4 christos
104 1.4 christos atf_test_case do_input_redirections
105 1.4 christos do_input_redirections_head()
106 1.4 christos {
107 1.4 christos atf_set "descr" "Tests that simple input redirection works"
108 1.4 christos }
109 1.4 christos do_input_redirections_body()
110 1.4 christos {
111 1.4 christos printf '%s\n%s\n%s\nEND\n' 'First Line' 'Second Line' 'Line 3' >File
112 1.4 christos
113 1.4 christos atf_check -s exit:0 -e empty \
114 1.4 christos -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
115 1.4 christos ${TEST_SH} -c 'cat < File'
116 1.4 christos atf_check -s exit:0 -e empty \
117 1.4 christos -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
118 1.4 christos ${TEST_SH} -c 'cat <File'
119 1.4 christos atf_check -s exit:0 -e empty \
120 1.4 christos -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
121 1.4 christos ${TEST_SH} -c 'cat< File'
122 1.4 christos atf_check -s exit:0 -e empty \
123 1.4 christos -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
124 1.4 christos ${TEST_SH} -c 'cat < "File"'
125 1.4 christos atf_check -s exit:0 -e empty \
126 1.4 christos -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
127 1.4 christos ${TEST_SH} -c '< File cat'
128 1.4 christos
129 1.4 christos ln File wc
130 1.4 christos atf_check -s exit:0 -e empty \
131 1.4 christos -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
132 1.4 christos ${TEST_SH} -c '< wc cat'
133 1.4 christos
134 1.4 christos mv wc cat
135 1.4 christos atf_check -s exit:0 -e empty -o match:4 \
136 1.4 christos ${TEST_SH} -c '< cat wc'
137 1.4 christos
138 1.4 christos
139 1.4 christos cat <<- 'EOF' |
140 1.5 christos for l in 1 2 3; do
141 1.4 christos read line < File
142 1.4 christos echo "$line"
143 1.4 christos done
144 1.4 christos EOF
145 1.4 christos atf_check -s exit:0 -e empty \
146 1.4 christos -o inline:'First Line\nFirst Line\nFirst Line\n' \
147 1.14 kre ${TEST_SH} ||
148 1.14 kre atf_fail 'loop rereading first line'
149 1.4 christos
150 1.4 christos cat <<- 'EOF' |
151 1.5 christos for l in 1 2 3; do
152 1.4 christos read line
153 1.4 christos echo "$line"
154 1.4 christos done <File
155 1.4 christos EOF
156 1.4 christos atf_check -s exit:0 -e empty \
157 1.4 christos -o inline:'First Line\nSecond Line\nLine 3\n' \
158 1.14 kre ${TEST_SH} ||
159 1.14 kre atf_fail 'loop reading file'
160 1.4 christos
161 1.4 christos cat <<- 'EOF' |
162 1.5 christos for l in 1 2 3; do
163 1.4 christos read line < File
164 1.4 christos echo "$line"
165 1.4 christos done <File
166 1.4 christos EOF
167 1.4 christos atf_check -s exit:0 -e empty \
168 1.4 christos -o inline:'First Line\nFirst Line\nFirst Line\n' \
169 1.14 kre ${TEST_SH} ||
170 1.14 kre atf_fail 'double redirect'
171 1.4 christos
172 1.4 christos cat <<- 'EOF' |
173 1.4 christos line=
174 1.4 christos while [ "$line" != END ]; do
175 1.4 christos read line || exit 1
176 1.4 christos echo "$line"
177 1.4 christos done <File
178 1.4 christos EOF
179 1.4 christos atf_check -s exit:0 -e empty \
180 1.4 christos -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
181 1.14 kre ${TEST_SH} ||
182 1.14 kre atf_fail 'read and test content'
183 1.4 christos
184 1.4 christos cat <<- 'EOF' |
185 1.4 christos while :; do
186 1.4 christos read line || exit 0
187 1.4 christos echo "$line"
188 1.4 christos done <File
189 1.4 christos EOF
190 1.4 christos atf_check -s exit:0 -e empty \
191 1.4 christos -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
192 1.14 kre ${TEST_SH} ||
193 1.14 kre atf_fail 'read and test status'
194 1.4 christos
195 1.4 christos cat <<- 'EOF' |
196 1.5 christos l=''
197 1.4 christos while read line < File
198 1.4 christos do
199 1.4 christos echo "$line"
200 1.5 christos l="${l}x"
201 1.5 christos [ ${#l} -ge 3 ] && break
202 1.4 christos done
203 1.4 christos echo DONE
204 1.4 christos EOF
205 1.4 christos atf_check -s exit:0 -e empty \
206 1.4 christos -o inline:'First Line\nFirst Line\nFirst Line\nDONE\n' \
207 1.14 kre ${TEST_SH} ||
208 1.14 kre atf_fail 'read 3 lines'
209 1.4 christos
210 1.4 christos cat <<- 'EOF' |
211 1.4 christos while read line
212 1.4 christos do
213 1.4 christos echo "$line"
214 1.4 christos done <File
215 1.4 christos echo DONE
216 1.4 christos EOF
217 1.4 christos atf_check -s exit:0 -e empty \
218 1.4 christos -o inline:'First Line\nSecond Line\nLine 3\nEND\nDONE\n' \
219 1.14 kre ${TEST_SH} ||
220 1.14 kre atf_fail 'read to EOF'
221 1.4 christos
222 1.4 christos cat <<- 'EOF' |
223 1.5 christos l=''
224 1.4 christos while read line
225 1.4 christos do
226 1.4 christos echo "$line"
227 1.5 christos l="${l}x"
228 1.5 christos [ ${#l} -ge 3 ] && break
229 1.4 christos done <File
230 1.4 christos echo DONE
231 1.4 christos EOF
232 1.4 christos atf_check -s exit:0 -e empty \
233 1.14 kre -o inline:'First Line\nSecond Line\nLine 3\nDONE\n' \
234 1.14 kre ${TEST_SH} ||
235 1.14 kre atf_fail 'read 3 and break'
236 1.4 christos
237 1.4 christos cat <<- 'EOF' |
238 1.5 christos l=''
239 1.4 christos while read line1 <File
240 1.4 christos do
241 1.4 christos read line2
242 1.4 christos echo "$line1":"$line2"
243 1.5 christos l="${l}x"
244 1.5 christos [ ${#l} -ge 2 ] && break
245 1.4 christos done <File
246 1.4 christos echo DONE
247 1.4 christos EOF
248 1.4 christos atf_check -s exit:0 -e empty \
249 1.4 christos -o inline:'First Line:First Line\nFirst Line:Second Line\nDONE\n' \
250 1.14 kre ${TEST_SH} ||
251 1.14 kre atf_fail 'read and read again'
252 1.4 christos }
253 1.4 christos
254 1.4 christos atf_test_case do_output_redirections
255 1.4 christos do_output_redirections_head()
256 1.4 christos {
257 1.4 christos atf_set "descr" "Test Output redirections"
258 1.4 christos }
259 1.4 christos do_output_redirections_body()
260 1.4 christos {
261 1.4 christos nl='
262 1.4 christos '
263 1.4 christos T=0
264 1.5 christos i() { T=$(expr "$T" + 1); }
265 1.4 christos
266 1.4 christos rm -f Output 2>/dev/null || :
267 1.4 christos test -f Output && atf_fail "Unable to remove Output file"
268 1.4 christos #1
269 1.4 christos i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '> Output'
270 1.4 christos test -f Output || atf_fail "#$T: Did not make Output file"
271 1.4 christos #2
272 1.4 christos rm -f Output 2>/dev/null || :
273 1.4 christos i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '>> Output'
274 1.4 christos test -f Output || atf_fail "#$T: Did not make Output file"
275 1.4 christos #3
276 1.4 christos rm -f Output 2>/dev/null || :
277 1.4 christos i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '>| Output'
278 1.4 christos test -f Output || atf_fail "#$T: Did not make Output file"
279 1.4 christos
280 1.4 christos #4
281 1.4 christos rm -f Output 2>/dev/null || :
282 1.4 christos i
283 1.4 christos atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Hello >Output'
284 1.4 christos test -s Output || atf_fail "#$T: Did not make non-empty Output file"
285 1.4 christos test "$(cat Output)" = "Hello" ||
286 1.4 christos atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'"
287 1.4 christos #5
288 1.4 christos i
289 1.4 christos atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Hello>!Output'
290 1.4 christos test -s Output || atf_fail "#$T: Did not make non-empty Output file"
291 1.4 christos test "$(cat Output)" = "Hello" ||
292 1.4 christos atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'"
293 1.4 christos #6
294 1.4 christos i
295 1.4 christos atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Bye >>Output'
296 1.4 christos test -s Output || atf_fail "#$T: Removed Output file"
297 1.4 christos test "$(cat Output)" = "Hello${nl}Bye" || atf_fail \
298 1.4 christos "#$T: Incorrect Output: Should be 'Hello\\nBye' is '$(cat Output)'"
299 1.4 christos #7
300 1.4 christos i; atf_check -s exit:0 -o inline:'line 1\nline 2\n' -e empty \
301 1.4 christos ${TEST_SH} -c \
302 1.4 christos 'echo line 1 > Output; echo line 2 >> Output; cat Output'
303 1.4 christos test "$(cat Output)" = "line 1${nl}line 2" || atf_fail \
304 1.4 christos "#$T: Incorrect Output: Should be 'line 1\\nline 2' is '$(cat Output)'"
305 1.4 christos #8
306 1.4 christos i; atf_check -s exit:0 -o inline:'line 2\n' -e empty \
307 1.4 christos ${TEST_SH} -c 'echo line 1 > Output; echo line 2'
308 1.4 christos test "$(cat Output)" = "line 1" || atf_fail \
309 1.4 christos "#$T: Incorrect Output: Should be 'line 1' is '$(cat Output)'"
310 1.4 christos #9
311 1.4 christos i; atf_check -s exit:0 -o empty -e empty \
312 1.4 christos ${TEST_SH} -c '(echo line 1; echo line 2 > Out2) > Out1'
313 1.4 christos test "$(cat Out1)" = "line 1" || atf_fail \
314 1.4 christos "#$T: Incorrect Out1: Should be 'line 1' is '$(cat Out1)'"
315 1.4 christos test "$(cat Out2)" = "line 2" || atf_fail \
316 1.4 christos "#$T: Incorrect Out2: Should be 'line 2' is '$(cat Out2)'"
317 1.4 christos #10
318 1.4 christos i; atf_check -s exit:0 -o empty -e empty \
319 1.4 christos ${TEST_SH} -c '{ echo line 1; echo line 2 > Out2;} > Out1'
320 1.4 christos test "$(cat Out1)" = "line 1" || atf_fail \
321 1.4 christos "#$T: Incorrect Out1: Should be 'line 1' is '$(cat Out1)'"
322 1.4 christos test "$(cat Out2)" = "line 2" || atf_fail \
323 1.4 christos "#$T: Incorrect Out2: Should be 'line 2' is '$(cat Out2)'"
324 1.4 christos #11
325 1.4 christos i; rm -f Out1 Out2 2>/dev/null || :
326 1.4 christos cat <<- 'EOF' |
327 1.4 christos for arg in 'line 1' 'line 2' 'line 3'
328 1.4 christos do
329 1.4 christos echo "$arg"
330 1.4 christos echo "$arg" > Out1
331 1.4 christos done > Out2
332 1.4 christos EOF
333 1.14 kre atf_check -s exit:0 -o empty -e empty ${TEST_SH} ||
334 1.14 kre atf_fail "#$T: not empty/empty/0"
335 1.4 christos test "$(cat Out1)" = "line 3" || atf_fail \
336 1.4 christos "#$T: Incorrect Out1: Should be 'line 3' is '$(cat Out1)'"
337 1.4 christos test "$(cat Out2)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
338 1.4 christos "#$T: Incorrect Out2: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out2)'"
339 1.4 christos #12
340 1.4 christos i; rm -f Out1 Out2 2>/dev/null || :
341 1.4 christos cat <<- 'EOF' |
342 1.4 christos for arg in 'line 1' 'line 2' 'line 3'
343 1.4 christos do
344 1.4 christos echo "$arg"
345 1.4 christos echo "$arg" >> Out1
346 1.4 christos done > Out2
347 1.4 christos EOF
348 1.14 kre atf_check -s exit:0 -o empty -e empty ${TEST_SH} ||
349 1.14 kre atf_fail "#$T: not empty/empty/0"
350 1.4 christos test "$(cat Out1)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
351 1.4 christos "#$T: Incorrect Out1: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out1)'"
352 1.4 christos test "$(cat Out2)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
353 1.4 christos "#$T: Incorrect Out2: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out2)'"
354 1.4 christos }
355 1.4 christos
356 1.10 kre atf_test_case do_redirect_input_output
357 1.10 kre do_redirect_input_output_head()
358 1.10 kre {
359 1.10 kre atf_set "descr" "Test Input+Output (BiDir) redirections"
360 1.10 kre }
361 1.10 kre do_redirect_input_output_body()
362 1.10 kre {
363 1.10 kre nl='
364 1.10 kre '
365 1.10 kre T=0
366 1.10 kre i() { T=$(expr "$T" + 1); }
367 1.10 kre
368 1.10 kre rm -f Output 2>/dev/null || :
369 1.10 kre test -f Output && atf_fail "Unable to remove Output file"
370 1.10 kre #1
371 1.10 kre i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '<> Output'
372 1.10 kre test -f Output || atf_fail "#$T: Did not make Output file"
373 1.10 kre
374 1.10 kre #2
375 1.10 kre echo data >Output 2>/dev/null || :
376 1.10 kre i
377 1.10 kre atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
378 1.10 kre '<>Output'
379 1.10 kre test -f Output || atf_fail "#$T: Removed Output file"
380 1.10 kre test -s Output || atf_fail "#$T: Did not keep data in Output file"
381 1.10 kre test "$(cat Output)" = "data" ||
382 1.10 kre atf_fail "#$T: Incorrect Output: Should be 'data' is '$(cat Output)'"
383 1.10 kre
384 1.10 kre #3
385 1.10 kre rm -f Output 2>/dev/null || :
386 1.10 kre i
387 1.10 kre atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
388 1.10 kre 'echo Hello 1<>Output'
389 1.10 kre test -s Output || atf_fail "#$T: Did not keep non-empty Output file"
390 1.10 kre test "$(cat Output)" = "Hello" ||
391 1.10 kre atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'"
392 1.10 kre
393 1.10 kre #4
394 1.10 kre printf data >Output 2>/dev/null || :
395 1.10 kre i
396 1.10 kre atf_check -s exit:0 -o inline:'data' -e empty ${TEST_SH} -c \
397 1.10 kre 'cat <>Output'
398 1.10 kre test -f Output || atf_fail "#$T: Removed Output file"
399 1.10 kre test -s Output || atf_fail "#$T: Did not keep data in Output file"
400 1.10 kre test "$(cat Output)" = "data" ||
401 1.10 kre atf_fail "#$T: Incorrect Output: Should be 'data' is '$(cat Output)'"
402 1.10 kre
403 1.10 kre #5
404 1.10 kre echo data >Output 2>/dev/null || :
405 1.10 kre i
406 1.10 kre atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
407 1.10 kre 'echo Hello 1<>Output'
408 1.10 kre test -s Output || atf_fail "#$T: Did not make non-empty Output file"
409 1.10 kre test "$(cat Output)" = "Hello" ||
410 1.10 kre atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'"
411 1.10 kre
412 1.10 kre #6
413 1.10 kre printf data >Output 2>/dev/null || :
414 1.10 kre i
415 1.10 kre atf_check -s exit:0 -o inline:data -e empty ${TEST_SH} -c \
416 1.10 kre '{ cat >&3; printf file; } <>Output 3>&1 >&0'
417 1.10 kre test -f Output || atf_fail "#$T: Removed Output file"
418 1.10 kre test -s Output || atf_fail "#$T: Did not keep data in Output file"
419 1.10 kre test "$(cat Output)" = "datafile" ||
420 1.10 kre atf_fail \
421 1.10 kre "#$T: Incorrect Output: Should be 'datafile' is '$(cat Output)'"
422 1.10 kre }
423 1.10 kre
424 1.4 christos atf_test_case fd_redirections
425 1.4 christos fd_redirections_head()
426 1.4 christos {
427 1.4 christos atf_set "descr" "Tests redirections to/from specific descriptors"
428 1.4 christos }
429 1.4 christos fd_redirections_body()
430 1.4 christos {
431 1.6 christos atf_require_prog /bin/echo
432 1.6 christos
433 1.6 christos cat <<- 'DONE' > helper.sh
434 1.6 christos f() {
435 1.6 christos /bin/echo nothing "$1" >& "$1"
436 1.6 christos }
437 1.6 christos for n
438 1.6 christos do
439 1.6 christos eval "f $n $n"'> file-$n'
440 1.6 christos done
441 1.6 christos DONE
442 1.6 christos cat <<- 'DONE' > reread.sh
443 1.6 christos f() {
444 1.6 christos (read -r var; echo "${var}") <&"$1"
445 1.6 christos }
446 1.6 christos for n
447 1.6 christos do
448 1.6 christos x=$( eval "f $n $n"'< file-$n' )
449 1.6 christos test "${x}" = "nothing $n" || echo "$n"
450 1.6 christos done
451 1.6 christos DONE
452 1.6 christos
453 1.6 christos validate()
454 1.6 christos {
455 1.6 christos for n
456 1.6 christos do
457 1.6 christos test -e "file-$n" || atf_fail "file-$n not created"
458 1.6 christos C=$(cat file-"$n")
459 1.6 christos test "$C" = "nothing $n" ||
460 1.6 christos atf_fail "file-$n contains '$C' not 'nothing $n'"
461 1.6 christos done
462 1.6 christos }
463 1.6 christos
464 1.6 christos atf_check -s exit:0 -e empty -o empty \
465 1.6 christos ${TEST_SH} helper.sh 1 2 3 4 5 6 7 8 9
466 1.6 christos validate 1 2 3 4 5 6 7 8 9
467 1.6 christos atf_check -s exit:0 -e empty -o empty \
468 1.6 christos ${TEST_SH} reread.sh 3 4 5 6 7 8 9
469 1.6 christos
470 1.6 christos L=$(ulimit -n)
471 1.6 christos if [ "$L" -ge 30 ]
472 1.6 christos then
473 1.6 christos atf_check -s exit:0 -e empty -o empty \
474 1.6 christos ${TEST_SH} helper.sh 10 15 19 20 25 29
475 1.6 christos validate 10 15 19 20 25 29
476 1.6 christos atf_check -s exit:0 -e empty -o empty \
477 1.6 christos ${TEST_SH} reread.sh 10 15 19 20 25 29
478 1.6 christos fi
479 1.6 christos if [ "$L" -ge 100 ]
480 1.6 christos then
481 1.6 christos atf_check -s exit:0 -e empty -o empty \
482 1.6 christos ${TEST_SH} helper.sh 32 33 49 50 51 63 64 65 77 88 99
483 1.6 christos validate 32 33 49 50 51 63 64 65 77 88 99
484 1.6 christos atf_check -s exit:0 -e empty -o empty \
485 1.6 christos ${TEST_SH} reread.sh 32 33 49 50 51 63 64 65 77 88 99
486 1.6 christos fi
487 1.6 christos if [ "$L" -ge 500 ]
488 1.6 christos then
489 1.6 christos atf_check -s exit:0 -e empty -o empty \
490 1.6 christos ${TEST_SH} helper.sh 100 101 199 200 222 333 444 499
491 1.6 christos validate 100 101 199 200 222 333 444 499
492 1.6 christos atf_check -s exit:0 -e empty -o empty \
493 1.6 christos ${TEST_SH} reread.sh 100 101 199 200 222 333 444 499
494 1.6 christos fi
495 1.6 christos if [ "$L" -gt 1005 ]
496 1.6 christos then
497 1.6 christos atf_check -s exit:0 -e empty -o empty \
498 1.6 christos ${TEST_SH} helper.sh 1000 1001 1002 1003 1004 1005
499 1.6 christos validate 1000 1001 1002 1003 1004 1005
500 1.6 christos atf_check -s exit:0 -e empty -o empty \
501 1.6 christos ${TEST_SH} reread.sh 1000 1001 1002 1003 1004 1005
502 1.6 christos fi
503 1.4 christos }
504 1.4 christos
505 1.4 christos atf_test_case local_redirections
506 1.4 christos local_redirections_head()
507 1.4 christos {
508 1.4 christos atf_set "descr" \
509 1.4 christos "Tests that exec can reassign file descriptors in the shell itself"
510 1.4 christos }
511 1.4 christos local_redirections_body()
512 1.4 christos {
513 1.6 christos cat <<- 'DONE' > helper.sh
514 1.6 christos for f
515 1.6 christos do
516 1.6 christos eval "exec $f"'> file-$f'
517 1.6 christos done
518 1.6 christos
519 1.6 christos for f
520 1.6 christos do
521 1.6 christos printf '%s\n' "Hello $f" >&"$f"
522 1.6 christos done
523 1.6 christos
524 1.6 christos for f
525 1.6 christos do
526 1.6 christos eval "exec $f"'>&-'
527 1.6 christos done
528 1.6 christos
529 1.6 christos for f
530 1.6 christos do
531 1.6 christos eval "exec $f"'< file-$f'
532 1.6 christos done
533 1.6 christos
534 1.6 christos for f
535 1.6 christos do
536 1.6 christos exec <& "$f"
537 1.6 christos read -r var || echo >&2 "No data in file-$f"
538 1.6 christos read -r x && echo >&2 "Too much data in file-${f}: $x"
539 1.6 christos test "${var}" = "Hello $f" ||
540 1.6 christos echo >&2 "file-$f contains '${var}' not 'Hello $f'"
541 1.6 christos done
542 1.6 christos DONE
543 1.6 christos
544 1.6 christos atf_check -s exit:0 -o empty -e empty \
545 1.6 christos ${TEST_SH} helper.sh 3 4 5 6 7 8 9
546 1.6 christos
547 1.6 christos L=$(ulimit -n)
548 1.6 christos if [ "$L" -ge 30 ]
549 1.6 christos then
550 1.6 christos atf_check -s exit:0 -o empty -e empty \
551 1.6 christos ${TEST_SH} helper.sh 10 11 13 15 16 19 20 28 29
552 1.6 christos fi
553 1.6 christos if [ "$L" -ge 100 ]
554 1.6 christos then
555 1.6 christos atf_check -s exit:0 -o empty -e empty \
556 1.6 christos ${TEST_SH} helper.sh 30 31 32 63 64 65 77 88 99
557 1.6 christos fi
558 1.6 christos if [ "$L" -ge 500 ]
559 1.6 christos then
560 1.6 christos atf_check -s exit:0 -o empty -e empty \
561 1.6 christos ${TEST_SH} helper.sh 100 101 111 199 200 201 222 333 499
562 1.6 christos fi
563 1.6 christos if [ "$L" -ge 1005 ]
564 1.6 christos then
565 1.6 christos atf_check -s exit:0 -o empty -e empty \
566 1.6 christos ${TEST_SH} helper.sh 1000 1001 1002 1003 1004 1005
567 1.6 christos fi
568 1.4 christos }
569 1.4 christos
570 1.7 kre atf_test_case named_fd_redirections
571 1.7 kre named_fd_redirections_head()
572 1.7 kre {
573 1.7 kre atf_set "descr" "Tests redirections to /dev/stdout (etc)"
574 1.7 kre
575 1.7 kre }
576 1.7 kre named_fd_redirections_body()
577 1.7 kre {
578 1.7 kre if test -c /dev/stdout
579 1.7 kre then
580 1.7 kre atf_check -s exit:0 -o inline:'OK\n' -e empty \
581 1.7 kre ${TEST_SH} -c 'echo OK >/dev/stdout'
582 1.7 kre atf_check -s exit:0 -o inline:'OK\n' -e empty \
583 1.7 kre ${TEST_SH} -c '/bin/echo OK >/dev/stdout'
584 1.7 kre fi
585 1.7 kre
586 1.7 kre if test -c /dev/stdin
587 1.7 kre then
588 1.7 kre atf_require_prog cat
589 1.7 kre
590 1.7 kre echo GOOD | atf_check -s exit:0 -o inline:'GOOD\n' -e empty \
591 1.12 kre ${TEST_SH} -c 'read var </dev/stdin; echo $var' ||
592 1.12 kre atf_fail "/dev/stdin test 1"
593 1.7 kre echo GOOD | atf_check -s exit:0 -o inline:'GOOD\n' -e empty \
594 1.12 kre ${TEST_SH} -c 'cat </dev/stdin' ||
595 1.12 kre atf_fail "/dev/stdin test 2"
596 1.7 kre fi
597 1.7 kre
598 1.7 kre if test -c /dev/stderr
599 1.7 kre then
600 1.7 kre atf_check -s exit:0 -e inline:'OK\n' -o empty \
601 1.7 kre ${TEST_SH} -c 'echo OK 2>/dev/stderr >&2'
602 1.7 kre atf_check -s exit:0 -e inline:'OK\n' -o empty \
603 1.7 kre ${TEST_SH} -c '/bin/echo OK 2>/dev/stderr >&2'
604 1.7 kre fi
605 1.7 kre
606 1.7 kre if test -c /dev/fd/8 && test -c /dev/fd/9
607 1.7 kre then
608 1.7 kre atf_check -s exit:0 -o inline:'EIGHT\n' -e empty \
609 1.7 kre ${TEST_SH} -c 'printf "%s\n" EIGHT 8>&1 >/dev/fd/8 |
610 1.7 kre cat 9<&0 </dev/fd/9'
611 1.7 kre fi
612 1.7 kre
613 1.7 kre return 0
614 1.7 kre }
615 1.7 kre
616 1.1 christos atf_test_case redir_in_case
617 1.4 christos redir_in_case_head()
618 1.4 christos {
619 1.4 christos atf_set "descr" "Tests that sh(1) allows just redirections " \
620 1.1 christos "in case statements. (PR bin/48631)"
621 1.1 christos }
622 1.4 christos redir_in_case_body()
623 1.4 christos {
624 1.2 christos atf_check -s exit:0 -o empty -e empty \
625 1.2 christos ${TEST_SH} -c 'case x in (whatever) >foo;; esac'
626 1.4 christos
627 1.4 christos atf_check -s exit:0 -o empty -e empty \
628 1.4 christos ${TEST_SH} -c 'case x in (whatever) >foo 2>&1;; esac'
629 1.4 christos
630 1.4 christos atf_check -s exit:0 -o empty -e empty \
631 1.4 christos ${TEST_SH} -c 'case x in (whatever) >foo 2>&1 </dev/null;; esac'
632 1.4 christos
633 1.4 christos atf_check -s exit:0 -o empty -e empty \
634 1.4 christos ${TEST_SH} -c 'case x in (whatever) >${somewhere};; esac'
635 1.2 christos }
636 1.2 christos
637 1.4 christos atf_test_case incorrect_redirections
638 1.4 christos incorrect_redirections_head()
639 1.4 christos {
640 1.4 christos atf_set "descr" "Tests that sh(1) correctly ignores non-redirections"
641 1.4 christos }
642 1.4 christos incorrect_redirections_body() {
643 1.4 christos
644 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'echo foo>'
645 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'read foo<'
646 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'echo foo<>'
647 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
648 1.4 christos 'echo x > '"$nl"
649 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
650 1.4 christos 'read x < '"$nl"
651 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
652 1.4 christos 'echo x <> '"$nl"
653 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
654 1.4 christos 'echo x >< anything'
655 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
656 1.4 christos 'echo x >>< anything'
657 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
658 1.4 christos 'echo x >|< anything'
659 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
660 1.4 christos 'echo x > ; read x < /dev/null || echo bad'
661 1.4 christos atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
662 1.4 christos 'read x < & echo y > /dev/null; wait && echo bad'
663 1.4 christos
664 1.4 christos rm -f Output 2>/dev/null || :
665 1.4 christos atf_check -s exit:0 -e empty -o inline:'A Line > Output\n' \
666 1.4 christos ${TEST_SH} -c 'echo A Line \> Output'
667 1.4 christos test -f Output && atf_file "File 'Output' appeared and should not have"
668 1.4 christos
669 1.4 christos rm -f Output 2>/dev/null || :
670 1.4 christos atf_check -s exit:0 -e empty -o empty \
671 1.4 christos ${TEST_SH} -c 'echo A Line \>> Output'
672 1.4 christos test -f Output || atf_file "File 'Output' not created when it should"
673 1.4 christos test "$(cat Output)" = 'A Line >' || atf_fail \
674 1.4 christos "Output file contains '$(cat Output)' instead of '"'A Line >'\'
675 1.4 christos
676 1.4 christos rm -f Output \> 2>/dev/null || :
677 1.4 christos atf_check -s exit:0 -e empty -o empty \
678 1.4 christos ${TEST_SH} -c 'echo A Line >\> Output'
679 1.4 christos test -f Output && atf_file "File 'Output' appeared and should not have"
680 1.4 christos test -f '>' || atf_file "File '>' not created when it should"
681 1.4 christos test "$(cat '>')" = 'A Line Output' || atf_fail \
682 1.4 christos "Output file ('>') contains '$(cat '>')' instead of 'A Line Output'"
683 1.10 kre
684 1.10 kre rm -fr OutDir
685 1.10 kre atf-check -s not-exit:0 -o empty -e not-empty \
686 1.10 kre ${TEST_SH} -c ': > OutDir/stdout; printf foo'
687 1.10 kre atf-check -s not-exit:0 -o empty -e not-empty \
688 1.10 kre ${TEST_SH} -c ': > OutDir/stdout || printf foo; printf bar'
689 1.10 kre atf-check -s exit:0 -o inline:bar -e not-empty \
690 1.10 kre ${TEST_SH} -c '> OutDir/stdout; printf bar'
691 1.10 kre atf-check -s exit:0 -o inline:foobar -e not-empty \
692 1.10 kre ${TEST_SH} -c '> OutDir/stdout || printf foo; printf bar'
693 1.10 kre atf-check -s exit:0 -o inline:bar -e not-empty \
694 1.10 kre ${TEST_SH} -c 'command : > OutDir/stdout; printf bar'
695 1.10 kre atf-check -s exit:0 -o inline:foobar -e not-empty ${TEST_SH} -c \
696 1.10 kre 'command : > OutDir/stdout || printf foo; printf bar'
697 1.10 kre atf-check -s not-exit:0 -o empty -e not-empty \
698 1.10 kre ${TEST_SH} -c ': <> OutDir/stdout; printf foo'
699 1.10 kre
700 1.10 kre atf-check -s not-exit:0 -o empty -e not-empty \
701 1.10 kre ${TEST_SH} -c ': >&8 ; printf foo'
702 1.10 kre atf-check -s not-exit:0 -o empty -e not-empty \
703 1.10 kre ${TEST_SH} -c ': >&8 || printf foo; printf bar'
704 1.10 kre atf-check -s exit:0 -o inline:bar -e not-empty \
705 1.10 kre ${TEST_SH} -c '>&8 ; printf bar'
706 1.10 kre atf-check -s exit:0 -o inline:foobar -e not-empty \
707 1.10 kre ${TEST_SH} -c '>&8 || printf foo; printf bar'
708 1.10 kre atf-check -s exit:0 -o inline:bar -e not-empty \
709 1.10 kre ${TEST_SH} -c 'command : >&7; printf bar'
710 1.10 kre atf-check -s exit:0 -o inline:foobar -e not-empty ${TEST_SH} -c \
711 1.10 kre 'command : >&7 || printf foo; printf bar'
712 1.10 kre
713 1.10 kre return 0
714 1.4 christos }
715 1.4 christos
716 1.4 christos # Many more tests in t_here, so here we have just rudimentary checks
717 1.2 christos atf_test_case redir_here_doc
718 1.4 christos redir_here_doc_head()
719 1.4 christos {
720 1.2 christos atf_set "descr" "Tests that sh(1) correctly processes 'here' doc " \
721 1.2 christos "input redirections"
722 1.2 christos }
723 1.4 christos redir_here_doc_body()
724 1.4 christos {
725 1.4 christos # nb: the printf is not executed, it is data
726 1.3 christos cat <<- 'DONE' |
727 1.3 christos cat <<EOF
728 1.3 christos printf '%s\n' 'hello\n'
729 1.3 christos EOF
730 1.3 christos DONE
731 1.4 christos atf_check -s exit:0 -o match:printf -o match:'hello\\n' \
732 1.14 kre -e empty ${TEST_SH} ||
733 1.14 kre atf_fail "redir_here_doc failed"
734 1.4 christos }
735 1.4 christos
736 1.4 christos atf_test_case subshell_redirections
737 1.4 christos subshell_redirections_head()
738 1.4 christos {
739 1.4 christos atf_set "descr" "Tests redirection interactions between shell and " \
740 1.4 christos "its sub-shell(s)"
741 1.4 christos }
742 1.4 christos subshell_redirections_body()
743 1.4 christos {
744 1.6 christos atf_require_prog cat
745 1.6 christos
746 1.6 christos LIM=$(ulimit -n)
747 1.6 christos
748 1.6 christos cat <<- 'DONE' |
749 1.6 christos exec 6>output-file
750 1.6 christos
751 1.6 christos ( printf "hello\n" >&6 )
752 1.6 christos
753 1.6 christos exec 8<output-file
754 1.6 christos
755 1.6 christos ( read hello <&8 ; test hello = "$hello" || echo >&2 Hello )
756 1.6 christos
757 1.6 christos ( printf "bye-bye\n" >&6 )
758 1.6 christos
759 1.6 christos ( exec 8<&- )
760 1.6 christos read bye <&8 || echo >&2 "Closed?"
761 1.6 christos echo Bye="$bye"
762 1.6 christos DONE
763 1.6 christos atf_check -s exit:0 -o match:Bye=bye-bye -e empty \
764 1.14 kre ${TEST_SH} ||
765 1.14 kre atf_fail 'bye-bye failure'
766 1.6 christos
767 1.6 christos cat <<- 'DONE' |
768 1.6 christos for arg in one-4 two-24 three-14
769 1.6 christos do
770 1.6 christos fd=${arg#*-}
771 1.6 christos file=${arg%-*}
772 1.6 christos eval "exec ${fd}>${file}"
773 1.6 christos done
774 1.6 christos
775 1.6 christos for arg in one-5 two-7 three-19
776 1.6 christos do
777 1.6 christos fd=${arg#*-}
778 1.6 christos file=${arg%-*}
779 1.6 christos eval "exec ${fd}<${file}"
780 1.6 christos done
781 1.6 christos
782 1.6 christos (
783 1.6 christos echo line-1 >&4
784 1.6 christos echo line-2 >&24
785 1.6 christos echo line-3 >&14
786 1.6 christos echo go
787 1.6 christos ) | (
788 1.6 christos read go
789 1.6 christos read x <&5
790 1.6 christos read y <&7
791 1.6 christos read z <&19
792 1.6 christos
793 1.6 christos printf "%s\n" "${x}" "${y}" "${z}"
794 1.6 christos )
795 1.6 christos DONE
796 1.6 christos atf_check -s exit:0 -o inline:'line-1\nline-2\nline-3\n' \
797 1.14 kre -e empty ${TEST_SH} ||
798 1.14 kre atf_fail 'complex 3 line redirects'
799 1.6 christos
800 1.6 christos cat <<- 'DONE' |
801 1.6 christos for arg in one-4-5 two-6-7 three-8-9 four-11-10 five-3-12
802 1.6 christos do
803 1.6 christos ofd=${arg##*-}
804 1.6 christos file=${arg%-*}
805 1.6 christos ifd=${file#*-}
806 1.6 christos file=${file%-*}
807 1.6 christos eval "exec ${ofd}>${file}"
808 1.6 christos eval "exec ${ifd}<${file}"
809 1.6 christos done
810 1.6 christos
811 1.6 christos ( ( ( echo line-1 >& 13 ) 13>&12 ) 12>&5 ) >stdout 2>errout
812 1.6 christos ( ( ( echo line-2 >& 4) 13>&12 ) 4>&7 ) >>stdout 2>>errout
813 1.6 christos ( ( ( echo line-3 >& 6) 8>&1 6>&11 >&12) 11>&9 >&7 ) >>stdout
814 1.6 christos
815 1.6 christos ( ( ( cat <&13 >&12 ) 13<&8 12>&10 ) 10>&1 8<&6 ) 6<&4
816 1.6 christos ( ( ( cat <&4 ) <&4 6<&8 8<&11 )
817 1.6 christos <&4 4<&6 6<&8 8<&11 ) <&4 4<&6 6<&8 8<&11 11<&3
818 1.6 christos ( ( ( cat <&7 >&1 ) 7<&6 >&10 ) 10>&2 6<&8 ) 2>&1
819 1.6 christos DONE
820 1.6 christos atf_check -s exit:0 -o inline:'line-1\nline-2\nline-3\n' \
821 1.14 kre -e empty ${TEST_SH} ||
822 1.14 kre atf_fail 'absurd 3 line redirects'
823 1.6 christos }
824 1.6 christos
825 1.6 christos atf_test_case ulimit_redirection_interaction
826 1.6 christos ulimit_redirection_interaction_head()
827 1.6 christos {
828 1.6 christos atf_set "descr" "Tests interactions between redirect and ulimit -n "
829 1.6 christos }
830 1.6 christos ulimit_redirection_interaction_body()
831 1.6 christos {
832 1.6 christos atf_require_prog ls
833 1.6 christos
834 1.6 christos cat <<- 'DONE' > helper.sh
835 1.6 christos oLIM=$(ulimit -n)
836 1.6 christos HRD=$(ulimit -H -n)
837 1.6 christos test "${oLIM}" -lt "${HRD}" && ulimit -n "${HRD}"
838 1.6 christos LIM=$(ulimit -n)
839 1.6 christos
840 1.6 christos FDs=
841 1.6 christos LFD=-1
842 1.6 christos while [ ${LIM} -gt 16 ]
843 1.6 christos do
844 1.6 christos FD=$(( ${LIM} - 1 ))
845 1.6 christos if [ "${FD}" -eq "${LFD}" ]; then
846 1.6 christos echo >&2 "Infinite loop... (busted $(( )) ??)"
847 1.6 christos exit 1
848 1.6 christos fi
849 1.6 christos LFD="${FD}"
850 1.6 christos
851 1.6 christos eval "exec ${FD}"'> /dev/null'
852 1.6 christos FDs="${FD}${FDs:+ }${FDs}"
853 1.6 christos
854 1.6 christos (
855 1.6 christos FD=$(( ${LIM} + 1 ))
856 1.6 christos eval "exec ${FD}"'> /dev/null'
857 1.6 christos echo "Reached unreachable command"
858 1.6 christos ) 2>/dev/null && echo >&2 "Opened beyond limit!"
859 1.6 christos
860 1.6 christos (eval 'ls 2>&1 3>&1 4>&1 5>&1 '"${FD}"'>&1') >&"${FD}"
861 1.6 christos
862 1.6 christos LIM=$(( ${LIM} / 2 ))
863 1.6 christos ulimit -S -n "${LIM}"
864 1.6 christos done
865 1.6 christos
866 1.6 christos # Even though ulimit has been reduced, open fds should work
867 1.6 christos for FD in ${FDs}
868 1.6 christos do
869 1.6 christos echo ${FD} in ${FDs} >&"${FD}" || exit 1
870 1.6 christos done
871 1.6 christos
872 1.6 christos ulimit -S -n "${oLIM}"
873 1.6 christos
874 1.6 christos # maybe more later...
875 1.6 christos
876 1.6 christos DONE
877 1.6 christos
878 1.6 christos atf_check -s exit:0 -o empty -e empty ${TEST_SH} helper.sh
879 1.1 christos }
880 1.1 christos
881 1.7 kre atf_test_case validate_fn_redirects
882 1.7 kre validate_fn_redirects_head()
883 1.7 kre {
884 1.7 kre # These test cases inspired by PR bin/48875 and the sh
885 1.7 kre # changes that were required to fix it.
886 1.7 kre
887 1.7 kre atf_set "descr" "Tests various redirections applied to functions " \
888 1.7 kre "See PR bin/48875"
889 1.7 kre }
890 1.7 kre validate_fn_redirects_body()
891 1.7 kre {
892 1.7 kre cat <<- 'DONE' > f-def
893 1.7 kre f() {
894 1.7 kre printf '%s\n' In-Func
895 1.7 kre }
896 1.7 kre DONE
897 1.7 kre
898 1.7 kre atf_check -s exit:0 -o inline:'In-Func\nsuccess1\n' -e empty \
899 1.7 kre ${TEST_SH} -c ". ./f-def; f ; printf '%s\n' success1"
900 1.7 kre atf_check -s exit:0 -o inline:'success2\n' -e empty \
901 1.7 kre ${TEST_SH} -c ". ./f-def; f >/dev/null; printf '%s\n' success2"
902 1.11 kre atf_check -s exit:0 -o inline:'success3\n' -e not-empty \
903 1.7 kre ${TEST_SH} -c ". ./f-def; f >&- ; printf '%s\n' success3"
904 1.7 kre atf_check -s exit:0 -o inline:'In-Func\nsuccess4\n' -e empty \
905 1.7 kre ${TEST_SH} -c ". ./f-def; f & wait; printf '%s\n' success4"
906 1.11 kre atf_check -s exit:0 -o inline:'success5\n' -e not-empty \
907 1.7 kre ${TEST_SH} -c ". ./f-def; f >&- & wait; printf '%s\n' success5"
908 1.7 kre atf_check -s exit:0 -o inline:'In-Func\nIn-Func\nsuccess6\n' -e empty \
909 1.7 kre ${TEST_SH} -c ". ./f-def; f;f; printf '%s\n' success6"
910 1.7 kre atf_check -s exit:0 -o inline:'In-Func\nIn-Func\nsuccess7\n' -e empty \
911 1.7 kre ${TEST_SH} -c ". ./f-def; { f;f;}; printf '%s\n' success7"
912 1.7 kre atf_check -s exit:0 -o inline:'In-Func\nIn-Func\nsuccess8\n' -e empty \
913 1.7 kre ${TEST_SH} -c ". ./f-def; { f;f;}& wait; printf '%s\n' success8"
914 1.7 kre atf_check -s exit:0 -o inline:'In-Func\nsuccess9\n' -e empty \
915 1.7 kre ${TEST_SH} -c \
916 1.7 kre ". ./f-def; { f>/dev/null;f;}& wait; printf '%s\n' success9"
917 1.7 kre atf_check -s exit:0 -o inline:'In-Func\nsuccess10\n' -e empty \
918 1.7 kre ${TEST_SH} -c \
919 1.7 kre ". ./f-def; { f;f>/dev/null;}& wait; printf '%s\n' success10"
920 1.7 kre
921 1.8 kre # This one tests the issue etcupdate had with the original 48875 fix
922 1.8 kre atf_check -s exit:0 -o inline:'Func a\nFunc b\nFunc c\n' -e empty \
923 1.8 kre ${TEST_SH} -c '
924 1.8 kre f() {
925 1.8 kre echo Func "$1"
926 1.8 kre }
927 1.8 kre exec 3<&0 4>&1
928 1.8 kre ( echo x-a; echo y-b; echo z-c ) |
929 1.8 kre while read A
930 1.8 kre do
931 1.8 kre B=${A#?-}
932 1.8 kre f "$B" <&3 >&4
933 1.8 kre done >&2'
934 1.8 kre
935 1.9 kre # And this tests a similar condition with that same fix
936 1.9 kre cat <<- 'DONE' >Script
937 1.9 kre f() {
938 1.9 kre printf '%s' " hello $1"
939 1.9 kre }
940 1.9 kre exec 3>&1
941 1.9 kre echo $( for i in a b c
942 1.9 kre do printf '%s' @$i; f $i >&3; done >foo
943 1.9 kre )
944 1.9 kre printf '%s\n' foo=$(cat foo)
945 1.9 kre DONE
946 1.9 kre atf_check -s exit:0 -e empty \
947 1.9 kre -o inline:' hello a hello b hello c\nfoo=@a@b@c\n' \
948 1.9 kre ${TEST_SH} Script
949 1.9 kre
950 1.7 kre # Tests with sh reading stdin, which is not quite the same internal
951 1.7 kre # mechanism.
952 1.7 kre echo ". ./f-def || echo >&2 FAIL
953 1.7 kre f
954 1.7 kre printf '%s\n' stdin1
955 1.12 kre " | atf_check -s exit:0 -o inline:'In-Func\nstdin1\n' -e empty \
956 1.12 kre ${TEST_SH} ||
957 1.12 kre atf_fail "stdin1 test failure"
958 1.7 kre
959 1.7 kre echo '
960 1.7 kre . ./f-def || echo >&2 FAIL
961 1.13 kre f >&- 2>/dev/null
962 1.8 kre printf "%s\n" stdin2
963 1.12 kre ' | atf_check -s exit:0 -o inline:'stdin2\n' -e empty ${TEST_SH} ||
964 1.12 kre atf_fail "stdin2 test failure"
965 1.7 kre
966 1.7 kre cat <<- 'DONE' > fgh.def
967 1.7 kre f() {
968 1.7 kre echo -n f >&3
969 1.7 kre sleep 4
970 1.7 kre echo -n F >&3
971 1.7 kre }
972 1.7 kre g() {
973 1.7 kre echo -n g >&3
974 1.7 kre sleep 2
975 1.7 kre echo -n G >&3
976 1.7 kre }
977 1.7 kre h() {
978 1.7 kre echo -n h >&3
979 1.7 kre }
980 1.7 kre DONE
981 1.7 kre
982 1.7 kre atf_check -s exit:0 -o inline:'fFgGh' -e empty \
983 1.7 kre ${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL
984 1.7 kre exec 3>&1
985 1.7 kre f; g; h'
986 1.7 kre
987 1.7 kre atf_check -s exit:0 -o inline:'fghGF' -e empty \
988 1.7 kre ${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL
989 1.7 kre exec 3>&1
990 1.7 kre f & sleep 1; g & sleep 1; h; wait'
991 1.7 kre
992 1.7 kre atf_check -s exit:0 -o inline:'fFgGhX Y\n' -e empty \
993 1.7 kre ${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL
994 1.7 kre exec 3>&1
995 1.7 kre echo X $( f ; g ; h ) Y'
996 1.7 kre
997 1.7 kre # This one is the real test for PR bin/48875. If the
998 1.7 kre # cmdsub does not complete before f g (and h) exit,
999 1.7 kre # then the 'F' & 'G' will precede 'X Y' in the output.
1000 1.7 kre # If the cmdsub finishes while f & g are still running,
1001 1.7 kre # then the X Y will appear before the F and G.
1002 1.7 kre # The trailing "sleep 3" is just so we catch all the
1003 1.7 kre # output (otherwise atf_check will be finished while
1004 1.7 kre # f & g are still sleeping).
1005 1.7 kre
1006 1.7 kre atf_check -s exit:0 -o inline:'fghX Y\nGF' -e empty \
1007 1.7 kre ${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL
1008 1.7 kre exec 3>&1
1009 1.7 kre echo X $( f >&- & sleep 1; g >&- & sleep 1 ; h ) Y
1010 1.7 kre sleep 3
1011 1.7 kre exec 4>&1 || echo FD_FAIL
1012 1.7 kre '
1013 1.7 kre
1014 1.7 kre # Do the test again to verify it also all works reading stdin
1015 1.7 kre # (which is a slightly different path through the shell)
1016 1.7 kre echo '
1017 1.7 kre . ./fgh.def || echo >&2 FAIL
1018 1.7 kre exec 3>&1
1019 1.7 kre echo X $( f >&- & sleep 1; g >&- & sleep 1 ; h ) Y
1020 1.7 kre sleep 3
1021 1.7 kre exec 4>&1 || echo FD_FAIL
1022 1.12 kre ' | atf_check -s exit:0 -o inline:'fghX Y\nGF' -e empty ${TEST_SH} ||
1023 1.12 kre atf_fail "48875 stdin variant failure"
1024 1.7 kre }
1025 1.7 kre
1026 1.1 christos atf_init_test_cases() {
1027 1.4 christos atf_add_test_case basic_test_method_test
1028 1.4 christos atf_add_test_case do_input_redirections
1029 1.4 christos atf_add_test_case do_output_redirections
1030 1.10 kre atf_add_test_case do_redirect_input_output
1031 1.4 christos atf_add_test_case fd_redirections
1032 1.4 christos atf_add_test_case local_redirections
1033 1.4 christos atf_add_test_case incorrect_redirections
1034 1.7 kre atf_add_test_case named_fd_redirections
1035 1.4 christos atf_add_test_case redir_here_doc
1036 1.1 christos atf_add_test_case redir_in_case
1037 1.4 christos atf_add_test_case subshell_redirections
1038 1.6 christos atf_add_test_case ulimit_redirection_interaction
1039 1.7 kre atf_add_test_case validate_fn_redirects
1040 1.1 christos }
1041