xref: /onnv-gate/usr/src/lib/libshell/common/tests/builtins.sh (revision 12068:08a39a083754)
14887Schin########################################################################
24887Schin#                                                                      #
34887Schin#               This software is part of the ast package               #
4*12068SRoger.Faulkner@Oracle.COM#          Copyright (c) 1982-2010 AT&T Intellectual Property          #
54887Schin#                      and is licensed under the                       #
64887Schin#                  Common Public License, Version 1.0                  #
78462SApril.Chin@Sun.COM#                    by AT&T Intellectual Property                     #
84887Schin#                                                                      #
94887Schin#                A copy of the License is available at                 #
104887Schin#            http://www.opensource.org/licenses/cpl1.0.txt             #
114887Schin#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
124887Schin#                                                                      #
134887Schin#              Information and Software Systems Research               #
144887Schin#                            AT&T Research                             #
154887Schin#                           Florham Park NJ                            #
164887Schin#                                                                      #
174887Schin#                  David Korn <dgk@research.att.com>                   #
184887Schin#                                                                      #
194887Schin########################################################################
204887Schinfunction err_exit
214887Schin{
224887Schin	print -u2 -n "\t"
234887Schin	print -u2 -r ${Command}[$1]: "${@:2}"
244887Schin	let Errors+=1
254887Schin}
264887Schinalias err_exit='err_exit $LINENO'
274887Schin
284887SchinCommand=${0##*/}
294887Schininteger Errors=0
3010898Sroland.mainz@nrubsig.org
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.org# test shell builtin commands
354887Schinbuiltin getconf
364887Schin: ${foo=bar} || err_exit ": failed"
374887Schin[[ $foo = bar ]] || err_exit ": side effects failed"
384887Schinset -- - foobar
394887Schin[[ $# = 2 && $1 = - && $2 = foobar ]] || err_exit "set -- - foobar failed"
404887Schinset -- -x foobar
414887Schin[[ $# = 2 && $1 = -x && $2 = foobar ]] || err_exit "set -- -x foobar failed"
424887Schingetopts :x: foo || err_exit "getopts :x: returns false"
434887Schin[[ $foo = x && $OPTARG = foobar ]] || err_exit "getopts :x: failed"
444887SchinOPTIND=1
454887Schingetopts :r:s var -r
464887Schinif	[[ $var != : || $OPTARG != r ]]
474887Schinthen	err_exit "'getopts :r:s var -r' not working"
484887Schinfi
494887SchinOPTIND=1
508462SApril.Chin@Sun.COMgetopts :d#u OPT -d 16177
518462SApril.Chin@Sun.COMif	[[ $OPT != d || $OPTARG != 16177 ]]
528462SApril.Chin@Sun.COMthen	err_exit "'getopts :d#u OPT=d OPTARG=16177' failed -- OPT=$OPT OPTARG=$OPTARG"
534887Schinfi
544887SchinOPTIND=1
554887Schinwhile getopts 'ab' option -a -b
564887Schindo	[[ $OPTIND == $((OPTIND)) ]] || err_exit "OPTIND optimization bug"
574887Schindone
584887Schin
594887SchinUSAGE=$'[-][S:server?Operate on the specified \asubservice\a:]:[subservice:=pmserver]
604887Schin    {
614887Schin        [p:pmserver]
624887Schin        [r:repserver]
634887Schin        [11:notifyd]
644887Schin    }'
654887Schinset pmser p rep r notifyd -11
664887Schinwhile	(( $# > 1 ))
674887Schindo	OPTIND=1
684887Schin	getopts "$USAGE" OPT -S $1
694887Schin	[[ $OPT == S && $OPTARG == $2 ]] || err_exit "OPT=$OPT OPTARG=$OPTARG -- expected OPT=S OPTARG=$2"
704887Schin	shift 2
714887Schindone
724887Schin
734887Schinfalse ${foo=bar} &&  err_exit "false failed"
744887Schinread <<!
754887Schinhello world
764887Schin!
774887Schin[[ $REPLY = 'hello world' ]] || err_exit "read builtin failed"
784887Schinprint x:y | IFS=: read a b
794887Schinif	[[ $a != x ]]
804887Schinthen	err_exit "IFS=: read ... not working"
814887Schinfi
824887Schinread <<!
834887Schinhello \
844887Schinworld
854887Schin!
864887Schin[[ $REPLY = 'hello world' ]] || err_exit "read continuation failed"
874887Schinread -d x <<!
884887Schinhello worldxfoobar
894887Schin!
904887Schin[[ $REPLY = 'hello world' ]] || err_exit "read builtin failed"
914887Schinread <<\!
924887Schinhello \
934887Schin	world \
944887Schin
954887Schin!
964887Schin[[ $REPLY == 'hello 	world' ]] || err_exit "read continuation2 failed"
974887Schinprint "one\ntwo" | { read line
984887Schin	print $line | /bin/cat > /dev/null
994887Schin	read line
1004887Schin}
1014887Schinread <<\!
1024887Schin\
1034887Schina\
1044887Schin\
1054887Schin\
1064887Schinb
1074887Schin!
1084887Schinif	[[ $REPLY != ab ]]
1094887Schinthen	err_exit "read multiple continuation failed"
1104887Schinfi
1114887Schinif	[[ $line != two ]]
1124887Schinthen	err_exit "read from pipeline failed"
1134887Schinfi
1144887Schinline=two
1154887Schinread line < /dev/null
1164887Schinif	[[ $line != "" ]]
1174887Schinthen	err_exit "read from /dev/null failed"
1184887Schinfi
1194887Schinif	[[ $(print -R -) != - ]]
1204887Schinthen	err_exit "print -R not working correctly"
1214887Schinfi
1224887Schinif	[[ $(print -- -) != - ]]
1234887Schinthen	err_exit "print -- not working correctly"
1244887Schinfi
1254887Schinprint -f "hello%nbar\n" size > /dev/null
1264887Schinif	((	size != 5 ))
1274887Schinthen	err_exit "%n format of printf not working"
1284887Schinfi
1294887Schinprint -n -u2 2>&1-
1304887Schin[[ -w /dev/fd/1 ]] || err_exit "2<&1- with built-ins has side effects"
1314887Schinx=$0
1324887Schinif	[[ $(eval 'print $0') != $x ]]
1334887Schinthen	err_exit '$0 not correct for eval'
1344887Schinfi
1358462SApril.Chin@Sun.COM$SHELL -c 'read x <<< hello' 2> /dev/null || err_exit 'syntax <<< not recognized'
1368462SApril.Chin@Sun.COM($SHELL -c 'read x[1] <<< hello') 2> /dev/null || err_exit 'read x[1] not working'
1374887Schinunset x
1384887Schinreadonly x
1394887Schinset -- $(readonly)
1404887Schinif      [[ " $@ " != *" x "* ]]
1414887Schinthen    err_exit 'unset readonly variables are not displayed'
1424887Schinfi
1434887Schinif	[[ $(	for i in foo bar
1444887Schin		do	print $i
1454887Schin			continue 10
1464887Schin		done
1474887Schin	    ) != $'foo\nbar' ]]
1484887Schinthen	err_exit 'continue breaks out of loop'
1494887Schinfi
1504887Schin(continue bad 2>/dev/null && err_exit 'continue bad should return an error')
1514887Schin(break bad 2>/dev/null && err_exit 'break bad should return an error')
1524887Schin(continue 0 2>/dev/null && err_exit 'continue 0 should return an error')
1534887Schin(break 0 2>/dev/null && err_exit 'break 0 should return an error')
1544887Schinbreakfun() { break;}
1554887Schincontinuefun() { continue;}
1564887Schinfor fun in break continue
1574887Schindo	if	[[ $(	for i in foo
1584887Schin			do	${fun}fun
1594887Schin				print $i
1604887Schin			done
1614887Schin		) != foo ]]
1624887Schin	then	err_exit "$fun call in ${fun}fun breaks out of for loop"
1634887Schin	fi
1644887Schindone
1654887Schinif	[[ $(print -f "%b" "\a\n\v\b\r\f\E\03\\oo") != $'\a\n\v\b\r\f\E\03\\oo' ]]
1664887Schinthen	err_exit 'print -f "%b" not working'
1674887Schinfi
1688462SApril.Chin@Sun.COMif	[[ $(print -f "%P" "[^x].*b\$") != '*[!x]*b' ]]
1694887Schinthen	err_exit 'print -f "%P" not working'
1704887Schinfi
1714887Schinif	[[ $(abc: for i in foo bar;do print $i;break abc;done) != foo ]]
1724887Schinthen	err_exit 'break labels not working'
1734887Schinfi
1744887Schinif	[[ $(command -v if)	!= if ]]
1754887Schinthen	err_exit	'command -v not working'
1764887Schinfi
1774887Schinread -r var <<\!
17810898Sroland.mainz@nrubsig.org
1794887Schin!
1804887Schinif	[[ $var != "" ]]
1814887Schinthen	err_exit "read -r of blank line not working"
1824887Schinfi
18310898Sroland.mainz@nrubsig.orgmkdir -p $tmp/a/b/c 2>/dev/null || err_exit  "mkdir -p failed"
18410898Sroland.mainz@nrubsig.org$SHELL -c "cd $tmp/a/b; cd c" 2>/dev/null || err_exit "initial script relative cd fails"
18510898Sroland.mainz@nrubsig.org
18610898Sroland.mainz@nrubsig.orgtrap 'print TERM' TERM
18710898Sroland.mainz@nrubsig.orgexp=$'trap -- \'print TERM\' TERM\ntrap -- \'cd /; rm -rf '$tmp$'\' EXIT'
18810898Sroland.mainz@nrubsig.orggot=$(trap)
18910898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "\$(trap) failed -- expected \"$exp\", got \"$got\""
19010898Sroland.mainz@nrubsig.orgexp='print TERM'
19110898Sroland.mainz@nrubsig.orggot=$(trap -p TERM)
19210898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "\$(trap -p TERM) failed -- expected \"$exp\", got \"$got\""
19310898Sroland.mainz@nrubsig.org
1948462SApril.Chin@Sun.COM[[ $($SHELL -c 'trap "print ok" SIGTERM; kill -s SIGTERM $$' 2> /dev/null) == ok ]] || err_exit 'SIGTERM not recognized'
1958462SApril.Chin@Sun.COM[[ $($SHELL -c 'trap "print ok" sigterm; kill -s sigterm $$' 2> /dev/null) == ok ]] || err_exit 'SIGTERM not recognized'
1968462SApril.Chin@Sun.COM[[ $($SHELL -c '( trap "" TERM);kill $$;print bad' == bad) ]] 2> /dev/null && err_exit 'trap ignored in subshell causes it to be ignored by parent'
1974887Schin${SHELL} -c 'kill -1 -$$' 2> /dev/null
19810898Sroland.mainz@nrubsig.org[[ $(kill -l $?) == HUP ]] || err_exit 'kill -1 -pid not working'
1994887Schin${SHELL} -c 'kill -1 -$$' 2> /dev/null
20010898Sroland.mainz@nrubsig.org[[ $(kill -l $?) == HUP ]] || err_exit 'kill -n1 -pid not working'
2014887Schin${SHELL} -c 'kill -s HUP -$$' 2> /dev/null
20210898Sroland.mainz@nrubsig.org[[ $(kill -l $?) == HUP ]] || err_exit 'kill -HUP -pid not working'
2034887Schinn=123
2044887Schintypeset -A base
2054887Schinbase[o]=8#
2064887Schinbase[x]=16#
2074887Schinbase[X]=16#
2084887Schinfor i in d i o u x X
2094887Schindo	if	(( $(( ${base[$i]}$(printf "%$i" $n) )) != n  ))
2104887Schin	then	err_exit "printf %$i not working"
2114887Schin	fi
2124887Schindone
2134887Schinif	[[ $( trap 'print done' EXIT) != done ]]
2144887Schinthen	err_exit 'trap on EXIT not working'
2154887Schinfi
2164887Schinif	[[ $( trap 'print done' EXIT; trap - EXIT) == done ]]
2174887Schinthen	err_exit 'trap on EXIT not being cleared'
2184887Schinfi
2194887Schinif	[[ $(type test) != 'test is a shell builtin' ]]
2204887Schinthen	err_exit 'whence -v test not a builtin'
2214887Schinfi
2224887Schinbuiltin -d test
2234887Schinif	[[ $(type test) == *builtin* ]]
2244887Schinthen	err_exit 'whence -v test after builtin -d incorrect'
2254887Schinfi
2264887Schintypeset -Z3 percent=$(printf '%o\n' "'%'")
2274887Schinforrmat=\\${percent}s
2284887Schinif      [[ $(printf "$forrmat") != %s ]]
2294887Schinthen    err_exit "printf $forrmat not working"
2304887Schinfi
2314887Schinif	(( $(printf 'x\0y' | wc -c) != 3 ))
2324887Schinthen	err_exit 'printf \0 not working'
2334887Schinfi
2344887Schinif	[[ $(printf "%bx%s\n" 'f\to\cbar') != $'f\to' ]]
2354887Schinthen	err_exit 'printf %bx%s\n  not working'
2364887Schinfi
2374887Schinalpha=abcdefghijklmnop
2384887Schinif	[[ $(printf "%10.*s\n" 5 $alpha) != '     abcde' ]]
2394887Schinthen	err_exit 'printf %10.%s\n  not working'
2404887Schinfi
2414887Schinfloat x2=.0000625
2424887Schinif	[[ $(printf "%10.5E\n" x2) != 6.25000E-05 ]]
2434887Schinthen	err_exit 'printf "%10.5E" not normalizing correctly'
2444887Schinfi
2454887Schinx2=.000000001
2464887Schinif	[[ $(printf "%g\n" x2 2>/dev/null) != 1e-09 ]]
2474887Schinthen	err_exit 'printf "%g" not working correctly'
2484887Schinfi
2494887Schin#FIXME#($SHELL read -s foobar <<\!
2504887Schin#FIXME#testing
2514887Schin#FIXME#!
2524887Schin#FIXME#) 2> /dev/null || err_exit ksh read -s var fails
2534887Schinif	[[ $(printf +3 2>/dev/null) !=   +3 ]]
2544887Schinthen	err_exit 'printf is not processing formats beginning with + correctly'
2554887Schinfi
2564887Schinif	printf "%d %d\n" 123bad 78 >/dev/null 2>/dev/null
2574887Schinthen	err_exit "printf not exiting non-zero with conversion errors"
2584887Schinfi
2594887Schinif	[[ $(trap --version 2> /dev/null;print done) != done ]]
2604887Schinthen	err_exit 'trap builtin terminating after --version'
2614887Schinfi
2624887Schinif	[[ $(set --version 2> /dev/null;print done) != done ]]
2634887Schinthen	err_exit 'set builtin terminating after --veresion'
2644887Schinfi
2654887Schinunset -f foobar
2664887Schinfunction foobar
2674887Schin{
2684887Schin	print 'hello world'
2694887Schin}
2704887SchinOPTIND=1
2714887Schinif	[[ $(getopts  $'[+?X\ffoobar\fX]' v --man 2>&1) != *'Xhello world'X* ]]
2724887Schinthen	err_exit '\f...\f not working in getopts usage strings'
2734887Schinfi
27410898Sroland.mainz@nrubsig.orgif	[[ $(printf '%H\n' $'<>"& \'\tabc') != '&lt;&gt;&quot;&amp;&nbsp;&apos;&#9;abc' ]]
2754887Schinthen	err_exit 'printf %H not working'
2764887Schinfi
27710898Sroland.mainz@nrubsig.orgif	[[ $(printf '%R %R %R %R\n' 'a.b' '*.c' '^'  '!(*.*)') != '^a\.b$ \.c$ ^\^$ ^(.*\..*)!$' ]]
2784887Schinthen	err_exit 'printf %R not working'
2794887Schinfi
2804887Schinif	[[ $(printf '%..:c\n' abc) != a:b:c ]]
28110898Sroland.mainz@nrubsig.orgthen	err_exit "printf '%..:c' not working"
2824887Schinfi
2834887Schinif	[[ $(printf '%..*c\n' : abc) != a:b:c ]]
28410898Sroland.mainz@nrubsig.orgthen	err_exit "printf '%..*c' not working"
2854887Schinfi
2864887Schinif	[[ $(printf '%..:s\n' abc def ) != abc:def ]]
28710898Sroland.mainz@nrubsig.orgthen	err_exit "printf '%..:s' not working"
2884887Schinfi
2894887Schinif	[[ $(printf '%..*s\n' : abc def) != abc:def ]]
29010898Sroland.mainz@nrubsig.orgthen	err_exit "printf '%..*s' not working"
2914887Schinfi
2924887Schin[[ $(printf '%q\n') == '' ]] || err_exit 'printf "%q" with missing arguments'
2934887Schin# we won't get hit by the one second boundary twice, right?
2944887Schin[[ $(printf '%T\n' now) == "$(date)" ]] ||
2954887Schin[[ $(printf '%T\n' now) == "$(date)" ]] ||
2964887Schinerr_exit 'printf "%T" now'
2974887Schinbehead()
2984887Schin{
2994887Schin	read line
3004887Schin	left=$(cat)
3014887Schin}
3024887Schinprint $'line1\nline2' | behead
3034887Schinif	[[ $left != line2 ]]
30410898Sroland.mainz@nrubsig.orgthen	err_exit "read reading ahead on a pipe"
3054887Schinfi
30610898Sroland.mainz@nrubsig.orgread -n1 y <<!
30710898Sroland.mainz@nrubsig.orgabc
30810898Sroland.mainz@nrubsig.org!
30910898Sroland.mainz@nrubsig.orgexp=a
31010898Sroland.mainz@nrubsig.orgif      [[ $y != $exp ]]
31110898Sroland.mainz@nrubsig.orgthen    err_exit "read -n1 failed -- expected '$exp', got '$y'"
31210898Sroland.mainz@nrubsig.orgfi
31310898Sroland.mainz@nrubsig.orgprint -n $'{ read -r line;print $line;}\nhello' > $tmp/script
31410898Sroland.mainz@nrubsig.orgchmod 755 $tmp/script
31510898Sroland.mainz@nrubsig.orgif	[[ $($SHELL < $tmp/script) != hello ]]
3164887Schinthen	err_exit 'read of incomplete line not working correctly'
3174887Schinfi
3184887Schinset -f
3194887Schinset -- *
3204887Schinif      [[ $1 != '*' ]]
3214887Schinthen    err_exit 'set -f not working'
3224887Schinfi
3234887Schinunset pid1 pid2
3244887Schinfalse &
3254887Schinpid1=$!
3264887Schinpid2=$(
3274887Schin	wait $pid1
3284887Schin	(( $? == 127 )) || err_exit "job known to subshell"
3294887Schin	print $!
3304887Schin)
3314887Schinwait $pid1
3324887Schin(( $? == 1 )) || err_exit "wait not saving exit value"
3334887Schinwait $pid2
3344887Schin(( $? == 127 )) || err_exit "subshell job known to parent"
3354887Schinenv=
33610898Sroland.mainz@nrubsig.orgv=$(getconf LIBPATH)
33710898Sroland.mainz@nrubsig.orgfor v in ${v//,/ }
33810898Sroland.mainz@nrubsig.orgdo	v=${v#*:}
33910898Sroland.mainz@nrubsig.org	v=${v%%:*}
34010898Sroland.mainz@nrubsig.org	eval [[ \$$v ]] && env="$env $v=\"\$$v\""
3414887Schindone
3424887Schinif	[[ $(foo=bar; eval foo=\$foo $env exec -c \$SHELL -c \'print \$foo\') != bar ]]
3434887Schinthen	err_exit '"name=value exec -c ..." not working'
3444887Schinfi
3454887Schin$SHELL -c 'OPTIND=-1000000; getopts a opt -a' 2> /dev/null
3464887Schin[[ $? == 1 ]] || err_exit 'getopts with negative OPTIND not working'
3474887Schingetopts 'n#num' opt  -n 3
3484887Schin[[ $OPTARG == 3 ]] || err_exit 'getopts with numerical arguments failed'
3494887Schinif	[[ $($SHELL -c $'printf \'%2$s %1$s\n\' world hello') != 'hello world' ]]
3504887Schinthen	err_exit 'printf %2$s %1$s not working'
3514887Schinfi
3528462SApril.Chin@Sun.COMval=$(( 'C' ))
3538462SApril.Chin@Sun.COMset -- \
3548462SApril.Chin@Sun.COM	"'C"	$val	0	\
3558462SApril.Chin@Sun.COM	"'C'"	$val	0	\
3568462SApril.Chin@Sun.COM	'"C'	$val	0	\
3578462SApril.Chin@Sun.COM	'"C"'	$val	0	\
3588462SApril.Chin@Sun.COM	"'CX"	$val	1	\
3598462SApril.Chin@Sun.COM	"'CX'"	$val	1	\
3608462SApril.Chin@Sun.COM	"'C'X"	$val	1	\
3618462SApril.Chin@Sun.COM	'"CX'	$val	1	\
3628462SApril.Chin@Sun.COM	'"CX"'	$val	1	\
3638462SApril.Chin@Sun.COM	'"C"X'	$val	1
3648462SApril.Chin@Sun.COMwhile (( $# >= 3 ))
3658462SApril.Chin@Sun.COMdo	arg=$1 val=$2 code=$3
3668462SApril.Chin@Sun.COM	shift 3
3678462SApril.Chin@Sun.COM	for fmt in '%d' '%g'
3688462SApril.Chin@Sun.COM	do	out=$(printf "$fmt" "$arg" 2>/dev/null)
3698462SApril.Chin@Sun.COM		err=$(printf "$fmt" "$arg" 2>&1 >/dev/null)
3708462SApril.Chin@Sun.COM		printf "$fmt" "$arg" >/dev/null 2>&1
3718462SApril.Chin@Sun.COM		ret=$?
37210898Sroland.mainz@nrubsig.org		[[ $out == $val ]] || err_exit "printf $fmt $arg failed -- expected '$val', got '$out'"
3738462SApril.Chin@Sun.COM		if	(( $code ))
3748462SApril.Chin@Sun.COM		then	[[ $err ]] || err_exit "printf $fmt $arg failed, error message expected"
3758462SApril.Chin@Sun.COM		else	[[ $err ]] && err_exit "$err: printf $fmt $arg failed, error message not expected -- got '$err'"
3768462SApril.Chin@Sun.COM		fi
3778462SApril.Chin@Sun.COM		(( $ret == $code )) || err_exit "printf $fmt $arg failed -- expected exit code $code, got $ret"
3788462SApril.Chin@Sun.COM	done
3798462SApril.Chin@Sun.COMdone
3804887Schin((n=0))
3814887Schin((n++)); ARGC[$n]=1 ARGV[$n]=""
3824887Schin((n++)); ARGC[$n]=2 ARGV[$n]="-a"
3834887Schin((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2"
3844887Schin((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2 x"
3854887Schin((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2 x y"
3864887Schinfor ((i=1; i<=n; i++))
3874887Schindo	set -- ${ARGV[$i]}
3884887Schin	OPTIND=0
3894887Schin	while	getopts -a tst "av:" OPT
3904887Schin	do	:
3914887Schin	done
3924887Schin	if	[[ $OPTIND != ${ARGC[$i]} ]]
3938462SApril.Chin@Sun.COM	then	err_exit "\$OPTIND after getopts loop incorrect -- expected ${ARGC[$i]}, got $OPTIND"
3944887Schin	fi
3954887Schindone
3968462SApril.Chin@Sun.COMoptions=ab:c
3978462SApril.Chin@Sun.COMoptarg=foo
3988462SApril.Chin@Sun.COMset -- -a -b $optarg -c bar
3998462SApril.Chin@Sun.COMwhile	getopts $options opt
4008462SApril.Chin@Sun.COMdo	case $opt in
4018462SApril.Chin@Sun.COM	a|c)	[[ $OPTARG ]] && err_exit "getopts $options \$OPTARG for flag $opt failed, expected \"\", got \"$OPTARG\"" ;;
4028462SApril.Chin@Sun.COM	b)	[[ $OPTARG == $optarg ]] || err_exit "getopts $options \$OPTARG failed -- \"$optarg\" expected, got \"$OPTARG\"" ;;
4038462SApril.Chin@Sun.COM	*)	err_exit "getopts $options failed -- got flag $opt" ;;
4048462SApril.Chin@Sun.COM	esac
4058462SApril.Chin@Sun.COMdone
40610898Sroland.mainz@nrubsig.org
40710898Sroland.mainz@nrubsig.orgunset a
40810898Sroland.mainz@nrubsig.org{ read -N3 a; read -N1 b;}  <<!
40910898Sroland.mainz@nrubsig.orgabcdefg
41010898Sroland.mainz@nrubsig.org!
41110898Sroland.mainz@nrubsig.orgexp=abc
41210898Sroland.mainz@nrubsig.org[[ $a == $exp ]] || err_exit "read -N3 here-document failed -- expected '$exp', got '$a'"
41310898Sroland.mainz@nrubsig.orgexp=d
41410898Sroland.mainz@nrubsig.org[[ $b == $exp ]] || err_exit "read -N1 here-document failed -- expected '$exp', got '$b'"
41510898Sroland.mainz@nrubsig.orgread -n3 a <<!
41610898Sroland.mainz@nrubsig.orgabcdefg
41710898Sroland.mainz@nrubsig.org!
41810898Sroland.mainz@nrubsig.orgexp=abc
41910898Sroland.mainz@nrubsig.org[[ $a == $exp ]] || err_exit "read -n3 here-document failed -- expected '$exp', got '$a'"
42010898Sroland.mainz@nrubsig.org#(print -n a;sleep 1; print -n bcde) | { read -N3 a; read -N1 b;}
42110898Sroland.mainz@nrubsig.org#[[ $a == $exp ]] || err_exit "read -N3 from pipe failed -- expected '$exp', got '$a'"
42210898Sroland.mainz@nrubsig.org#exp=d
42310898Sroland.mainz@nrubsig.org#[[ $b == $exp ]] || err_exit "read -N1 from pipe failed -- expected '$exp', got '$b'"
42410898Sroland.mainz@nrubsig.org#(print -n a;sleep 1; print -n bcde) | read -n3 a
42510898Sroland.mainz@nrubsig.org#exp=a
42610898Sroland.mainz@nrubsig.org#[[ $a == $exp ]] || err_exit "read -n3 from pipe failed -- expected '$exp', got '$a'"
42710898Sroland.mainz@nrubsig.org#rm -f $tmp/fifo
42810898Sroland.mainz@nrubsig.org#if	mkfifo $tmp/fifo 2> /dev/null
42910898Sroland.mainz@nrubsig.org#then	(print -n a; sleep 1;print -n bcde)  > $tmp/fifo &
43010898Sroland.mainz@nrubsig.org#	{
43110898Sroland.mainz@nrubsig.org#	read -u5 -n3 -t2 a || err_exit 'read -n3 from fifo timedout'
43210898Sroland.mainz@nrubsig.org#	read -u5 -n1 -t2 b || err_exit 'read -n1 from fifo timedout'
43310898Sroland.mainz@nrubsig.org#	} 5< $tmp/fifo
43410898Sroland.mainz@nrubsig.org#	exp=a
43510898Sroland.mainz@nrubsig.org#	[[ $a == $exp ]] || err_exit "read -n3 from fifo failed -- expected '$exp', got '$a'"
43610898Sroland.mainz@nrubsig.org#	rm -f $tmp/fifo
43710898Sroland.mainz@nrubsig.org#	mkfifo $tmp/fifo 2> /dev/null
43810898Sroland.mainz@nrubsig.org#	(print -n a; sleep 1;print -n bcde) > $tmp/fifo &
43910898Sroland.mainz@nrubsig.org#	{
44010898Sroland.mainz@nrubsig.org#	read -u5 -N3 -t2 a || err_exit 'read -N3 from fifo timed out'
44110898Sroland.mainz@nrubsig.org#	read -u5 -N1 -t2 b || err_exit 'read -N1 from fifo timedout'
44210898Sroland.mainz@nrubsig.org#	} 5< $tmp/fifo
44310898Sroland.mainz@nrubsig.org#	exp=abc
44410898Sroland.mainz@nrubsig.org#	[[ $a == $exp ]] || err_exit "read -N3 from fifo failed -- expected '$exp', got '$a'"
44510898Sroland.mainz@nrubsig.org#	exp=d
44610898Sroland.mainz@nrubsig.org#	[[ $b == $exp ]] || err_exit "read -N1 from fifo failed -- expected '$exp', got '$b'"
44710898Sroland.mainz@nrubsig.org#fi
44810898Sroland.mainz@nrubsig.org#rm -f $tmp/fifo
44910898Sroland.mainz@nrubsig.org
4504887Schinfunction longline
4514887Schin{
4524887Schin	integer i
4534887Schin	for((i=0; i < $1; i++))
4544887Schin	do	print argument$i
4554887Schin	done
4564887Schin}
4574887Schin# test command -x option
4584887Schininteger sum=0 n=10000
4594887Schinif	! ${SHELL:-ksh} -c 'print $#' count $(longline $n) > /dev/null  2>&1
4604887Schinthen	for i in $(command command -x ${SHELL:-ksh} -c 'print $#;[[ $1 != argument0 ]]' count $(longline $n) 2> /dev/null)
4614887Schin	do	((sum += $i))
4624887Schin	done
4634887Schin	(( sum == n )) || err_exit "command -x processed only $sum arguments"
4644887Schin	command -p command -x ${SHELL:-ksh} -c 'print $#;[[ $1 == argument0 ]]' count $(longline $n) > /dev/null  2>&1
4654887Schin	[[ $? != 1 ]] && err_exit 'incorrect exit status for command -x'
4664887Schinfi
4674887Schin# test command -x option with extra arguments
4684887Schininteger sum=0 n=10000
4694887Schinif      ! ${SHELL:-ksh} -c 'print $#' count $(longline $n) > /dev/null  2>&1
4704887Schinthen    for i in $(command command -x ${SHELL:-ksh} -c 'print $#;[[ $1 != argument0 ]]' count $(longline $n) one two three) #2> /dev/null)
4714887Schin	do      ((sum += $i))
4724887Schin	done
4734887Schin	(( sum  > n )) || err_exit "command -x processed only $sum arguments"
4744887Schin	(( (sum-n)%3==0 )) || err_exit "command -x processed only $sum arguments"
4754887Schin	(( sum == n+3)) && err_exit "command -x processed only $sum arguments"
4764887Schin	command -p command -x ${SHELL:-ksh} -c 'print $#;[[ $1 == argument0 ]]' count $(longline $n) > /dev/null  2>&1
4774887Schin	[[ $? != 1 ]] && err_exit 'incorrect exit status for command -x'
4784887Schinfi
4794887Schin# test for debug trap
4804887Schin[[ $(typeset -i i=0
4814887Schin	trap 'print $i' DEBUG
4824887Schin	while (( i <2))
4834887Schin	do	(( i++))
4844887Schin	done) == $'0\n0\n1\n1\n2' ]]  || err_exit  "DEBUG trap not working"
4854887Schingetconf UNIVERSE - ucb
4864887Schin[[ $($SHELL -c 'echo -3') == -3 ]] || err_exit "echo -3 not working in ucb universe"
4874887Schintypeset -F3 start_x=SECONDS total_t delay=0.02
4884887Schintypeset reps=50 leeway=5
48910898Sroland.mainz@nrubsig.org#sleep $(( 2 * leeway * reps * delay )) |
49010898Sroland.mainz@nrubsig.org#for (( i=0 ; i < reps ; i++ ))
49110898Sroland.mainz@nrubsig.org#do	read -N1 -t $delay
49210898Sroland.mainz@nrubsig.org#done
49310898Sroland.mainz@nrubsig.org#(( total_t = SECONDS - start_x ))
49410898Sroland.mainz@nrubsig.org#if	(( total_t > leeway * reps * delay ))
49510898Sroland.mainz@nrubsig.org#then	err_exit "read -t in pipe taking $total_t secs - $(( reps * delay )) minimum - too long"
49610898Sroland.mainz@nrubsig.org#elif	(( total_t < reps * delay ))
49710898Sroland.mainz@nrubsig.org#then	err_exit "read -t in pipe taking $total_t secs - $(( reps * delay )) minimum - too fast"
49810898Sroland.mainz@nrubsig.org#fi
49910898Sroland.mainz@nrubsig.org#$SHELL -c 'sleep $(printf "%a" .95)' 2> /dev/null || err_exit "sleep doesn't except %a format constants"
50010898Sroland.mainz@nrubsig.org#$SHELL -c 'test \( ! -e \)' 2> /dev/null ; [[ $? == 1 ]] || err_exit 'test \( ! -e \) not working'
5018462SApril.Chin@Sun.COM[[ $(ulimit) == "$(ulimit -fS)" ]] || err_exit 'ulimit is not the same as ulimit -fS'
50210898Sroland.mainz@nrubsig.orgtmpfile=$tmp/file.2
5038462SApril.Chin@Sun.COMprint $'\nprint -r -- "${.sh.file} ${LINENO} ${.sh.lineno}"' > $tmpfile
5048462SApril.Chin@Sun.COM[[ $( . "$tmpfile") == "$tmpfile 2 1" ]] || err_exit 'dot command not working'
5058462SApril.Chin@Sun.COMprint -r -- "'xxx" > $tmpfile
5068462SApril.Chin@Sun.COM[[ $($SHELL -c ". $tmpfile"$'\n print ok' 2> /dev/null) == ok ]] || err_exit 'syntax error in dot command affects next command'
5078462SApril.Chin@Sun.COM
50810898Sroland.mainz@nrubsig.org#float sec=$SECONDS del=4
50910898Sroland.mainz@nrubsig.org#exec 3>&2 2>/dev/null
51010898Sroland.mainz@nrubsig.org#$SHELL -c "( sleep 1; kill -ALRM \$\$ ) & sleep $del" 2> /dev/null
51110898Sroland.mainz@nrubsig.org#exitval=$?
51210898Sroland.mainz@nrubsig.org#(( sec = SECONDS - sec ))
51310898Sroland.mainz@nrubsig.org#exec 2>&3-
51410898Sroland.mainz@nrubsig.org#(( exitval )) && err_exit "sleep doesn't exit 0 with ALRM interupt"
51510898Sroland.mainz@nrubsig.org#(( sec > (del - 1) )) || err_exit "ALRM signal causes sleep to terminate prematurely -- expected 3 sec, got $sec"
51610898Sroland.mainz@nrubsig.orgtypeset -r z=3
51710898Sroland.mainz@nrubsig.orgy=5
51810898Sroland.mainz@nrubsig.orgfor i in 123 z  %x a.b.c
51910898Sroland.mainz@nrubsig.orgdo	( unset $i)  2>/dev/null && err_exit "unset $i should fail"
52010898Sroland.mainz@nrubsig.orgdone
52110898Sroland.mainz@nrubsig.orga=()
52210898Sroland.mainz@nrubsig.orgfor i in y y  y[8] t[abc] y.d a.b  a
52310898Sroland.mainz@nrubsig.orgdo	unset $i ||  print -u2  "err_exit unset $i should not fail"
52410898Sroland.mainz@nrubsig.orgdone
52510898Sroland.mainz@nrubsig.org[[ $($SHELL -c 'y=3; unset 123 y;print $?$y') == 1 ]] 2> /dev/null ||  err_exit 'y is not getting unset with unset 123 y'
52610898Sroland.mainz@nrubsig.org[[ $($SHELL -c 'trap foo TERM; (trap;(trap) )') == 'trap -- foo TERM' ]] || err_exit 'traps not getting reset when subshell is last process'
5278462SApril.Chin@Sun.COM
5284887Schinexit $((Errors))
529