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