Home | History | Annotate | Line # | Download | only in sh
      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