17c2fbfb3SApril Chin######################################################################## 27c2fbfb3SApril Chin# # 37c2fbfb3SApril Chin# This software is part of the ast package # 4*3e14f97fSRoger A. Faulkner# Copyright (c) 1982-2010 AT&T Intellectual Property # 57c2fbfb3SApril Chin# and is licensed under the # 67c2fbfb3SApril Chin# Common Public License, Version 1.0 # 77c2fbfb3SApril Chin# by AT&T Intellectual Property # 87c2fbfb3SApril Chin# # 97c2fbfb3SApril Chin# A copy of the License is available at # 107c2fbfb3SApril Chin# http://www.opensource.org/licenses/cpl1.0.txt # 117c2fbfb3SApril Chin# (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) # 127c2fbfb3SApril Chin# # 137c2fbfb3SApril Chin# Information and Software Systems Research # 147c2fbfb3SApril Chin# AT&T Research # 157c2fbfb3SApril Chin# Florham Park NJ # 167c2fbfb3SApril Chin# # 177c2fbfb3SApril Chin# David Korn <dgk@research.att.com> # 187c2fbfb3SApril Chin# # 197c2fbfb3SApril Chin######################################################################## 207c2fbfb3SApril Chinfunction err_exit 217c2fbfb3SApril Chin{ 227c2fbfb3SApril Chin print -u$Error_fd -n "\t" 237c2fbfb3SApril Chin print -u$Error_fd -r ${Command}[$1]: "${@:2}" 247c2fbfb3SApril Chin (( Errors+=1 )) 257c2fbfb3SApril Chin} 267c2fbfb3SApril Chinalias err_exit='err_exit $LINENO' 2734f9b3eeSRoland Mainz 287c2fbfb3SApril ChinCommand=${0##*/} 297c2fbfb3SApril Chininteger Errors=0 Error_fd=2 307c2fbfb3SApril Chin 3134f9b3eeSRoland Mainztmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 3234f9b3eeSRoland Mainztrap "cd /; rm -rf $tmp" EXIT 3334f9b3eeSRoland Mainz 3434f9b3eeSRoland Mainzbincat=$(PATH=$(getconf PATH) whence -p cat) 3534f9b3eeSRoland Mainz 367c2fbfb3SApril Chinz=() 377c2fbfb3SApril Chinz.foo=( [one]=hello [two]=(x=3 y=4) [three]=hi) 387c2fbfb3SApril Chinz.bar[0]=hello 397c2fbfb3SApril Chinz.bar[2]=world 407c2fbfb3SApril Chinz.bar[1]=(x=4 y=5) 417c2fbfb3SApril Chinval='( 427c2fbfb3SApril Chin typeset -a bar=( 437c2fbfb3SApril Chin [0]=hello 447c2fbfb3SApril Chin [2]=world 457c2fbfb3SApril Chin [1]=( 467c2fbfb3SApril Chin x=4 477c2fbfb3SApril Chin y=5 487c2fbfb3SApril Chin ) 497c2fbfb3SApril Chin ) 507c2fbfb3SApril Chin typeset -A foo=( 517c2fbfb3SApril Chin [one]=hello 527c2fbfb3SApril Chin [three]=hi 537c2fbfb3SApril Chin [two]=( 547c2fbfb3SApril Chin x=3 557c2fbfb3SApril Chin y=4 567c2fbfb3SApril Chin ) 577c2fbfb3SApril Chin ) 587c2fbfb3SApril Chin)' 597c2fbfb3SApril Chin[[ $z == "$val" ]] || err_exit 'compound variable with mixed arrays not working' 607c2fbfb3SApril Chinz.bar[1]=yesyes 617c2fbfb3SApril Chin[[ ${z.bar[1]} == yesyes ]] || err_exit 'reassign of index array compound variable fails' 627c2fbfb3SApril Chinz.bar[1]=(x=12 y=5) 637c2fbfb3SApril Chin[[ ${z.bar[1]} == $'(\n\tx=12\n\ty=5\n)' ]] || err_exit 'reassign array simple to compound variable fails' 647c2fbfb3SApril Chineval val="$z" 657c2fbfb3SApril Chin( 667c2fbfb3SApril Chin z.foo[three]=good 677c2fbfb3SApril Chin [[ ${z.foo[three]} == good ]] || err_exit 'associative array assignment in subshell not working' 687c2fbfb3SApril Chin) 697c2fbfb3SApril Chin[[ $z == "$val" ]] || err_exit 'compound variable changes after associative array assignment' 707c2fbfb3SApril Chineval val="$z" 717c2fbfb3SApril Chin( 727c2fbfb3SApril Chinfalse 737c2fbfb3SApril Chin z.foo[two]=ok 747c2fbfb3SApril Chin [[ ${z.foo[two]} == ok ]] || err_exit 'associative array assignment to compound variable in subshell not working' 757c2fbfb3SApril Chin z.bar[1]=yes 767c2fbfb3SApril Chin [[ ${z.bar[1]} == yes ]] || err_exit 'index array assignment to compound variable in subshell not working' 777c2fbfb3SApril Chin) 787c2fbfb3SApril Chin[[ $z == "$val" ]] || err_exit 'compound variable changes after associative array assignment' 797c2fbfb3SApril Chin 807c2fbfb3SApril Chinx=( 817c2fbfb3SApril Chin foo=( qqq=abc rrr=def) 827c2fbfb3SApril Chin bar=( zzz=no rst=fed) 837c2fbfb3SApril Chin) 847c2fbfb3SApril Chineval val="$x" 857c2fbfb3SApril Chin( 867c2fbfb3SApril Chin unset x.foo 877c2fbfb3SApril Chin [[ ${x.foo.qqq} ]] && err_exit 'x.foo.qqq should be unset' 887c2fbfb3SApril Chin x.foo=good 897c2fbfb3SApril Chin [[ ${x.foo} == good ]] || err_exit 'x.foo should be good' 907c2fbfb3SApril Chin) 917c2fbfb3SApril Chin[[ $x == "$val" ]] || err_exit 'compound variable changes after unset leaves' 927c2fbfb3SApril Chinunset l 937c2fbfb3SApril Chin( 947c2fbfb3SApril Chin l=( a=1 b="BE" ) 957c2fbfb3SApril Chin) 967c2fbfb3SApril Chin[[ ${l+foo} != foo ]] || err_exit 'l should be unset' 977c2fbfb3SApril Chin 987c2fbfb3SApril ChinError_fd=9 997c2fbfb3SApril Chineval "exec $Error_fd>&2 2>/dev/null" 1007c2fbfb3SApril Chin 1017c2fbfb3SApril ChinTEST_notfound=notfound 1027c2fbfb3SApril Chinwhile whence $TEST_notfound >/dev/null 2>&1 1037c2fbfb3SApril Chindo TEST_notfound=notfound-$RANDOM 1047c2fbfb3SApril Chindone 1057c2fbfb3SApril Chin 1067c2fbfb3SApril Chininteger BS=1024 nb=64 ss=60 bs no 1077c2fbfb3SApril Chinfor bs in $BS 1 1087c2fbfb3SApril Chindo $SHELL -c ' 1097c2fbfb3SApril Chin { 1107c2fbfb3SApril Chin sleep '$ss' 1117c2fbfb3SApril Chin kill -KILL $$ 1127c2fbfb3SApril Chin } & 1137c2fbfb3SApril Chin set -- $(printf %.'$(($BS*$nb))'c x | dd bs='$bs') 1147c2fbfb3SApril Chin print ${#1} 1157c2fbfb3SApril Chin kill $! 11634f9b3eeSRoland Mainz ' > $tmp/sub 2>/dev/null 11734f9b3eeSRoland Mainz no=$(<$tmp/sub) 1187c2fbfb3SApril Chin (( no == (BS * nb) )) || err_exit "shell hangs on command substitution output size >= $BS*$nb with write size $bs -- expected $((BS*nb)), got ${no:-0}" 1197c2fbfb3SApril Chindone 1207c2fbfb3SApril Chin# this time with redirection on the trailing command 1217c2fbfb3SApril Chinfor bs in $BS 1 1227c2fbfb3SApril Chindo $SHELL -c ' 1237c2fbfb3SApril Chin { 1247c2fbfb3SApril Chin sleep 2 1257c2fbfb3SApril Chin sleep '$ss' 1267c2fbfb3SApril Chin kill -KILL $$ 1277c2fbfb3SApril Chin } & 1287c2fbfb3SApril Chin set -- $(printf %.'$(($BS*$nb))'c x | dd bs='$bs' 2>/dev/null) 1297c2fbfb3SApril Chin print ${#1} 1307c2fbfb3SApril Chin kill $! 13134f9b3eeSRoland Mainz ' > $tmp/sub 2>/dev/null 13234f9b3eeSRoland Mainz no=$(<$tmp/sub) 1337c2fbfb3SApril Chin (( 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}" 1347c2fbfb3SApril Chindone 1357c2fbfb3SApril Chin 1367c2fbfb3SApril Chin# exercise command substitutuion trailing newline logic w.r.t. pipe vs. tmp file io 1377c2fbfb3SApril Chin 1387c2fbfb3SApril Chinset -- \ 1397c2fbfb3SApril Chin 'post-line print' \ 1407c2fbfb3SApril Chin '$TEST_unset; ($TEST_fork; print 1); print' \ 1417c2fbfb3SApril Chin 1 \ 1427c2fbfb3SApril Chin 'pre-line print' \ 1437c2fbfb3SApril Chin '$TEST_unset; ($TEST_fork; print); print 1' \ 1447c2fbfb3SApril Chin $'\n1' \ 1457c2fbfb3SApril Chin 'multiple pre-line print' \ 1467c2fbfb3SApril Chin '$TEST_unset; ($TEST_fork; print); print; ($TEST_fork; print 1); print' \ 1477c2fbfb3SApril Chin $'\n\n1' \ 1487c2fbfb3SApril Chin 'multiple post-line print' \ 1497c2fbfb3SApril Chin '$TEST_unset; ($TEST_fork; print 1); print; ($TEST_fork; print); print' \ 1507c2fbfb3SApril Chin 1 \ 1517c2fbfb3SApril Chin 'intermediate print' \ 1527c2fbfb3SApril Chin '$TEST_unset; ($TEST_fork; print 1); print; ($TEST_fork; print 2); print' \ 1537c2fbfb3SApril Chin $'1\n\n2' \ 1547c2fbfb3SApril Chin 'simple variable' \ 1557c2fbfb3SApril Chin '$TEST_unset; ($TEST_fork; l=2; print "$l"); print $l' \ 1567c2fbfb3SApril Chin 2 \ 1577c2fbfb3SApril Chin 'compound variable' \ 1587c2fbfb3SApril Chin '$TEST_unset; ($TEST_fork; l=(a=2 b="BE"); print "$l"); print $l' \ 1597c2fbfb3SApril Chin $'(\n\ta=2\n\tb=BE\n)' \ 1607c2fbfb3SApril Chin 1617c2fbfb3SApril Chinexport TEST_fork TEST_unset 1627c2fbfb3SApril Chin 1637c2fbfb3SApril Chinwhile (( $# >= 3 )) 1647c2fbfb3SApril Chindo txt=$1 1657c2fbfb3SApril Chin cmd=$2 1667c2fbfb3SApril Chin exp=$3 1677c2fbfb3SApril Chin shift 3 1687c2fbfb3SApril Chin for TEST_unset in '' 'unset var' 1697c2fbfb3SApril Chin do for TEST_fork in '' 'ulimit -c 0' 1707c2fbfb3SApril Chin do for TEST_shell in "eval" "$SHELL -c" 1717c2fbfb3SApril Chin do if ! got=$($TEST_shell "$cmd") 1727c2fbfb3SApril Chin then err_exit "${TEST_shell/*-c/\$SHELL -c} ${TEST_unset:+unset }${TEST_fork:+fork }$txt print failed" 1737c2fbfb3SApril Chin elif [[ "$got" != "$exp" ]] 1747c2fbfb3SApril Chin then EXP=$(printf %q "$exp") 1757c2fbfb3SApril Chin GOT=$(printf %q "$got") 1767c2fbfb3SApril Chin err_exit "${TEST_shell/*-c/\$SHELL -c} ${TEST_unset:+unset }${TEST_fork:+fork }$txt command substitution failed -- expected $EXP, got $GOT" 1777c2fbfb3SApril Chin fi 1787c2fbfb3SApril Chin done 1797c2fbfb3SApril Chin done 1807c2fbfb3SApril Chin done 1817c2fbfb3SApril Chindone 1827c2fbfb3SApril Chin 1837c2fbfb3SApril Chinr=$( ($SHELL -c ' 1847c2fbfb3SApril Chin { 1857c2fbfb3SApril Chin sleep 32 1867c2fbfb3SApril Chin kill -KILL $$ 1877c2fbfb3SApril Chin } & 1887c2fbfb3SApril Chin for v in $(set | sed "s/=.*//") 1897c2fbfb3SApril Chin do command unset $v 1907c2fbfb3SApril Chin done 1917c2fbfb3SApril Chin typeset -Z5 I 1927c2fbfb3SApril Chin for ((I = 0; I < 1024; I++)) 1937c2fbfb3SApril Chin do eval A$I=1234567890 1947c2fbfb3SApril Chin done 1957c2fbfb3SApril Chin a=$(set 2>&1) 1967c2fbfb3SApril Chin print ok 1977c2fbfb3SApril Chin kill -KILL $! 1987c2fbfb3SApril Chin') 2>/dev/null) 1997c2fbfb3SApril Chin[[ $r == ok ]] || err_exit "large subshell command substitution hangs" 2007c2fbfb3SApril Chin 2017c2fbfb3SApril Chinfor TEST_command in '' $TEST_notfound 2027c2fbfb3SApril Chindo for TEST_exec in '' 'exec' 2037c2fbfb3SApril Chin do for TEST_fork in '' 'ulimit -c 0;' 2047c2fbfb3SApril Chin do for TEST_redirect in '' '>/dev/null' 2057c2fbfb3SApril Chin do for TEST_substitute in '' ': $' 2067c2fbfb3SApril Chin do 2077c2fbfb3SApril Chin 2087c2fbfb3SApril Chin TEST_test="$TEST_substitute($TEST_fork $TEST_exec $TEST_command $TEST_redirect)" 2097c2fbfb3SApril Chin [[ $TEST_test == '('*([[:space:]])')' ]] && continue 2107c2fbfb3SApril Chin r=$($SHELL -c ' 2117c2fbfb3SApril Chin { 2127c2fbfb3SApril Chin sleep 2 2137c2fbfb3SApril Chin kill -KILL $$ 2147c2fbfb3SApril Chin } & 2157c2fbfb3SApril Chin '"$TEST_test"' 2167c2fbfb3SApril Chin kill $! 2177c2fbfb3SApril Chin print ok 2187c2fbfb3SApril Chin ') 2197c2fbfb3SApril Chin [[ $r == ok ]] || err_exit "shell hangs on $TEST_test" 2207c2fbfb3SApril Chin 2217c2fbfb3SApril Chin done 2227c2fbfb3SApril Chin done 2237c2fbfb3SApril Chin done 2247c2fbfb3SApril Chin done 2257c2fbfb3SApril Chindone 2267c2fbfb3SApril Chin 22734f9b3eeSRoland Mainz$SHELL -c '( autoload xxxxx);print -n' || err_exit 'autoloaded functions in subshells can cause failure' 22834f9b3eeSRoland Mainzfoo=$($SHELL <<- ++EOF++ 22934f9b3eeSRoland Mainz (trap 'print bar' EXIT;print -n foo) 23034f9b3eeSRoland Mainz ++EOF++ 23134f9b3eeSRoland Mainz) 23234f9b3eeSRoland Mainz[[ $foo == foobar ]] || err_exit 'trap on exit when last commands is subshell is not triggered' 23334f9b3eeSRoland Mainz 23434f9b3eeSRoland Mainzerr=$( 23534f9b3eeSRoland Mainz $SHELL 2>&1 <<- \EOF 23634f9b3eeSRoland Mainz date=$(whence -p date) 23734f9b3eeSRoland Mainz function foo 23834f9b3eeSRoland Mainz { 23934f9b3eeSRoland Mainz x=$( $date > /dev/null 2>&1 ;:) 24034f9b3eeSRoland Mainz } 24134f9b3eeSRoland Mainz # consume almost all fds to push the test to the fd limit # 24234f9b3eeSRoland Mainz integer max=$(ulimit --nofile) 24334f9b3eeSRoland Mainz (( max -= 6 )) 24434f9b3eeSRoland Mainz for ((i=20; i < max; i++)) 24534f9b3eeSRoland Mainz do exec {i}>&1 24634f9b3eeSRoland Mainz done 24734f9b3eeSRoland Mainz for ((i=0; i < 20; i++)) 24834f9b3eeSRoland Mainz do y=$(foo) 24934f9b3eeSRoland Mainz done 25034f9b3eeSRoland Mainz EOF 25134f9b3eeSRoland Mainz) || { 25234f9b3eeSRoland Mainz err=${err%%$'\n'*} 25334f9b3eeSRoland Mainz err=${err#*:} 25434f9b3eeSRoland Mainz err=${err##[[:space:]]} 25534f9b3eeSRoland Mainz err_exit "nested command substitution with redirections failed -- $err" 25634f9b3eeSRoland Mainz} 25734f9b3eeSRoland Mainz 25834f9b3eeSRoland Mainzexp=0 25934f9b3eeSRoland Mainz$SHELL -c $' 26034f9b3eeSRoland Mainz function foobar 26134f9b3eeSRoland Mainz { 26234f9b3eeSRoland Mainz print "hello world" 26334f9b3eeSRoland Mainz } 26434f9b3eeSRoland Mainz [[ $(getopts \'[+?X\ffoobar\fX]\' v --man 2>&1) == *"Xhello worldX"* ]] 26534f9b3eeSRoland Mainz exit '$exp$' 26634f9b3eeSRoland Mainz' 26734f9b3eeSRoland Mainzgot=$? 26834f9b3eeSRoland Mainz[[ $got == $exp ]] || err_exit "getopts --man runtime callout with nonzero exit terminates shell -- expected '$exp', got '$got'" 26934f9b3eeSRoland Mainzexp=ok 27034f9b3eeSRoland Mainzgot=$($SHELL -c $' 27134f9b3eeSRoland Mainz function foobar 27234f9b3eeSRoland Mainz { 27334f9b3eeSRoland Mainz print "hello world" 27434f9b3eeSRoland Mainz } 27534f9b3eeSRoland Mainz [[ $(getopts \'[+?X\ffoobar\fX]\' v --man 2>&1) == *"Xhello worldX"* ]] 27634f9b3eeSRoland Mainz print '$exp$' 27734f9b3eeSRoland Mainz') 27834f9b3eeSRoland Mainz[[ $got == $exp ]] || err_exit "getopts --man runtime callout with nonzero exit terminates shell -- expected '$exp', got '$got'" 27934f9b3eeSRoland Mainz 28034f9b3eeSRoland Mainz# command substitution variations # 28134f9b3eeSRoland Mainzset -- \ 28234f9b3eeSRoland Mainz '$(' ')' \ 28334f9b3eeSRoland Mainz '${ ' '; }' \ 28434f9b3eeSRoland Mainz '$(ulimit -c 0; ' ')' \ 28534f9b3eeSRoland Mainz '$( (' ') )' \ 28634f9b3eeSRoland Mainz '${ (' '); }' \ 28734f9b3eeSRoland Mainz '`' '`' \ 28834f9b3eeSRoland Mainz '`(' ')`' \ 28934f9b3eeSRoland Mainz '`ulimit -c 0; ' '`' \ 29034f9b3eeSRoland Mainz # end of table # 29134f9b3eeSRoland Mainzexp=ok 29234f9b3eeSRoland Mainztestcase[1]=' 29334f9b3eeSRoland Mainz if %sexpr "NOMATCH" : ".*Z" >/dev/null%s 29434f9b3eeSRoland Mainz then print error 29534f9b3eeSRoland Mainz else print ok 29634f9b3eeSRoland Mainz fi 29734f9b3eeSRoland Mainz exit %s 29834f9b3eeSRoland Mainz' 29934f9b3eeSRoland Mainztestcase[2]=' 30034f9b3eeSRoland Mainz function bar 30134f9b3eeSRoland Mainz { 30234f9b3eeSRoland Mainz pipeout=%1$sprintf Ok | tr O o%2$s 30334f9b3eeSRoland Mainz print $pipeout 30434f9b3eeSRoland Mainz return 0 30534f9b3eeSRoland Mainz } 30634f9b3eeSRoland Mainz foo=%1$sbar%2$s || foo="exit status $?" 30734f9b3eeSRoland Mainz print $foo 30834f9b3eeSRoland Mainz exit %3$s 30934f9b3eeSRoland Mainz' 31034f9b3eeSRoland Mainzwhile (( $# >= 2 )) 31134f9b3eeSRoland Mainzdo for ((TEST=1; TEST<=${#testcase[@]}; TEST++)) 31234f9b3eeSRoland Mainz do body=${testcase[TEST]} 31334f9b3eeSRoland Mainz for code in 0 2 31434f9b3eeSRoland Mainz do got=${ printf "$body" "$1" "$2" "$code" | $SHELL 2>&1 } 31534f9b3eeSRoland Mainz status=$? 31634f9b3eeSRoland Mainz if (( status != code )) 31734f9b3eeSRoland Mainz then err_exit "test $TEST '$1...$2 exit $code' failed -- exit status $status, expected $code" 31834f9b3eeSRoland Mainz elif [[ $got != $exp ]] 31934f9b3eeSRoland Mainz then err_exit "test $TEST '$1...$2 exit $code' failed -- got '$got', expected '$exp'" 32034f9b3eeSRoland Mainz fi 32134f9b3eeSRoland Mainz done 32234f9b3eeSRoland Mainz done 32334f9b3eeSRoland Mainz shift 2 32434f9b3eeSRoland Mainzdone 32534f9b3eeSRoland Mainz 32634f9b3eeSRoland Mainz# the next tests loop on all combinations of 32734f9b3eeSRoland Mainz# { SUB CAT INS TST APP } X { file-sizes } 32834f9b3eeSRoland Mainz# where the file size starts at 1Ki and doubles up to and including 1Mi 32934f9b3eeSRoland Mainz# 33034f9b3eeSRoland Mainz# the tests and timeouts are done in async subshells to prevent 33134f9b3eeSRoland Mainz# the test harness from hanging 33234f9b3eeSRoland Mainz 33334f9b3eeSRoland MainzSUB=( 33434f9b3eeSRoland Mainz ( BEG='$( ' END=' )' ) 33534f9b3eeSRoland Mainz ( BEG='${ ' END='; }' ) 33634f9b3eeSRoland Mainz) 33734f9b3eeSRoland MainzCAT=( cat $bincat ) 33834f9b3eeSRoland MainzINS=( "" "builtin cat; " "builtin -d cat $bincat; " ": > /dev/null; " ) 33934f9b3eeSRoland MainzAPP=( "" "; :" ) 34034f9b3eeSRoland MainzTST=( 34134f9b3eeSRoland Mainz ( CMD='print foo | $cat' EXP=3 ) 34234f9b3eeSRoland Mainz ( CMD='$cat < $tmp/lin' ) 34334f9b3eeSRoland Mainz ( CMD='cat $tmp/lin | $cat' ) 34434f9b3eeSRoland Mainz ( CMD='read v < $tmp/buf; print $v' LIM=4*1024 ) 34534f9b3eeSRoland Mainz ( CMD='cat $tmp/buf | read v; print $v' LIM=4*1024 ) 34634f9b3eeSRoland Mainz) 34734f9b3eeSRoland Mainz 34834f9b3eeSRoland Mainzcommand exec 3<> /dev/null 34934f9b3eeSRoland Mainzif cat /dev/fd/3 >/dev/null 2>&1 35034f9b3eeSRoland Mainzthen T=${#TST[@]} 35134f9b3eeSRoland Mainz TST[T].CMD='$cat <(print foo)' 35234f9b3eeSRoland Mainz TST[T].EXP=3 35334f9b3eeSRoland Mainzfi 35434f9b3eeSRoland Mainz 35534f9b3eeSRoland Mainz# prime the two data files to 512 bytes each 35634f9b3eeSRoland Mainz# $tmp/lin has newlines every 16 bytes and $tmp/buf has no newlines 35734f9b3eeSRoland Mainz# the outer loop doubles the file size at top 35834f9b3eeSRoland Mainz 35934f9b3eeSRoland Mainzbuf=$'1234567890abcdef' 36034f9b3eeSRoland Mainzlin=$'\n1234567890abcde' 36134f9b3eeSRoland Mainzfor ((i=0; i<5; i++)) 36234f9b3eeSRoland Mainzdo buf=$buf$buf 36334f9b3eeSRoland Mainz lin=$lin$lin 36434f9b3eeSRoland Mainzdone 36534f9b3eeSRoland Mainzprint -n "$buf" > $tmp/buf 36634f9b3eeSRoland Mainzprint -n "$lin" > $tmp/lin 36734f9b3eeSRoland Mainz 36834f9b3eeSRoland Mainzunset SKIP 36934f9b3eeSRoland Mainzfor ((n=1024; n<=1024*1024; n*=2)) 37034f9b3eeSRoland Mainzdo cat $tmp/buf $tmp/buf > $tmp/tmp 37134f9b3eeSRoland Mainz mv $tmp/tmp $tmp/buf 37234f9b3eeSRoland Mainz cat $tmp/lin $tmp/lin > $tmp/tmp 37334f9b3eeSRoland Mainz mv $tmp/tmp $tmp/lin 37434f9b3eeSRoland Mainz for ((S=0; S<${#SUB[@]}; S++)) 37534f9b3eeSRoland Mainz do for ((C=0; C<${#CAT[@]}; C++)) 37634f9b3eeSRoland Mainz do cat=${CAT[C]} 37734f9b3eeSRoland Mainz for ((I=0; I<${#INS[@]}; I++)) 37834f9b3eeSRoland Mainz do for ((A=0; A<${#APP[@]}; A++)) 37934f9b3eeSRoland Mainz do for ((T=0; T<${#TST[@]}; T++)) 38034f9b3eeSRoland Mainz do #undent...# 38134f9b3eeSRoland Mainz 38234f9b3eeSRoland Mainz if [[ ! ${SKIP[S][C][I][A][T]} ]] 38334f9b3eeSRoland Mainz then eval "{ x=${SUB[S].BEG}${INS[I]}${TST[T].CMD}${APP[A]}${SUB[S].END}; print \${#x}; } >\$tmp/out &" 38434f9b3eeSRoland Mainz m=$! 38534f9b3eeSRoland Mainz { sleep 4; kill -9 $m; } & 38634f9b3eeSRoland Mainz k=$! 38734f9b3eeSRoland Mainz wait $m 38834f9b3eeSRoland Mainz h=$? 38934f9b3eeSRoland Mainz kill -9 $k 39034f9b3eeSRoland Mainz wait $k 39134f9b3eeSRoland Mainz got=$(<$tmp/out) 39234f9b3eeSRoland Mainz if [[ ! $got ]] && (( h )) 39334f9b3eeSRoland Mainz then got=HUNG 39434f9b3eeSRoland Mainz fi 39534f9b3eeSRoland Mainz if [[ ${TST[T].EXP} ]] 39634f9b3eeSRoland Mainz then exp=${TST[T].EXP} 39734f9b3eeSRoland Mainz else exp=$n 39834f9b3eeSRoland Mainz fi 39934f9b3eeSRoland Mainz if [[ $got != $exp ]] 40034f9b3eeSRoland Mainz then # on failure skip similar tests on larger files sizes # 40134f9b3eeSRoland Mainz SKIP[S][C][I][A][T]=1 40234f9b3eeSRoland Mainz siz=$(printf $'%#i' $exp) 40334f9b3eeSRoland Mainz cmd=${TST[T].CMD//\$cat/$cat} 40434f9b3eeSRoland Mainz cmd=${cmd//\$tmp\/buf/$siz.buf} 40534f9b3eeSRoland Mainz cmd=${cmd//\$tmp\/lin/$siz.lin} 40634f9b3eeSRoland Mainz err_exit "'x=${SUB[S].BEG}${INS[I]}${cmd}${APP[A]}${SUB[S].END} && print \${#x}' failed -- expected '$exp', got '$got'" 40734f9b3eeSRoland Mainz elif [[ ${TST[T].EXP} ]] || (( TST[T].LIM >= n )) 40834f9b3eeSRoland Mainz then SKIP[S][C][I][A][T]=1 40934f9b3eeSRoland Mainz fi 41034f9b3eeSRoland Mainz fi 41134f9b3eeSRoland Mainz 41234f9b3eeSRoland Mainz #...indent# 41334f9b3eeSRoland Mainz done 41434f9b3eeSRoland Mainz done 41534f9b3eeSRoland Mainz done 41634f9b3eeSRoland Mainz done 41734f9b3eeSRoland Mainz done 41834f9b3eeSRoland Mainzdone 41934f9b3eeSRoland Mainz 42034f9b3eeSRoland Mainz# specifics -- there's more? 42134f9b3eeSRoland Mainz 42234f9b3eeSRoland Mainz{ 42334f9b3eeSRoland Mainz cmd='{ exec 5>/dev/null; print "$(eval ls -d . 2>&1 1>&5)"; } >$tmp/out &' 42434f9b3eeSRoland Mainz eval $cmd 42534f9b3eeSRoland Mainz m=$! 42634f9b3eeSRoland Mainz { sleep 4; kill -9 $m; } & 42734f9b3eeSRoland Mainz k=$! 42834f9b3eeSRoland Mainz wait $m 42934f9b3eeSRoland Mainz h=$? 43034f9b3eeSRoland Mainz kill -9 $k 43134f9b3eeSRoland Mainz wait $k 43234f9b3eeSRoland Mainz got=$(<$tmp/out) 43334f9b3eeSRoland Mainz} 2>/dev/null 43434f9b3eeSRoland Mainzexp='' 43534f9b3eeSRoland Mainzif [[ ! $got ]] && (( h )) 43634f9b3eeSRoland Mainzthen got=HUNG 43734f9b3eeSRoland Mainzfi 43834f9b3eeSRoland Mainzif [[ $got != $exp ]] 43934f9b3eeSRoland Mainzthen err_exit "eval '$cmd' failed -- expected '$exp', got '$got'" 44034f9b3eeSRoland Mainzfi 44134f9b3eeSRoland Mainz 44234f9b3eeSRoland Mainzfloat t1=$SECONDS 44334f9b3eeSRoland Mainzsleep=$(whence -p sleep) 44434f9b3eeSRoland Mainzif [[ $sleep ]] 44534f9b3eeSRoland Mainzthen 44634f9b3eeSRoland Mainz $SHELL -c "( $sleep 5 </dev/null >/dev/null 2>&1 & );exit 0" | cat 44734f9b3eeSRoland Mainz (( (SECONDS-t1) > 4 )) && err_exit '/bin/sleep& in subshell hanging' 44834f9b3eeSRoland Mainz ((t1=SECONDS)) 44934f9b3eeSRoland Mainzfi 45034f9b3eeSRoland Mainz$SHELL -c '( sleep 5 </dev/null >/dev/null 2>&1 & );exit 0' | cat 45134f9b3eeSRoland Mainz(( (SECONDS-t1) > 4 )) && err_exit 'sleep& in subshell hanging' 45234f9b3eeSRoland Mainz 453*3e14f97fSRoger A. Faulknerexp=HOME=$HOME 454*3e14f97fSRoger A. Faulkner( HOME=/bin/sh ) 455*3e14f97fSRoger A. Faulknergot=$(env | grep ^HOME=) 456*3e14f97fSRoger A. Faulkner[[ $got == "$exp" ]] || err_exit "( HOME=/bin/sh ) cleanup failed -- expected '$exp', got '$got'" 457*3e14f97fSRoger A. Faulkner 458*3e14f97fSRoger A. Faulknercmd='echo $((case x in x)echo ok;esac);:)' 459*3e14f97fSRoger A. Faulknerexp=ok 460*3e14f97fSRoger A. Faulknergot=$($SHELL -c "$cmd" 2>&1) 461*3e14f97fSRoger A. Faulkner[[ $got == "$exp" ]] || err_exit "'$cmd' failed -- expected '$exp', got '$got'" 462*3e14f97fSRoger A. Faulkner 463*3e14f97fSRoger A. Faulknercmd='eval "for i in 1 2; do eval /bin/echo x; done"' 464*3e14f97fSRoger A. Faulknerexp=$'x\nx' 465*3e14f97fSRoger A. Faulknergot=$($SHELL -c "$cmd") 466*3e14f97fSRoger A. Faulknerif [[ $got != "$exp" ]] 467*3e14f97fSRoger A. Faulknerthen EXP=$(printf %q "$exp") 468*3e14f97fSRoger A. Faulkner GOT=$(printf %q "$got") 469*3e14f97fSRoger A. Faulkner err_exit "'$cmd' failed -- expected $EXP, got $GOT" 470*3e14f97fSRoger A. Faulknerfi 471*3e14f97fSRoger A. Faulkner 4727c2fbfb3SApril Chinexit $Errors 473