18462SApril.Chin@Sun.COM######################################################################## 28462SApril.Chin@Sun.COM# # 38462SApril.Chin@Sun.COM# This software is part of the ast package # 4*10898Sroland.mainz@nrubsig.org# Copyright (c) 1982-2009 AT&T Intellectual Property # 58462SApril.Chin@Sun.COM# and is licensed under the # 68462SApril.Chin@Sun.COM# Common Public License, Version 1.0 # 78462SApril.Chin@Sun.COM# by AT&T Intellectual Property # 88462SApril.Chin@Sun.COM# # 98462SApril.Chin@Sun.COM# A copy of the License is available at # 108462SApril.Chin@Sun.COM# http://www.opensource.org/licenses/cpl1.0.txt # 118462SApril.Chin@Sun.COM# (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) # 128462SApril.Chin@Sun.COM# # 138462SApril.Chin@Sun.COM# Information and Software Systems Research # 148462SApril.Chin@Sun.COM# AT&T Research # 158462SApril.Chin@Sun.COM# Florham Park NJ # 168462SApril.Chin@Sun.COM# # 178462SApril.Chin@Sun.COM# David Korn <dgk@research.att.com> # 188462SApril.Chin@Sun.COM# # 198462SApril.Chin@Sun.COM######################################################################## 208462SApril.Chin@Sun.COMfunction err_exit 218462SApril.Chin@Sun.COM{ 228462SApril.Chin@Sun.COM print -u$Error_fd -n "\t" 238462SApril.Chin@Sun.COM print -u$Error_fd -r ${Command}[$1]: "${@:2}" 248462SApril.Chin@Sun.COM (( Errors+=1 )) 258462SApril.Chin@Sun.COM} 268462SApril.Chin@Sun.COMalias err_exit='err_exit $LINENO' 27*10898Sroland.mainz@nrubsig.org 288462SApril.Chin@Sun.COMCommand=${0##*/} 298462SApril.Chin@Sun.COMinteger Errors=0 Error_fd=2 308462SApril.Chin@Sun.COM 31*10898Sroland.mainz@nrubsig.orgtmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 32*10898Sroland.mainz@nrubsig.orgtrap "cd /; rm -rf $tmp" EXIT 33*10898Sroland.mainz@nrubsig.org 34*10898Sroland.mainz@nrubsig.orgbincat=$(PATH=$(getconf PATH) whence -p cat) 35*10898Sroland.mainz@nrubsig.org 368462SApril.Chin@Sun.COMz=() 378462SApril.Chin@Sun.COMz.foo=( [one]=hello [two]=(x=3 y=4) [three]=hi) 388462SApril.Chin@Sun.COMz.bar[0]=hello 398462SApril.Chin@Sun.COMz.bar[2]=world 408462SApril.Chin@Sun.COMz.bar[1]=(x=4 y=5) 418462SApril.Chin@Sun.COMval='( 428462SApril.Chin@Sun.COM typeset -a bar=( 438462SApril.Chin@Sun.COM [0]=hello 448462SApril.Chin@Sun.COM [2]=world 458462SApril.Chin@Sun.COM [1]=( 468462SApril.Chin@Sun.COM x=4 478462SApril.Chin@Sun.COM y=5 488462SApril.Chin@Sun.COM ) 498462SApril.Chin@Sun.COM ) 508462SApril.Chin@Sun.COM typeset -A foo=( 518462SApril.Chin@Sun.COM [one]=hello 528462SApril.Chin@Sun.COM [three]=hi 538462SApril.Chin@Sun.COM [two]=( 548462SApril.Chin@Sun.COM x=3 558462SApril.Chin@Sun.COM y=4 568462SApril.Chin@Sun.COM ) 578462SApril.Chin@Sun.COM ) 588462SApril.Chin@Sun.COM)' 598462SApril.Chin@Sun.COM[[ $z == "$val" ]] || err_exit 'compound variable with mixed arrays not working' 608462SApril.Chin@Sun.COMz.bar[1]=yesyes 618462SApril.Chin@Sun.COM[[ ${z.bar[1]} == yesyes ]] || err_exit 'reassign of index array compound variable fails' 628462SApril.Chin@Sun.COMz.bar[1]=(x=12 y=5) 638462SApril.Chin@Sun.COM[[ ${z.bar[1]} == $'(\n\tx=12\n\ty=5\n)' ]] || err_exit 'reassign array simple to compound variable fails' 648462SApril.Chin@Sun.COMeval val="$z" 658462SApril.Chin@Sun.COM( 668462SApril.Chin@Sun.COM z.foo[three]=good 678462SApril.Chin@Sun.COM [[ ${z.foo[three]} == good ]] || err_exit 'associative array assignment in subshell not working' 688462SApril.Chin@Sun.COM) 698462SApril.Chin@Sun.COM[[ $z == "$val" ]] || err_exit 'compound variable changes after associative array assignment' 708462SApril.Chin@Sun.COMeval val="$z" 718462SApril.Chin@Sun.COM( 728462SApril.Chin@Sun.COMfalse 738462SApril.Chin@Sun.COM z.foo[two]=ok 748462SApril.Chin@Sun.COM [[ ${z.foo[two]} == ok ]] || err_exit 'associative array assignment to compound variable in subshell not working' 758462SApril.Chin@Sun.COM z.bar[1]=yes 768462SApril.Chin@Sun.COM [[ ${z.bar[1]} == yes ]] || err_exit 'index array assignment to compound variable in subshell not working' 778462SApril.Chin@Sun.COM) 788462SApril.Chin@Sun.COM[[ $z == "$val" ]] || err_exit 'compound variable changes after associative array assignment' 79*10898Sroland.mainz@nrubsig.org 808462SApril.Chin@Sun.COMx=( 818462SApril.Chin@Sun.COM foo=( qqq=abc rrr=def) 828462SApril.Chin@Sun.COM bar=( zzz=no rst=fed) 838462SApril.Chin@Sun.COM) 848462SApril.Chin@Sun.COMeval val="$x" 858462SApril.Chin@Sun.COM( 868462SApril.Chin@Sun.COM unset x.foo 878462SApril.Chin@Sun.COM [[ ${x.foo.qqq} ]] && err_exit 'x.foo.qqq should be unset' 888462SApril.Chin@Sun.COM x.foo=good 898462SApril.Chin@Sun.COM [[ ${x.foo} == good ]] || err_exit 'x.foo should be good' 908462SApril.Chin@Sun.COM) 918462SApril.Chin@Sun.COM[[ $x == "$val" ]] || err_exit 'compound variable changes after unset leaves' 928462SApril.Chin@Sun.COMunset l 938462SApril.Chin@Sun.COM( 948462SApril.Chin@Sun.COM l=( a=1 b="BE" ) 958462SApril.Chin@Sun.COM) 968462SApril.Chin@Sun.COM[[ ${l+foo} != foo ]] || err_exit 'l should be unset' 978462SApril.Chin@Sun.COM 988462SApril.Chin@Sun.COMError_fd=9 998462SApril.Chin@Sun.COMeval "exec $Error_fd>&2 2>/dev/null" 1008462SApril.Chin@Sun.COM 1018462SApril.Chin@Sun.COMTEST_notfound=notfound 1028462SApril.Chin@Sun.COMwhile whence $TEST_notfound >/dev/null 2>&1 1038462SApril.Chin@Sun.COMdo TEST_notfound=notfound-$RANDOM 1048462SApril.Chin@Sun.COMdone 1058462SApril.Chin@Sun.COM 1068462SApril.Chin@Sun.COMinteger BS=1024 nb=64 ss=60 bs no 1078462SApril.Chin@Sun.COMfor bs in $BS 1 1088462SApril.Chin@Sun.COMdo $SHELL -c ' 1098462SApril.Chin@Sun.COM { 1108462SApril.Chin@Sun.COM sleep '$ss' 1118462SApril.Chin@Sun.COM kill -KILL $$ 1128462SApril.Chin@Sun.COM } & 1138462SApril.Chin@Sun.COM set -- $(printf %.'$(($BS*$nb))'c x | dd bs='$bs') 1148462SApril.Chin@Sun.COM print ${#1} 1158462SApril.Chin@Sun.COM kill $! 116*10898Sroland.mainz@nrubsig.org ' > $tmp/sub 2>/dev/null 117*10898Sroland.mainz@nrubsig.org no=$(<$tmp/sub) 1188462SApril.Chin@Sun.COM (( no == (BS * nb) )) || err_exit "shell hangs on command substitution output size >= $BS*$nb with write size $bs -- expected $((BS*nb)), got ${no:-0}" 1198462SApril.Chin@Sun.COMdone 1208462SApril.Chin@Sun.COM# this time with redirection on the trailing command 1218462SApril.Chin@Sun.COMfor bs in $BS 1 1228462SApril.Chin@Sun.COMdo $SHELL -c ' 1238462SApril.Chin@Sun.COM { 1248462SApril.Chin@Sun.COM sleep 2 1258462SApril.Chin@Sun.COM sleep '$ss' 1268462SApril.Chin@Sun.COM kill -KILL $$ 1278462SApril.Chin@Sun.COM } & 1288462SApril.Chin@Sun.COM set -- $(printf %.'$(($BS*$nb))'c x | dd bs='$bs' 2>/dev/null) 1298462SApril.Chin@Sun.COM print ${#1} 1308462SApril.Chin@Sun.COM kill $! 131*10898Sroland.mainz@nrubsig.org ' > $tmp/sub 2>/dev/null 132*10898Sroland.mainz@nrubsig.org no=$(<$tmp/sub) 1338462SApril.Chin@Sun.COM (( no == (BS * nb) )) || err_exit "shell hangs on command substitution output size >= $BS*$nb with write size $bs and trailing redirection -- expected $((BS*nb)), got ${no:-0}" 1348462SApril.Chin@Sun.COMdone 1358462SApril.Chin@Sun.COM 1368462SApril.Chin@Sun.COM# exercise command substitutuion trailing newline logic w.r.t. pipe vs. tmp file io 1378462SApril.Chin@Sun.COM 1388462SApril.Chin@Sun.COMset -- \ 1398462SApril.Chin@Sun.COM 'post-line print' \ 1408462SApril.Chin@Sun.COM '$TEST_unset; ($TEST_fork; print 1); print' \ 1418462SApril.Chin@Sun.COM 1 \ 1428462SApril.Chin@Sun.COM 'pre-line print' \ 1438462SApril.Chin@Sun.COM '$TEST_unset; ($TEST_fork; print); print 1' \ 1448462SApril.Chin@Sun.COM $'\n1' \ 1458462SApril.Chin@Sun.COM 'multiple pre-line print' \ 1468462SApril.Chin@Sun.COM '$TEST_unset; ($TEST_fork; print); print; ($TEST_fork; print 1); print' \ 1478462SApril.Chin@Sun.COM $'\n\n1' \ 1488462SApril.Chin@Sun.COM 'multiple post-line print' \ 1498462SApril.Chin@Sun.COM '$TEST_unset; ($TEST_fork; print 1); print; ($TEST_fork; print); print' \ 1508462SApril.Chin@Sun.COM 1 \ 1518462SApril.Chin@Sun.COM 'intermediate print' \ 1528462SApril.Chin@Sun.COM '$TEST_unset; ($TEST_fork; print 1); print; ($TEST_fork; print 2); print' \ 1538462SApril.Chin@Sun.COM $'1\n\n2' \ 1548462SApril.Chin@Sun.COM 'simple variable' \ 1558462SApril.Chin@Sun.COM '$TEST_unset; ($TEST_fork; l=2; print "$l"); print $l' \ 1568462SApril.Chin@Sun.COM 2 \ 1578462SApril.Chin@Sun.COM 'compound variable' \ 1588462SApril.Chin@Sun.COM '$TEST_unset; ($TEST_fork; l=(a=2 b="BE"); print "$l"); print $l' \ 1598462SApril.Chin@Sun.COM $'(\n\ta=2\n\tb=BE\n)' \ 1608462SApril.Chin@Sun.COM 1618462SApril.Chin@Sun.COMexport TEST_fork TEST_unset 1628462SApril.Chin@Sun.COM 1638462SApril.Chin@Sun.COMwhile (( $# >= 3 )) 1648462SApril.Chin@Sun.COMdo txt=$1 1658462SApril.Chin@Sun.COM cmd=$2 1668462SApril.Chin@Sun.COM exp=$3 1678462SApril.Chin@Sun.COM shift 3 1688462SApril.Chin@Sun.COM for TEST_unset in '' 'unset var' 1698462SApril.Chin@Sun.COM do for TEST_fork in '' 'ulimit -c 0' 1708462SApril.Chin@Sun.COM do for TEST_shell in "eval" "$SHELL -c" 1718462SApril.Chin@Sun.COM do if ! got=$($TEST_shell "$cmd") 1728462SApril.Chin@Sun.COM then err_exit "${TEST_shell/*-c/\$SHELL -c} ${TEST_unset:+unset }${TEST_fork:+fork }$txt print failed" 1738462SApril.Chin@Sun.COM elif [[ "$got" != "$exp" ]] 1748462SApril.Chin@Sun.COM then EXP=$(printf %q "$exp") 1758462SApril.Chin@Sun.COM GOT=$(printf %q "$got") 1768462SApril.Chin@Sun.COM err_exit "${TEST_shell/*-c/\$SHELL -c} ${TEST_unset:+unset }${TEST_fork:+fork }$txt command substitution failed -- expected $EXP, got $GOT" 1778462SApril.Chin@Sun.COM fi 1788462SApril.Chin@Sun.COM done 1798462SApril.Chin@Sun.COM done 1808462SApril.Chin@Sun.COM done 1818462SApril.Chin@Sun.COMdone 1828462SApril.Chin@Sun.COM 1838462SApril.Chin@Sun.COMr=$( ($SHELL -c ' 1848462SApril.Chin@Sun.COM { 1858462SApril.Chin@Sun.COM sleep 32 1868462SApril.Chin@Sun.COM kill -KILL $$ 1878462SApril.Chin@Sun.COM } & 1888462SApril.Chin@Sun.COM for v in $(set | sed "s/=.*//") 1898462SApril.Chin@Sun.COM do command unset $v 1908462SApril.Chin@Sun.COM done 1918462SApril.Chin@Sun.COM typeset -Z5 I 1928462SApril.Chin@Sun.COM for ((I = 0; I < 1024; I++)) 1938462SApril.Chin@Sun.COM do eval A$I=1234567890 1948462SApril.Chin@Sun.COM done 1958462SApril.Chin@Sun.COM a=$(set 2>&1) 1968462SApril.Chin@Sun.COM print ok 1978462SApril.Chin@Sun.COM kill -KILL $! 1988462SApril.Chin@Sun.COM') 2>/dev/null) 1998462SApril.Chin@Sun.COM[[ $r == ok ]] || err_exit "large subshell command substitution hangs" 2008462SApril.Chin@Sun.COM 2018462SApril.Chin@Sun.COMfor TEST_command in '' $TEST_notfound 2028462SApril.Chin@Sun.COMdo for TEST_exec in '' 'exec' 2038462SApril.Chin@Sun.COM do for TEST_fork in '' 'ulimit -c 0;' 2048462SApril.Chin@Sun.COM do for TEST_redirect in '' '>/dev/null' 2058462SApril.Chin@Sun.COM do for TEST_substitute in '' ': $' 2068462SApril.Chin@Sun.COM do 2078462SApril.Chin@Sun.COM 2088462SApril.Chin@Sun.COM TEST_test="$TEST_substitute($TEST_fork $TEST_exec $TEST_command $TEST_redirect)" 2098462SApril.Chin@Sun.COM [[ $TEST_test == '('*([[:space:]])')' ]] && continue 2108462SApril.Chin@Sun.COM r=$($SHELL -c ' 2118462SApril.Chin@Sun.COM { 2128462SApril.Chin@Sun.COM sleep 2 2138462SApril.Chin@Sun.COM kill -KILL $$ 2148462SApril.Chin@Sun.COM } & 2158462SApril.Chin@Sun.COM '"$TEST_test"' 2168462SApril.Chin@Sun.COM kill $! 2178462SApril.Chin@Sun.COM print ok 2188462SApril.Chin@Sun.COM ') 2198462SApril.Chin@Sun.COM [[ $r == ok ]] || err_exit "shell hangs on $TEST_test" 2208462SApril.Chin@Sun.COM 2218462SApril.Chin@Sun.COM done 2228462SApril.Chin@Sun.COM done 2238462SApril.Chin@Sun.COM done 2248462SApril.Chin@Sun.COM done 2258462SApril.Chin@Sun.COMdone 2268462SApril.Chin@Sun.COM 227*10898Sroland.mainz@nrubsig.org$SHELL -c '( autoload xxxxx);print -n' || err_exit 'autoloaded functions in subshells can cause failure' 228*10898Sroland.mainz@nrubsig.orgfoo=$($SHELL <<- ++EOF++ 229*10898Sroland.mainz@nrubsig.org (trap 'print bar' EXIT;print -n foo) 230*10898Sroland.mainz@nrubsig.org ++EOF++ 231*10898Sroland.mainz@nrubsig.org) 232*10898Sroland.mainz@nrubsig.org[[ $foo == foobar ]] || err_exit 'trap on exit when last commands is subshell is not triggered' 233*10898Sroland.mainz@nrubsig.org 234*10898Sroland.mainz@nrubsig.orgerr=$( 235*10898Sroland.mainz@nrubsig.org $SHELL 2>&1 <<- \EOF 236*10898Sroland.mainz@nrubsig.org date=$(whence -p date) 237*10898Sroland.mainz@nrubsig.org function foo 238*10898Sroland.mainz@nrubsig.org { 239*10898Sroland.mainz@nrubsig.org x=$( $date > /dev/null 2>&1 ;:) 240*10898Sroland.mainz@nrubsig.org } 241*10898Sroland.mainz@nrubsig.org # consume almost all fds to push the test to the fd limit # 242*10898Sroland.mainz@nrubsig.org integer max=$(ulimit --nofile) 243*10898Sroland.mainz@nrubsig.org (( max -= 6 )) 244*10898Sroland.mainz@nrubsig.org for ((i=20; i < max; i++)) 245*10898Sroland.mainz@nrubsig.org do exec {i}>&1 246*10898Sroland.mainz@nrubsig.org done 247*10898Sroland.mainz@nrubsig.org for ((i=0; i < 20; i++)) 248*10898Sroland.mainz@nrubsig.org do y=$(foo) 249*10898Sroland.mainz@nrubsig.org done 250*10898Sroland.mainz@nrubsig.org EOF 251*10898Sroland.mainz@nrubsig.org) || { 252*10898Sroland.mainz@nrubsig.org err=${err%%$'\n'*} 253*10898Sroland.mainz@nrubsig.org err=${err#*:} 254*10898Sroland.mainz@nrubsig.org err=${err##[[:space:]]} 255*10898Sroland.mainz@nrubsig.org err_exit "nested command substitution with redirections failed -- $err" 256*10898Sroland.mainz@nrubsig.org} 257*10898Sroland.mainz@nrubsig.org 258*10898Sroland.mainz@nrubsig.orgexp=0 259*10898Sroland.mainz@nrubsig.org$SHELL -c $' 260*10898Sroland.mainz@nrubsig.org function foobar 261*10898Sroland.mainz@nrubsig.org { 262*10898Sroland.mainz@nrubsig.org print "hello world" 263*10898Sroland.mainz@nrubsig.org } 264*10898Sroland.mainz@nrubsig.org [[ $(getopts \'[+?X\ffoobar\fX]\' v --man 2>&1) == *"Xhello worldX"* ]] 265*10898Sroland.mainz@nrubsig.org exit '$exp$' 266*10898Sroland.mainz@nrubsig.org' 267*10898Sroland.mainz@nrubsig.orggot=$? 268*10898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "getopts --man runtime callout with nonzero exit terminates shell -- expected '$exp', got '$got'" 269*10898Sroland.mainz@nrubsig.orgexp=ok 270*10898Sroland.mainz@nrubsig.orggot=$($SHELL -c $' 271*10898Sroland.mainz@nrubsig.org function foobar 272*10898Sroland.mainz@nrubsig.org { 273*10898Sroland.mainz@nrubsig.org print "hello world" 274*10898Sroland.mainz@nrubsig.org } 275*10898Sroland.mainz@nrubsig.org [[ $(getopts \'[+?X\ffoobar\fX]\' v --man 2>&1) == *"Xhello worldX"* ]] 276*10898Sroland.mainz@nrubsig.org print '$exp$' 277*10898Sroland.mainz@nrubsig.org') 278*10898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "getopts --man runtime callout with nonzero exit terminates shell -- expected '$exp', got '$got'" 279*10898Sroland.mainz@nrubsig.org 280*10898Sroland.mainz@nrubsig.org# command substitution variations # 281*10898Sroland.mainz@nrubsig.orgset -- \ 282*10898Sroland.mainz@nrubsig.org '$(' ')' \ 283*10898Sroland.mainz@nrubsig.org '${ ' '; }' \ 284*10898Sroland.mainz@nrubsig.org '$(ulimit -c 0; ' ')' \ 285*10898Sroland.mainz@nrubsig.org '$( (' ') )' \ 286*10898Sroland.mainz@nrubsig.org '${ (' '); }' \ 287*10898Sroland.mainz@nrubsig.org '`' '`' \ 288*10898Sroland.mainz@nrubsig.org '`(' ')`' \ 289*10898Sroland.mainz@nrubsig.org '`ulimit -c 0; ' '`' \ 290*10898Sroland.mainz@nrubsig.org # end of table # 291*10898Sroland.mainz@nrubsig.orgexp=ok 292*10898Sroland.mainz@nrubsig.orgtestcase[1]=' 293*10898Sroland.mainz@nrubsig.org if %sexpr "NOMATCH" : ".*Z" >/dev/null%s 294*10898Sroland.mainz@nrubsig.org then print error 295*10898Sroland.mainz@nrubsig.org else print ok 296*10898Sroland.mainz@nrubsig.org fi 297*10898Sroland.mainz@nrubsig.org exit %s 298*10898Sroland.mainz@nrubsig.org' 299*10898Sroland.mainz@nrubsig.orgtestcase[2]=' 300*10898Sroland.mainz@nrubsig.org function bar 301*10898Sroland.mainz@nrubsig.org { 302*10898Sroland.mainz@nrubsig.org pipeout=%1$sprintf Ok | tr O o%2$s 303*10898Sroland.mainz@nrubsig.org print $pipeout 304*10898Sroland.mainz@nrubsig.org return 0 305*10898Sroland.mainz@nrubsig.org } 306*10898Sroland.mainz@nrubsig.org foo=%1$sbar%2$s || foo="exit status $?" 307*10898Sroland.mainz@nrubsig.org print $foo 308*10898Sroland.mainz@nrubsig.org exit %3$s 309*10898Sroland.mainz@nrubsig.org' 310*10898Sroland.mainz@nrubsig.orgwhile (( $# >= 2 )) 311*10898Sroland.mainz@nrubsig.orgdo for ((TEST=1; TEST<=${#testcase[@]}; TEST++)) 312*10898Sroland.mainz@nrubsig.org do body=${testcase[TEST]} 313*10898Sroland.mainz@nrubsig.org for code in 0 2 314*10898Sroland.mainz@nrubsig.org do got=${ printf "$body" "$1" "$2" "$code" | $SHELL 2>&1 } 315*10898Sroland.mainz@nrubsig.org status=$? 316*10898Sroland.mainz@nrubsig.org if (( status != code )) 317*10898Sroland.mainz@nrubsig.org then err_exit "test $TEST '$1...$2 exit $code' failed -- exit status $status, expected $code" 318*10898Sroland.mainz@nrubsig.org elif [[ $got != $exp ]] 319*10898Sroland.mainz@nrubsig.org then err_exit "test $TEST '$1...$2 exit $code' failed -- got '$got', expected '$exp'" 320*10898Sroland.mainz@nrubsig.org fi 321*10898Sroland.mainz@nrubsig.org done 322*10898Sroland.mainz@nrubsig.org done 323*10898Sroland.mainz@nrubsig.org shift 2 324*10898Sroland.mainz@nrubsig.orgdone 325*10898Sroland.mainz@nrubsig.org 326*10898Sroland.mainz@nrubsig.org# the next tests loop on all combinations of 327*10898Sroland.mainz@nrubsig.org# { SUB CAT INS TST APP } X { file-sizes } 328*10898Sroland.mainz@nrubsig.org# where the file size starts at 1Ki and doubles up to and including 1Mi 329*10898Sroland.mainz@nrubsig.org# 330*10898Sroland.mainz@nrubsig.org# the tests and timeouts are done in async subshells to prevent 331*10898Sroland.mainz@nrubsig.org# the test harness from hanging 332*10898Sroland.mainz@nrubsig.org 333*10898Sroland.mainz@nrubsig.orgSUB=( 334*10898Sroland.mainz@nrubsig.org ( BEG='$( ' END=' )' ) 335*10898Sroland.mainz@nrubsig.org ( BEG='${ ' END='; }' ) 336*10898Sroland.mainz@nrubsig.org) 337*10898Sroland.mainz@nrubsig.orgCAT=( cat $bincat ) 338*10898Sroland.mainz@nrubsig.orgINS=( "" "builtin cat; " "builtin -d cat $bincat; " ": > /dev/null; " ) 339*10898Sroland.mainz@nrubsig.orgAPP=( "" "; :" ) 340*10898Sroland.mainz@nrubsig.orgTST=( 341*10898Sroland.mainz@nrubsig.org ( CMD='print foo | $cat' EXP=3 ) 342*10898Sroland.mainz@nrubsig.org ( CMD='$cat < $tmp/lin' ) 343*10898Sroland.mainz@nrubsig.org ( CMD='cat $tmp/lin | $cat' ) 344*10898Sroland.mainz@nrubsig.org ( CMD='read v < $tmp/buf; print $v' LIM=4*1024 ) 345*10898Sroland.mainz@nrubsig.org ( CMD='cat $tmp/buf | read v; print $v' LIM=4*1024 ) 346*10898Sroland.mainz@nrubsig.org) 347*10898Sroland.mainz@nrubsig.org 348*10898Sroland.mainz@nrubsig.orgcommand exec 3<> /dev/null 349*10898Sroland.mainz@nrubsig.orgif cat /dev/fd/3 >/dev/null 2>&1 350*10898Sroland.mainz@nrubsig.orgthen T=${#TST[@]} 351*10898Sroland.mainz@nrubsig.org TST[T].CMD='$cat <(print foo)' 352*10898Sroland.mainz@nrubsig.org TST[T].EXP=3 353*10898Sroland.mainz@nrubsig.orgfi 354*10898Sroland.mainz@nrubsig.org 355*10898Sroland.mainz@nrubsig.org# prime the two data files to 512 bytes each 356*10898Sroland.mainz@nrubsig.org# $tmp/lin has newlines every 16 bytes and $tmp/buf has no newlines 357*10898Sroland.mainz@nrubsig.org# the outer loop doubles the file size at top 358*10898Sroland.mainz@nrubsig.org 359*10898Sroland.mainz@nrubsig.orgbuf=$'1234567890abcdef' 360*10898Sroland.mainz@nrubsig.orglin=$'\n1234567890abcde' 361*10898Sroland.mainz@nrubsig.orgfor ((i=0; i<5; i++)) 362*10898Sroland.mainz@nrubsig.orgdo buf=$buf$buf 363*10898Sroland.mainz@nrubsig.org lin=$lin$lin 364*10898Sroland.mainz@nrubsig.orgdone 365*10898Sroland.mainz@nrubsig.orgprint -n "$buf" > $tmp/buf 366*10898Sroland.mainz@nrubsig.orgprint -n "$lin" > $tmp/lin 367*10898Sroland.mainz@nrubsig.org 368*10898Sroland.mainz@nrubsig.orgunset SKIP 369*10898Sroland.mainz@nrubsig.orgfor ((n=1024; n<=1024*1024; n*=2)) 370*10898Sroland.mainz@nrubsig.orgdo cat $tmp/buf $tmp/buf > $tmp/tmp 371*10898Sroland.mainz@nrubsig.org mv $tmp/tmp $tmp/buf 372*10898Sroland.mainz@nrubsig.org cat $tmp/lin $tmp/lin > $tmp/tmp 373*10898Sroland.mainz@nrubsig.org mv $tmp/tmp $tmp/lin 374*10898Sroland.mainz@nrubsig.org for ((S=0; S<${#SUB[@]}; S++)) 375*10898Sroland.mainz@nrubsig.org do for ((C=0; C<${#CAT[@]}; C++)) 376*10898Sroland.mainz@nrubsig.org do cat=${CAT[C]} 377*10898Sroland.mainz@nrubsig.org for ((I=0; I<${#INS[@]}; I++)) 378*10898Sroland.mainz@nrubsig.org do for ((A=0; A<${#APP[@]}; A++)) 379*10898Sroland.mainz@nrubsig.org do for ((T=0; T<${#TST[@]}; T++)) 380*10898Sroland.mainz@nrubsig.org do #undent...# 381*10898Sroland.mainz@nrubsig.org 382*10898Sroland.mainz@nrubsig.org if [[ ! ${SKIP[S][C][I][A][T]} ]] 383*10898Sroland.mainz@nrubsig.org then eval "{ x=${SUB[S].BEG}${INS[I]}${TST[T].CMD}${APP[A]}${SUB[S].END}; print \${#x}; } >\$tmp/out &" 384*10898Sroland.mainz@nrubsig.org m=$! 385*10898Sroland.mainz@nrubsig.org { sleep 4; kill -9 $m; } & 386*10898Sroland.mainz@nrubsig.org k=$! 387*10898Sroland.mainz@nrubsig.org wait $m 388*10898Sroland.mainz@nrubsig.org h=$? 389*10898Sroland.mainz@nrubsig.org kill -9 $k 390*10898Sroland.mainz@nrubsig.org wait $k 391*10898Sroland.mainz@nrubsig.org got=$(<$tmp/out) 392*10898Sroland.mainz@nrubsig.org if [[ ! $got ]] && (( h )) 393*10898Sroland.mainz@nrubsig.org then got=HUNG 394*10898Sroland.mainz@nrubsig.org fi 395*10898Sroland.mainz@nrubsig.org if [[ ${TST[T].EXP} ]] 396*10898Sroland.mainz@nrubsig.org then exp=${TST[T].EXP} 397*10898Sroland.mainz@nrubsig.org else exp=$n 398*10898Sroland.mainz@nrubsig.org fi 399*10898Sroland.mainz@nrubsig.org if [[ $got != $exp ]] 400*10898Sroland.mainz@nrubsig.org then # on failure skip similar tests on larger files sizes # 401*10898Sroland.mainz@nrubsig.org SKIP[S][C][I][A][T]=1 402*10898Sroland.mainz@nrubsig.org siz=$(printf $'%#i' $exp) 403*10898Sroland.mainz@nrubsig.org cmd=${TST[T].CMD//\$cat/$cat} 404*10898Sroland.mainz@nrubsig.org cmd=${cmd//\$tmp\/buf/$siz.buf} 405*10898Sroland.mainz@nrubsig.org cmd=${cmd//\$tmp\/lin/$siz.lin} 406*10898Sroland.mainz@nrubsig.org err_exit "'x=${SUB[S].BEG}${INS[I]}${cmd}${APP[A]}${SUB[S].END} && print \${#x}' failed -- expected '$exp', got '$got'" 407*10898Sroland.mainz@nrubsig.org elif [[ ${TST[T].EXP} ]] || (( TST[T].LIM >= n )) 408*10898Sroland.mainz@nrubsig.org then SKIP[S][C][I][A][T]=1 409*10898Sroland.mainz@nrubsig.org fi 410*10898Sroland.mainz@nrubsig.org fi 411*10898Sroland.mainz@nrubsig.org 412*10898Sroland.mainz@nrubsig.org #...indent# 413*10898Sroland.mainz@nrubsig.org done 414*10898Sroland.mainz@nrubsig.org done 415*10898Sroland.mainz@nrubsig.org done 416*10898Sroland.mainz@nrubsig.org done 417*10898Sroland.mainz@nrubsig.org done 418*10898Sroland.mainz@nrubsig.orgdone 419*10898Sroland.mainz@nrubsig.org 420*10898Sroland.mainz@nrubsig.org# specifics -- there's more? 421*10898Sroland.mainz@nrubsig.org 422*10898Sroland.mainz@nrubsig.org{ 423*10898Sroland.mainz@nrubsig.org cmd='{ exec 5>/dev/null; print "$(eval ls -d . 2>&1 1>&5)"; } >$tmp/out &' 424*10898Sroland.mainz@nrubsig.org eval $cmd 425*10898Sroland.mainz@nrubsig.org m=$! 426*10898Sroland.mainz@nrubsig.org { sleep 4; kill -9 $m; } & 427*10898Sroland.mainz@nrubsig.org k=$! 428*10898Sroland.mainz@nrubsig.org wait $m 429*10898Sroland.mainz@nrubsig.org h=$? 430*10898Sroland.mainz@nrubsig.org kill -9 $k 431*10898Sroland.mainz@nrubsig.org wait $k 432*10898Sroland.mainz@nrubsig.org got=$(<$tmp/out) 433*10898Sroland.mainz@nrubsig.org} 2>/dev/null 434*10898Sroland.mainz@nrubsig.orgexp='' 435*10898Sroland.mainz@nrubsig.orgif [[ ! $got ]] && (( h )) 436*10898Sroland.mainz@nrubsig.orgthen got=HUNG 437*10898Sroland.mainz@nrubsig.orgfi 438*10898Sroland.mainz@nrubsig.orgif [[ $got != $exp ]] 439*10898Sroland.mainz@nrubsig.orgthen err_exit "eval '$cmd' failed -- expected '$exp', got '$got'" 440*10898Sroland.mainz@nrubsig.orgfi 441*10898Sroland.mainz@nrubsig.org 442*10898Sroland.mainz@nrubsig.orgfloat t1=$SECONDS 443*10898Sroland.mainz@nrubsig.orgsleep=$(whence -p sleep) 444*10898Sroland.mainz@nrubsig.orgif [[ $sleep ]] 445*10898Sroland.mainz@nrubsig.orgthen 446*10898Sroland.mainz@nrubsig.org $SHELL -c "( $sleep 5 </dev/null >/dev/null 2>&1 & );exit 0" | cat 447*10898Sroland.mainz@nrubsig.org (( (SECONDS-t1) > 4 )) && err_exit '/bin/sleep& in subshell hanging' 448*10898Sroland.mainz@nrubsig.org ((t1=SECONDS)) 449*10898Sroland.mainz@nrubsig.orgfi 450*10898Sroland.mainz@nrubsig.org$SHELL -c '( sleep 5 </dev/null >/dev/null 2>&1 & );exit 0' | cat 451*10898Sroland.mainz@nrubsig.org(( (SECONDS-t1) > 4 )) && err_exit 'sleep& in subshell hanging' 452*10898Sroland.mainz@nrubsig.org 4538462SApril.Chin@Sun.COMexit $Errors 454