xref: /onnv-gate/usr/src/lib/libshell/common/tests/subshell.sh (revision 12068:08a39a083754)
18462SApril.Chin@Sun.COM########################################################################
28462SApril.Chin@Sun.COM#                                                                      #
38462SApril.Chin@Sun.COM#               This software is part of the ast package               #
4*12068SRoger.Faulkner@Oracle.COM#          Copyright (c) 1982-2010 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'
2710898Sroland.mainz@nrubsig.org
288462SApril.Chin@Sun.COMCommand=${0##*/}
298462SApril.Chin@Sun.COMinteger Errors=0 Error_fd=2
308462SApril.Chin@Sun.COM
3110898Sroland.mainz@nrubsig.orgtmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
3210898Sroland.mainz@nrubsig.orgtrap "cd /; rm -rf $tmp" EXIT
3310898Sroland.mainz@nrubsig.org
3410898Sroland.mainz@nrubsig.orgbincat=$(PATH=$(getconf PATH) whence -p cat)
3510898Sroland.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'
7910898Sroland.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 $!
11610898Sroland.mainz@nrubsig.org	' > $tmp/sub 2>/dev/null
11710898Sroland.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 $!
13110898Sroland.mainz@nrubsig.org	' > $tmp/sub 2>/dev/null
13210898Sroland.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
22710898Sroland.mainz@nrubsig.org$SHELL -c '( autoload xxxxx);print -n' ||  err_exit 'autoloaded functions in subshells can cause failure'
22810898Sroland.mainz@nrubsig.orgfoo=$($SHELL  <<- ++EOF++
22910898Sroland.mainz@nrubsig.org	(trap 'print bar' EXIT;print -n foo)
23010898Sroland.mainz@nrubsig.org	++EOF++
23110898Sroland.mainz@nrubsig.org)
23210898Sroland.mainz@nrubsig.org[[ $foo == foobar ]] || err_exit 'trap on exit when last commands is subshell is not triggered'
23310898Sroland.mainz@nrubsig.org
23410898Sroland.mainz@nrubsig.orgerr=$(
23510898Sroland.mainz@nrubsig.org	$SHELL  2>&1  <<- \EOF
23610898Sroland.mainz@nrubsig.org	        date=$(whence -p date)
23710898Sroland.mainz@nrubsig.org	        function foo
23810898Sroland.mainz@nrubsig.org	        {
23910898Sroland.mainz@nrubsig.org	                x=$( $date > /dev/null 2>&1 ;:)
24010898Sroland.mainz@nrubsig.org	        }
24110898Sroland.mainz@nrubsig.org		# consume almost all fds to push the test to the fd limit #
24210898Sroland.mainz@nrubsig.org		integer max=$(ulimit --nofile)
24310898Sroland.mainz@nrubsig.org		(( max -= 6 ))
24410898Sroland.mainz@nrubsig.org		for ((i=20; i < max; i++))
24510898Sroland.mainz@nrubsig.org		do	exec {i}>&1
24610898Sroland.mainz@nrubsig.org		done
24710898Sroland.mainz@nrubsig.org	        for ((i=0; i < 20; i++))
24810898Sroland.mainz@nrubsig.org	        do      y=$(foo)
24910898Sroland.mainz@nrubsig.org	        done
25010898Sroland.mainz@nrubsig.org	EOF
25110898Sroland.mainz@nrubsig.org) || {
25210898Sroland.mainz@nrubsig.org	err=${err%%$'\n'*}
25310898Sroland.mainz@nrubsig.org	err=${err#*:}
25410898Sroland.mainz@nrubsig.org	err=${err##[[:space:]]}
25510898Sroland.mainz@nrubsig.org	err_exit "nested command substitution with redirections failed -- $err"
25610898Sroland.mainz@nrubsig.org}
25710898Sroland.mainz@nrubsig.org
25810898Sroland.mainz@nrubsig.orgexp=0
25910898Sroland.mainz@nrubsig.org$SHELL -c $'
26010898Sroland.mainz@nrubsig.org	function foobar
26110898Sroland.mainz@nrubsig.org	{
26210898Sroland.mainz@nrubsig.org		print "hello world"
26310898Sroland.mainz@nrubsig.org	}
26410898Sroland.mainz@nrubsig.org	[[ $(getopts \'[+?X\ffoobar\fX]\' v --man 2>&1) == *"Xhello worldX"* ]]
26510898Sroland.mainz@nrubsig.org	exit '$exp$'
26610898Sroland.mainz@nrubsig.org'
26710898Sroland.mainz@nrubsig.orggot=$?
26810898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "getopts --man runtime callout with nonzero exit terminates shell -- expected '$exp', got '$got'"
26910898Sroland.mainz@nrubsig.orgexp=ok
27010898Sroland.mainz@nrubsig.orggot=$($SHELL -c $'
27110898Sroland.mainz@nrubsig.org	function foobar
27210898Sroland.mainz@nrubsig.org	{
27310898Sroland.mainz@nrubsig.org		print "hello world"
27410898Sroland.mainz@nrubsig.org	}
27510898Sroland.mainz@nrubsig.org	[[ $(getopts \'[+?X\ffoobar\fX]\' v --man 2>&1) == *"Xhello worldX"* ]]
27610898Sroland.mainz@nrubsig.org	print '$exp$'
27710898Sroland.mainz@nrubsig.org')
27810898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "getopts --man runtime callout with nonzero exit terminates shell -- expected '$exp', got '$got'"
27910898Sroland.mainz@nrubsig.org
28010898Sroland.mainz@nrubsig.org# command substitution variations #
28110898Sroland.mainz@nrubsig.orgset -- \
28210898Sroland.mainz@nrubsig.org	'$('			')'		\
28310898Sroland.mainz@nrubsig.org	'${ '			'; }'		\
28410898Sroland.mainz@nrubsig.org	'$(ulimit -c 0; '	')'		\
28510898Sroland.mainz@nrubsig.org	'$( ('			') )'		\
28610898Sroland.mainz@nrubsig.org	'${ ('			'); }'		\
28710898Sroland.mainz@nrubsig.org	'`'			'`'		\
28810898Sroland.mainz@nrubsig.org	'`('			')`'		\
28910898Sroland.mainz@nrubsig.org	'`ulimit -c 0; '	'`'		\
29010898Sroland.mainz@nrubsig.org	# end of table #
29110898Sroland.mainz@nrubsig.orgexp=ok
29210898Sroland.mainz@nrubsig.orgtestcase[1]='
29310898Sroland.mainz@nrubsig.org	if	%sexpr "NOMATCH" : ".*Z" >/dev/null%s
29410898Sroland.mainz@nrubsig.org	then	print error
29510898Sroland.mainz@nrubsig.org	else	print ok
29610898Sroland.mainz@nrubsig.org	fi
29710898Sroland.mainz@nrubsig.org	exit %s
29810898Sroland.mainz@nrubsig.org'
29910898Sroland.mainz@nrubsig.orgtestcase[2]='
30010898Sroland.mainz@nrubsig.org	function bar
30110898Sroland.mainz@nrubsig.org	{
30210898Sroland.mainz@nrubsig.org		pipeout=%1$sprintf Ok | tr O o%2$s
30310898Sroland.mainz@nrubsig.org		print $pipeout
30410898Sroland.mainz@nrubsig.org		return 0
30510898Sroland.mainz@nrubsig.org	}
30610898Sroland.mainz@nrubsig.org	foo=%1$sbar%2$s || foo="exit status $?"
30710898Sroland.mainz@nrubsig.org	print $foo
30810898Sroland.mainz@nrubsig.org	exit %3$s
30910898Sroland.mainz@nrubsig.org'
31010898Sroland.mainz@nrubsig.orgwhile	(( $# >= 2 ))
31110898Sroland.mainz@nrubsig.orgdo	for ((TEST=1; TEST<=${#testcase[@]}; TEST++))
31210898Sroland.mainz@nrubsig.org	do	body=${testcase[TEST]}
31310898Sroland.mainz@nrubsig.org		for code in 0 2
31410898Sroland.mainz@nrubsig.org		do	got=${ printf "$body" "$1" "$2" "$code" | $SHELL 2>&1 }
31510898Sroland.mainz@nrubsig.org			status=$?
31610898Sroland.mainz@nrubsig.org			if	(( status != code ))
31710898Sroland.mainz@nrubsig.org			then	err_exit "test $TEST '$1...$2 exit $code' failed -- exit status $status, expected $code"
31810898Sroland.mainz@nrubsig.org			elif	[[ $got != $exp ]]
31910898Sroland.mainz@nrubsig.org			then	err_exit "test $TEST '$1...$2 exit $code' failed -- got '$got', expected '$exp'"
32010898Sroland.mainz@nrubsig.org			fi
32110898Sroland.mainz@nrubsig.org		done
32210898Sroland.mainz@nrubsig.org	done
32310898Sroland.mainz@nrubsig.org	shift 2
32410898Sroland.mainz@nrubsig.orgdone
32510898Sroland.mainz@nrubsig.org
32610898Sroland.mainz@nrubsig.org# the next tests loop on all combinations of
32710898Sroland.mainz@nrubsig.org#	{ SUB CAT INS TST APP } X { file-sizes }
32810898Sroland.mainz@nrubsig.org# where the file size starts at 1Ki and doubles up to and including 1Mi
32910898Sroland.mainz@nrubsig.org#
33010898Sroland.mainz@nrubsig.org# the tests and timeouts are done in async subshells to prevent
33110898Sroland.mainz@nrubsig.org# the test harness from hanging
33210898Sroland.mainz@nrubsig.org
33310898Sroland.mainz@nrubsig.orgSUB=(
33410898Sroland.mainz@nrubsig.org	( BEG='$( '	END=' )'	)
33510898Sroland.mainz@nrubsig.org	( BEG='${ '	END='; }'	)
33610898Sroland.mainz@nrubsig.org)
33710898Sroland.mainz@nrubsig.orgCAT=(  cat  $bincat  )
33810898Sroland.mainz@nrubsig.orgINS=(  ""  "builtin cat; "  "builtin -d cat $bincat; "  ": > /dev/null; "  )
33910898Sroland.mainz@nrubsig.orgAPP=(  ""  "; :"  )
34010898Sroland.mainz@nrubsig.orgTST=(
34110898Sroland.mainz@nrubsig.org	( CMD='print foo | $cat'			EXP=3		)
34210898Sroland.mainz@nrubsig.org	( CMD='$cat < $tmp/lin'						)
34310898Sroland.mainz@nrubsig.org	( CMD='cat $tmp/lin | $cat'					)
34410898Sroland.mainz@nrubsig.org	( CMD='read v < $tmp/buf; print $v'		LIM=4*1024	)
34510898Sroland.mainz@nrubsig.org	( CMD='cat $tmp/buf | read v; print $v'		LIM=4*1024	)
34610898Sroland.mainz@nrubsig.org)
34710898Sroland.mainz@nrubsig.org
34810898Sroland.mainz@nrubsig.orgcommand exec 3<> /dev/null
34910898Sroland.mainz@nrubsig.orgif	cat /dev/fd/3 >/dev/null 2>&1
35010898Sroland.mainz@nrubsig.orgthen	T=${#TST[@]}
35110898Sroland.mainz@nrubsig.org	TST[T].CMD='$cat <(print foo)'
35210898Sroland.mainz@nrubsig.org	TST[T].EXP=3
35310898Sroland.mainz@nrubsig.orgfi
35410898Sroland.mainz@nrubsig.org
35510898Sroland.mainz@nrubsig.org# prime the two data files to 512 bytes each
35610898Sroland.mainz@nrubsig.org# $tmp/lin has newlines every 16 bytes and $tmp/buf has no newlines
35710898Sroland.mainz@nrubsig.org# the outer loop doubles the file size at top
35810898Sroland.mainz@nrubsig.org
35910898Sroland.mainz@nrubsig.orgbuf=$'1234567890abcdef'
36010898Sroland.mainz@nrubsig.orglin=$'\n1234567890abcde'
36110898Sroland.mainz@nrubsig.orgfor ((i=0; i<5; i++))
36210898Sroland.mainz@nrubsig.orgdo	buf=$buf$buf
36310898Sroland.mainz@nrubsig.org	lin=$lin$lin
36410898Sroland.mainz@nrubsig.orgdone
36510898Sroland.mainz@nrubsig.orgprint -n "$buf" > $tmp/buf
36610898Sroland.mainz@nrubsig.orgprint -n "$lin" > $tmp/lin
36710898Sroland.mainz@nrubsig.org
36810898Sroland.mainz@nrubsig.orgunset SKIP
36910898Sroland.mainz@nrubsig.orgfor ((n=1024; n<=1024*1024; n*=2))
37010898Sroland.mainz@nrubsig.orgdo	cat $tmp/buf $tmp/buf > $tmp/tmp
37110898Sroland.mainz@nrubsig.org	mv $tmp/tmp $tmp/buf
37210898Sroland.mainz@nrubsig.org	cat $tmp/lin $tmp/lin > $tmp/tmp
37310898Sroland.mainz@nrubsig.org	mv $tmp/tmp $tmp/lin
37410898Sroland.mainz@nrubsig.org	for ((S=0; S<${#SUB[@]}; S++))
37510898Sroland.mainz@nrubsig.org	do	for ((C=0; C<${#CAT[@]}; C++))
37610898Sroland.mainz@nrubsig.org		do	cat=${CAT[C]}
37710898Sroland.mainz@nrubsig.org			for ((I=0; I<${#INS[@]}; I++))
37810898Sroland.mainz@nrubsig.org			do	for ((A=0; A<${#APP[@]}; A++))
37910898Sroland.mainz@nrubsig.org				do	for ((T=0; T<${#TST[@]}; T++))
38010898Sroland.mainz@nrubsig.org					do	#undent...#
38110898Sroland.mainz@nrubsig.org
38210898Sroland.mainz@nrubsig.org	if	[[ ! ${SKIP[S][C][I][A][T]} ]]
38310898Sroland.mainz@nrubsig.org	then	eval "{ x=${SUB[S].BEG}${INS[I]}${TST[T].CMD}${APP[A]}${SUB[S].END}; print \${#x}; } >\$tmp/out &"
38410898Sroland.mainz@nrubsig.org		m=$!
38510898Sroland.mainz@nrubsig.org		{ sleep 4; kill -9 $m; } &
38610898Sroland.mainz@nrubsig.org		k=$!
38710898Sroland.mainz@nrubsig.org		wait $m
38810898Sroland.mainz@nrubsig.org		h=$?
38910898Sroland.mainz@nrubsig.org		kill -9 $k
39010898Sroland.mainz@nrubsig.org		wait $k
39110898Sroland.mainz@nrubsig.org		got=$(<$tmp/out)
39210898Sroland.mainz@nrubsig.org		if	[[ ! $got ]] && (( h ))
39310898Sroland.mainz@nrubsig.org		then	got=HUNG
39410898Sroland.mainz@nrubsig.org		fi
39510898Sroland.mainz@nrubsig.org		if	[[ ${TST[T].EXP} ]]
39610898Sroland.mainz@nrubsig.org		then	exp=${TST[T].EXP}
39710898Sroland.mainz@nrubsig.org		else	exp=$n
39810898Sroland.mainz@nrubsig.org		fi
39910898Sroland.mainz@nrubsig.org		if	[[ $got != $exp ]]
40010898Sroland.mainz@nrubsig.org		then	# on failure skip similar tests on larger files sizes #
40110898Sroland.mainz@nrubsig.org			SKIP[S][C][I][A][T]=1
40210898Sroland.mainz@nrubsig.org			siz=$(printf $'%#i' $exp)
40310898Sroland.mainz@nrubsig.org			cmd=${TST[T].CMD//\$cat/$cat}
40410898Sroland.mainz@nrubsig.org			cmd=${cmd//\$tmp\/buf/$siz.buf}
40510898Sroland.mainz@nrubsig.org			cmd=${cmd//\$tmp\/lin/$siz.lin}
40610898Sroland.mainz@nrubsig.org			err_exit "'x=${SUB[S].BEG}${INS[I]}${cmd}${APP[A]}${SUB[S].END} && print \${#x}' failed -- expected '$exp', got '$got'"
40710898Sroland.mainz@nrubsig.org		elif	[[ ${TST[T].EXP} ]] || (( TST[T].LIM >= n ))
40810898Sroland.mainz@nrubsig.org		then	SKIP[S][C][I][A][T]=1
40910898Sroland.mainz@nrubsig.org		fi
41010898Sroland.mainz@nrubsig.org	fi
41110898Sroland.mainz@nrubsig.org
41210898Sroland.mainz@nrubsig.org						#...indent#
41310898Sroland.mainz@nrubsig.org					done
41410898Sroland.mainz@nrubsig.org				done
41510898Sroland.mainz@nrubsig.org			done
41610898Sroland.mainz@nrubsig.org		done
41710898Sroland.mainz@nrubsig.org	done
41810898Sroland.mainz@nrubsig.orgdone
41910898Sroland.mainz@nrubsig.org
42010898Sroland.mainz@nrubsig.org# specifics -- there's more?
42110898Sroland.mainz@nrubsig.org
42210898Sroland.mainz@nrubsig.org{
42310898Sroland.mainz@nrubsig.org	cmd='{ exec 5>/dev/null; print "$(eval ls -d . 2>&1 1>&5)"; } >$tmp/out &'
42410898Sroland.mainz@nrubsig.org	eval $cmd
42510898Sroland.mainz@nrubsig.org	m=$!
42610898Sroland.mainz@nrubsig.org	{ sleep 4; kill -9 $m; } &
42710898Sroland.mainz@nrubsig.org	k=$!
42810898Sroland.mainz@nrubsig.org	wait $m
42910898Sroland.mainz@nrubsig.org	h=$?
43010898Sroland.mainz@nrubsig.org	kill -9 $k
43110898Sroland.mainz@nrubsig.org	wait $k
43210898Sroland.mainz@nrubsig.org	got=$(<$tmp/out)
43310898Sroland.mainz@nrubsig.org} 2>/dev/null
43410898Sroland.mainz@nrubsig.orgexp=''
43510898Sroland.mainz@nrubsig.orgif	[[ ! $got ]] && (( h ))
43610898Sroland.mainz@nrubsig.orgthen	got=HUNG
43710898Sroland.mainz@nrubsig.orgfi
43810898Sroland.mainz@nrubsig.orgif	[[ $got != $exp ]]
43910898Sroland.mainz@nrubsig.orgthen	err_exit "eval '$cmd' failed -- expected '$exp', got '$got'"
44010898Sroland.mainz@nrubsig.orgfi
44110898Sroland.mainz@nrubsig.org
44210898Sroland.mainz@nrubsig.orgfloat t1=$SECONDS
44310898Sroland.mainz@nrubsig.orgsleep=$(whence -p sleep)
44410898Sroland.mainz@nrubsig.orgif	[[ $sleep ]]
44510898Sroland.mainz@nrubsig.orgthen
44610898Sroland.mainz@nrubsig.org	$SHELL -c "( $sleep 5 </dev/null >/dev/null 2>&1 & );exit 0" | cat
44710898Sroland.mainz@nrubsig.org	(( (SECONDS-t1) > 4 )) && err_exit '/bin/sleep& in subshell hanging'
44810898Sroland.mainz@nrubsig.org	((t1=SECONDS))
44910898Sroland.mainz@nrubsig.orgfi
45010898Sroland.mainz@nrubsig.org$SHELL -c '( sleep 5 </dev/null >/dev/null 2>&1 & );exit 0' | cat
45110898Sroland.mainz@nrubsig.org(( (SECONDS-t1) > 4 )) && err_exit 'sleep& in subshell hanging'
45210898Sroland.mainz@nrubsig.org
453*12068SRoger.Faulkner@Oracle.COMexp=HOME=$HOME
454*12068SRoger.Faulkner@Oracle.COM( HOME=/bin/sh )
455*12068SRoger.Faulkner@Oracle.COMgot=$(env | grep ^HOME=)
456*12068SRoger.Faulkner@Oracle.COM[[ $got == "$exp" ]] ||  err_exit "( HOME=/bin/sh ) cleanup failed -- expected '$exp', got '$got'"
457*12068SRoger.Faulkner@Oracle.COM
458*12068SRoger.Faulkner@Oracle.COMcmd='echo $((case x in x)echo ok;esac);:)'
459*12068SRoger.Faulkner@Oracle.COMexp=ok
460*12068SRoger.Faulkner@Oracle.COMgot=$($SHELL -c "$cmd" 2>&1)
461*12068SRoger.Faulkner@Oracle.COM[[ $got == "$exp" ]] ||  err_exit "'$cmd' failed -- expected '$exp', got '$got'"
462*12068SRoger.Faulkner@Oracle.COM
463*12068SRoger.Faulkner@Oracle.COMcmd='eval "for i in 1 2; do eval /bin/echo x; done"'
464*12068SRoger.Faulkner@Oracle.COMexp=$'x\nx'
465*12068SRoger.Faulkner@Oracle.COMgot=$($SHELL -c "$cmd")
466*12068SRoger.Faulkner@Oracle.COMif	[[ $got != "$exp" ]]
467*12068SRoger.Faulkner@Oracle.COMthen	EXP=$(printf %q "$exp")
468*12068SRoger.Faulkner@Oracle.COM	GOT=$(printf %q "$got")
469*12068SRoger.Faulkner@Oracle.COM	err_exit "'$cmd' failed -- expected $EXP, got $GOT"
470*12068SRoger.Faulkner@Oracle.COMfi
471*12068SRoger.Faulkner@Oracle.COM
4728462SApril.Chin@Sun.COMexit $Errors
473