Blame src/cmd/ksh93/tests/basic.sh

Packit Service a8c26c
########################################################################
Packit Service a8c26c
#                                                                      #
Packit Service a8c26c
#               This software is part of the ast package               #
Packit Service a8c26c
#          Copyright (c) 1982-2012 AT&T Intellectual Property          #
Packit Service a8c26c
#                      and is licensed under the                       #
Packit Service a8c26c
#                 Eclipse Public License, Version 1.0                  #
Packit Service a8c26c
#                    by AT&T Intellectual Property                     #
Packit Service a8c26c
#                                                                      #
Packit Service a8c26c
#                A copy of the License is available at                 #
Packit Service a8c26c
#          http://www.eclipse.org/org/documents/epl-v10.html           #
Packit Service a8c26c
#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
Packit Service a8c26c
#                                                                      #
Packit Service a8c26c
#              Information and Software Systems Research               #
Packit Service a8c26c
#                            AT&T Research                             #
Packit Service a8c26c
#                           Florham Park NJ                            #
Packit Service a8c26c
#                                                                      #
Packit Service a8c26c
#                  David Korn <dgk@research.att.com>                   #
Packit Service a8c26c
#                                                                      #
Packit Service a8c26c
########################################################################
Packit Service a8c26c
function err_exit
Packit Service a8c26c
{
Packit Service a8c26c
	print -u2 -n "\t"
Packit Service a8c26c
	print -u2 -r ${Command}[$1]: "${@:2}"
Packit Service a8c26c
	let Errors+=1
Packit Service a8c26c
}
Packit Service a8c26c
alias err_exit='err_exit $LINENO'
Packit Service a8c26c
Packit Service a8c26c
Command=${0##*/}
Packit Service a8c26c
integer Errors=0
Packit Service a8c26c
Packit Service a8c26c
tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
Packit Service a8c26c
trap "cd /; rm -rf $tmp" EXIT
Packit Service a8c26c
Packit Service a8c26c
# test basic file operations like redirection, pipes, file expansion
Packit Service a8c26c
set -- \
Packit Service a8c26c
	go+r	0000	\
Packit Service a8c26c
	go-r	0044	\
Packit Service a8c26c
	ug=r	0330	\
Packit Service a8c26c
	go+w	0000	\
Packit Service a8c26c
	go-w	0022	\
Packit Service a8c26c
	ug=w	0550	\
Packit Service a8c26c
	go+x	0000	\
Packit Service a8c26c
	go-x	0011	\
Packit Service a8c26c
	ug=x	0660	\
Packit Service a8c26c
	go-rx	0055	\
Packit Service a8c26c
	uo-wx	0303	\
Packit Service a8c26c
	ug-rw	0660	\
Packit Service a8c26c
	o=	0007
Packit Service a8c26c
while	(( $# >= 2 ))
Packit Service a8c26c
do	umask 0
Packit Service a8c26c
	umask $1
Packit Service a8c26c
	g=$(umask)
Packit Service a8c26c
	[[ $g == $2 ]] || err_exit "umask 0; umask $1 failed -- expected $2, got $g"
Packit Service a8c26c
	shift 2
Packit Service a8c26c
done
Packit Service a8c26c
umask u=rwx,go=rx || err_exit "umask u=rws,go=rx failed"
Packit Service a8c26c
if	[[ $(umask -S) != u=rwx,g=rx,o=rx ]]
Packit Service a8c26c
then	err_exit 'umask -S incorrect'
Packit Service a8c26c
fi
Packit Service a8c26c
pwd=$PWD
Packit Service a8c26c
[[ $SHELL != /* ]] && SHELL=$pwd/$SHELL
Packit Service a8c26c
cd $tmp || { err_exit "cd $tmp failed"; exit 1; }
Packit Service a8c26c
um=$(umask -S)
Packit Service a8c26c
( umask 0777; > foobar )
Packit Service a8c26c
rm -f foobar
Packit Service a8c26c
> foobar
Packit Service a8c26c
[[ -r foobar ]] || err_exit 'umask not being restored after subshell'
Packit Service a8c26c
umask "$um"
Packit Service a8c26c
rm -f foobar
Packit Service a8c26c
# optimizer bug test
Packit Service a8c26c
> foobar
Packit Service a8c26c
for i in 1 2
Packit Service a8c26c
do      print foobar*
Packit Service a8c26c
        rm -f foobar
Packit Service a8c26c
done > out
Packit Service a8c26c
if      [[ "$(
Packit Service a8c26c
then    print -u2 "optimizer bug with file expansion"
Packit Service a8c26c
fi
Packit Service a8c26c
rm -f out foobar
Packit Service a8c26c
mkdir dir
Packit Service a8c26c
if	[[ $(print */) != dir/ ]]
Packit Service a8c26c
then	err_exit 'file expansion with trailing / not working'
Packit Service a8c26c
fi
Packit Service a8c26c
if	[[ $(print *) != dir ]]
Packit Service a8c26c
then	err_exit 'file expansion with single file not working'
Packit Service a8c26c
fi
Packit Service a8c26c
print hi > .foo
Packit Service a8c26c
if	[[ $(print *) != dir ]]
Packit Service a8c26c
then	err_exit 'file expansion leading . not working'
Packit Service a8c26c
fi
Packit Service a8c26c
date > dat1 || err_exit "date > dat1 failed"
Packit Service a8c26c
test -r dat1 || err_exit "dat1 is not readable"
Packit Service a8c26c
x=dat1
Packit Service a8c26c
cat <$x > dat2 || err_exit "cat < $x > dat2 failed"
Packit Service a8c26c
cat dat1 dat2 | cat  | cat | cat > dat3 || err_exit "cat pipe failed"
Packit Service a8c26c
cat > dat4 <
Packit Service a8c26c
$(date)
Packit Service a8c26c
!
Packit Service a8c26c
cat dat1 dat2 | cat  | cat | cat > dat5 &
Packit Service a8c26c
wait $!
Packit Service a8c26c
set -- dat*
Packit Service a8c26c
if	(( $# != 5 ))
Packit Service a8c26c
then	err_exit "dat* matches only $# files"
Packit Service a8c26c
fi
Packit Service a8c26c
if	(command > foo\\abc) 2> /dev/null
Packit Service a8c26c
then	set -- foo*
Packit Service a8c26c
	if	[[ $1 != 'foo\abc' ]]
Packit Service a8c26c
	then	err_exit 'foo* does not match foo\abc'
Packit Service a8c26c
	fi
Packit Service a8c26c
fi
Packit Service a8c26c
if ( : > TT* && : > TTfoo ) 2>/dev/null
Packit Service a8c26c
then	set -- TT*
Packit Service a8c26c
	if	(( $# < 2 ))
Packit Service a8c26c
	then	err_exit 'TT* not expanding when file TT* exists'
Packit Service a8c26c
	fi
Packit Service a8c26c
fi
Packit Service a8c26c
cd ~- || err_exit "cd back failed"
Packit Service a8c26c
cat > $tmp/script <<- !
Packit Service a8c26c
	#! $SHELL
Packit Service a8c26c
	print -r -- \$0
Packit Service a8c26c
!
Packit Service a8c26c
chmod 755 $tmp/script
Packit Service a8c26c
if	[[ $($tmp/script) != "$tmp/script" ]]
Packit Service a8c26c
then	err_exit '$0 not correct for #! script'
Packit Service a8c26c
fi
Packit Service a8c26c
bar=foo
Packit Service a8c26c
eval foo=\$bar
Packit Service a8c26c
if	[[ $foo != foo ]]
Packit Service a8c26c
then	err_exit 'eval foo=\$bar not working'
Packit Service a8c26c
fi
Packit Service a8c26c
bar='foo=foo\ bar'
Packit Service a8c26c
eval $bar
Packit Service a8c26c
if	[[ $foo != 'foo bar' ]]
Packit Service a8c26c
then	err_exit 'eval foo=\$bar, with bar="foo\ bar" not working'
Packit Service a8c26c
fi
Packit Service a8c26c
cd /tmp
Packit Service a8c26c
cd ../../tmp || err_exit "cd ../../tmp failed"
Packit Service a8c26c
if	[[ $PWD != /tmp ]]
Packit Service a8c26c
then	err_exit 'cd ../../tmp is not /tmp'
Packit Service a8c26c
fi
Packit Service a8c26c
( sleep 2; cat <
Packit Service a8c26c
foobar
Packit Service a8c26c
!
Packit Service a8c26c
) | cat > $tmp/foobar &
Packit Service a8c26c
wait $!
Packit Service a8c26c
foobar=$( < $tmp/foobar)
Packit Service a8c26c
if	[[ $foobar != foobar ]]
Packit Service a8c26c
then	err_exit "$foobar is not foobar"
Packit Service a8c26c
fi
Packit Service a8c26c
{
Packit Service a8c26c
	print foo
Packit Service a8c26c
	/bin/echo bar
Packit Service a8c26c
	print bam
Packit Service a8c26c
} > $tmp/foobar
Packit Service a8c26c
if	[[ $( < $tmp/foobar) != $'foo\nbar\nbam' ]]
Packit Service a8c26c
then	err_exit "output file pointer not shared correctly"
Packit Service a8c26c
fi
Packit Service a8c26c
cat > $tmp/foobar <<\!
Packit Service a8c26c
	print foo
Packit Service a8c26c
	/bin/echo bar
Packit Service a8c26c
	print bam
Packit Service a8c26c
!
Packit Service a8c26c
chmod +x $tmp/foobar
Packit Service a8c26c
if	[[ $($tmp/foobar) != $'foo\nbar\nbam' ]]
Packit Service a8c26c
then	err_exit "script not working"
Packit Service a8c26c
fi
Packit Service a8c26c
if	[[ $($tmp/foobar | /bin/cat) != $'foo\nbar\nbam' ]]
Packit Service a8c26c
then	err_exit "script | cat not working"
Packit Service a8c26c
fi
Packit Service a8c26c
if	[[ $( $tmp/foobar) != $'foo\nbar\nbam' ]]
Packit Service a8c26c
then	err_exit "output file pointer not shared correctly"
Packit Service a8c26c
fi
Packit Service a8c26c
rm -f $tmp/foobar
Packit Service a8c26c
x=$( (print foo) ; (print bar) )
Packit Service a8c26c
if	[[ $x != $'foo\nbar' ]]
Packit Service a8c26c
then	err_exit " ( (print foo);(print bar ) failed"
Packit Service a8c26c
fi
Packit Service a8c26c
x=$( (/bin/echo foo) ; (print bar) )
Packit Service a8c26c
if	[[ $x != $'foo\nbar' ]]
Packit Service a8c26c
then	err_exit " ( (/bin/echo);(print bar ) failed"
Packit Service a8c26c
fi
Packit Service a8c26c
x=$( (/bin/echo foo) ; (/bin/echo bar) )
Packit Service a8c26c
if	[[ $x != $'foo\nbar' ]]
Packit Service a8c26c
then	err_exit " ( (/bin/echo);(/bin/echo bar ) failed"
Packit Service a8c26c
fi
Packit Service a8c26c
cat > $tmp/script <<\!
Packit Service a8c26c
if	[[ -p /dev/fd/0 ]]
Packit Service a8c26c
then	builtin cat
Packit Service a8c26c
	cat - > /dev/null
Packit Service a8c26c
	[[ -p /dev/fd/0 ]] && print ok
Packit Service a8c26c
else	print no
Packit Service a8c26c
fi
Packit Service a8c26c
!
Packit Service a8c26c
chmod +x $tmp/script
Packit Service a8c26c
case $( (print) | $tmp/script;:) in
Packit Service a8c26c
ok)	;;
Packit Service a8c26c
no)	err_exit "[[ -p /dev/fd/0 ]] fails for standard input pipe" ;;
Packit Service a8c26c
*)	err_exit "builtin replaces standard input pipe" ;;
Packit Service a8c26c
esac
Packit Service a8c26c
print 'print $0' > $tmp/script
Packit Service a8c26c
print ". $tmp/script" > $tmp/scriptx
Packit Service a8c26c
chmod +x $tmp/scriptx
Packit Service a8c26c
if	[[ $($tmp/scriptx) != $tmp/scriptx ]]
Packit Service a8c26c
then	err_exit '$0 not correct for . script'
Packit Service a8c26c
fi
Packit Service a8c26c
cd $tmp || { err_exit "cd $tmp failed"; exit 1; }
Packit Service a8c26c
print ./b > ./a; print ./c > b; print ./d > c; print ./e > d; print "echo \"hello there\"" > e
Packit Service a8c26c
chmod 755 a b c d e
Packit Service a8c26c
x=$(./a)
Packit Service a8c26c
if	[[ $x != "hello there" ]]
Packit Service a8c26c
then	err_exit "nested scripts failed"
Packit Service a8c26c
fi
Packit Service a8c26c
x=$( (./a) | cat)
Packit Service a8c26c
if	[[ $x != "hello there" ]]
Packit Service a8c26c
then	err_exit "scripts in subshells fail"
Packit Service a8c26c
fi
Packit Service a8c26c
cd ~- || err_exit "cd back failed"
Packit Service a8c26c
x=$( (/bin/echo foo) 2> /dev/null )
Packit Service a8c26c
if	[[ $x != foo ]]
Packit Service a8c26c
then	err_exit "subshell in command substitution fails"
Packit Service a8c26c
fi
Packit Service a8c26c
exec 9>& 1
Packit Service a8c26c
exec 1>&-
Packit Service a8c26c
x=$(print hello)
Packit Service a8c26c
if	[[ $x != hello ]]
Packit Service a8c26c
then	err_exit "command subsitution with stdout closed failed"
Packit Service a8c26c
fi
Packit Service a8c26c
exec >& 9
Packit Service a8c26c
cd $pwd
Packit Service a8c26c
x=$(cat <<\! | $SHELL
Packit Service a8c26c
/bin/echo | /bin/cat
Packit Service a8c26c
/bin/echo hello
Packit Service a8c26c
!
Packit Service a8c26c
)
Packit Service a8c26c
if	[[ $x != $'\n'hello ]]
Packit Service a8c26c
then	err_exit "$SHELL not working when standard input is a pipe"
Packit Service a8c26c
fi
Packit Service a8c26c
x=$( (/bin/echo hello) 2> /dev/null )
Packit Service a8c26c
if	[[ $x != hello ]]
Packit Service a8c26c
then	err_exit "subshell in command substitution with 1 closed fails"
Packit Service a8c26c
fi
Packit Service a8c26c
cat > $tmp/script <<- \!
Packit Service a8c26c
read line 2> /dev/null
Packit Service a8c26c
print done
Packit Service a8c26c
!
Packit Service a8c26c
if	[[ $($SHELL $tmp/script <&-) != done ]]
Packit Service a8c26c
then	err_exit "executing script with 0 closed fails"
Packit Service a8c26c
fi
Packit Service a8c26c
trap '' INT
Packit Service a8c26c
cat > $tmp/script <<- \!
Packit Service a8c26c
trap 'print bad' INT
Packit Service a8c26c
kill -s INT $$
Packit Service a8c26c
print good
Packit Service a8c26c
!
Packit Service a8c26c
chmod +x $tmp/script
Packit Service a8c26c
if	[[ $($SHELL  $tmp/script) != good ]]
Packit Service a8c26c
then	err_exit "traps ignored by parent not ignored"
Packit Service a8c26c
fi
Packit Service a8c26c
trap - INT
Packit Service a8c26c
cat > $tmp/script <<- \!
Packit Service a8c26c
read line
Packit Service a8c26c
/bin/cat
Packit Service a8c26c
!
Packit Service a8c26c
if	[[ $($SHELL $tmp/script <
Packit Service a8c26c
one
Packit Service a8c26c
two
Packit Service a8c26c
!
Packit Service a8c26c
)	!= two ]]
Packit Service a8c26c
then	err_exit "standard input not positioned correctly"
Packit Service a8c26c
fi
Packit Service a8c26c
word=$(print $'foo\nbar' | { read line; /bin/cat;})
Packit Service a8c26c
if	[[ $word != bar ]]
Packit Service a8c26c
then	err_exit "pipe to { read line; /bin/cat;} not working"
Packit Service a8c26c
fi
Packit Service a8c26c
word=$(print $'foo\nbar' | ( read line; /bin/cat) )
Packit Service a8c26c
if	[[ $word != bar ]]
Packit Service a8c26c
then	err_exit "pipe to ( read line; /bin/cat) not working"
Packit Service a8c26c
fi
Packit Service a8c26c
if	[[ $(print x{a,b}y) != 'xay xby' ]]
Packit Service a8c26c
then	err_exit 'brace expansion not working'
Packit Service a8c26c
fi
Packit Service a8c26c
if	[[ $(for i in foo bar
Packit Service a8c26c
	  do ( tgz=$(print $i)
Packit Service a8c26c
	  print $tgz)
Packit Service a8c26c
	  done) != $'foo\nbar' ]]
Packit Service a8c26c
then	err_exit 'for loop subshell optimizer bug'
Packit Service a8c26c
fi
Packit Service a8c26c
unset a1
Packit Service a8c26c
optbug()
Packit Service a8c26c
{
Packit Service a8c26c
	set -A a1  foo bar bam
Packit Service a8c26c
	integer i
Packit Service a8c26c
	for ((i=0; i < 3; i++))
Packit Service a8c26c
	do
Packit Service a8c26c
		(( ${#a1[@]} < 2 )) && return 0
Packit Service a8c26c
		set -- "${a1[@]}"
Packit Service a8c26c
		shift
Packit Service a8c26c
		set -A a1 -- "$@"
Packit Service a8c26c
	done
Packit Service a8c26c
	return 1
Packit Service a8c26c
}
Packit Service a8c26c
optbug ||  err_exit 'array size optimzation bug'
Packit Service a8c26c
wait # not running --pipefail which would interfere with subsequent tests
Packit Service a8c26c
: $(jobs -p) # required to clear jobs for next jobs -p (interactive side effect)
Packit Service a8c26c
sleep 20 &
Packit Service a8c26c
pids=$!
Packit Service a8c26c
if	[[ $(jobs -p) != $! ]]
Packit Service a8c26c
then	err_exit 'jobs -p not reporting a background job'
Packit Service a8c26c
fi
Packit Service a8c26c
sleep 20 &
Packit Service a8c26c
pids="$pids $!"
Packit Service a8c26c
foo()
Packit Service a8c26c
{
Packit Service a8c26c
	set -- $(jobs -p)
Packit Service a8c26c
	(( $# == 2 )) || err_exit "$# jobs not reported -- 2 expected"
Packit Service a8c26c
}
Packit Service a8c26c
foo
Packit Service a8c26c
kill $pids
Packit Service a8c26c
Packit Service a8c26c
[[ $( (trap 'print alarm' ALRM; sleep 4) & sleep 2; kill -ALRM $!; sleep 2; wait) == alarm ]] || err_exit 'ALRM signal not working'
Packit Service a8c26c
[[ $($SHELL -c 'trap "" HUP; $SHELL -c "(sleep 2;kill -HUP $$)& sleep 4;print done"') != done ]] && err_exit 'ignored traps not being ignored'
Packit Service a8c26c
[[ $($SHELL -c 'o=foobar; for x in foo bar; do (o=save);print $o;done' 2> /dev/null ) == $'foobar\nfoobar' ]] || err_exit 'for loop optimization subshell bug'
Packit Service a8c26c
command exec 3<> /dev/null
Packit Service a8c26c
if	cat /dev/fd/3 >/dev/null 2>&1  || whence mkfifo > /dev/null
Packit Service a8c26c
then	[[ $($SHELL -c 'cat <(print foo)' 2> /dev/null) == foo ]] || err_exit 'process substitution not working'
Packit Service a8c26c
	[[ $($SHELL -c  $'tee >(grep \'1$\' > '$tmp/scriptx$') > /dev/null <<-  \!!!
Packit Service a8c26c
	line0
Packit Service a8c26c
	line1
Packit Service a8c26c
	line2
Packit Service a8c26c
	!!!
Packit Service a8c26c
	wait
Packit Service a8c26c
	cat '$tmp/scriptx 2> /dev/null)  == line1 ]] || err_exit '>() process substitution fails'
Packit Service a8c26c
	> $tmp/scriptx
Packit Service a8c26c
	[[ $($SHELL -c  $'
Packit Service a8c26c
	for i in 1
Packit Service a8c26c
	do	tee >(grep \'1$\' > '$tmp/scriptx$') > /dev/null  <<-  \!!!
Packit Service a8c26c
		line0
Packit Service a8c26c
		line1
Packit Service a8c26c
		line2
Packit Service a8c26c
		!!!
Packit Service a8c26c
	done
Packit Service a8c26c
	wait
Packit Service a8c26c
	cat '$tmp/scriptx 2>> /dev/null) == line1 ]] || err_exit '>() process substitution fails in for loop'
Packit Service a8c26c
	[[ $({ $SHELL -c 'cat <(for i in x y z; do print $i; done)';} 2> /dev/null) == $'x\ny\nz' ]] ||
Packit Service a8c26c
		err_exit 'process substitution of compound commands not working'
Packit Service a8c26c
fi
Packit Service a8c26c
[[ $($SHELL -r 'command -p :' 2>&1) == *restricted* ]]  || err_exit 'command -p not restricted'
Packit Service a8c26c
print cat >  $tmp/scriptx
Packit Service a8c26c
chmod +x $tmp/scriptx
Packit Service a8c26c
[[ $($SHELL -c "print foo | $tmp/scriptx ;:" 2> /dev/null ) == foo ]] || err_exit 'piping into script fails'
Packit Service a8c26c
[[ $($SHELL -c 'X=1;print -r -- ${X:=$(expr "a(0)" : '"'a*(\([^)]\))')}'" 2> /dev/null) == 1 ]] || err_exit 'x=1;${x:=$(..."...")} failure'
Packit Service a8c26c
[[ $($SHELL -c 'print -r -- ${X:=$(expr "a(0)" : '"'a*(\([^)]\))')}'" 2> /dev/null) == 0 ]] || err_exit '${x:=$(..."...")} failure'
Packit Service a8c26c
if	cat /dev/fd/3 >/dev/null 2>&1  || whence mkfifo > /dev/null
Packit Service a8c26c
then	[[ $(cat <(print hello) ) == hello ]] || err_exit "process substitution not working outside for or while loop"
Packit Service a8c26c
	$SHELL -c '[[ $(for i in 1;do cat <(print hello);done ) == hello ]]' 2> /dev/null|| err_exit "process substitution not working in for or while loop"
Packit Service a8c26c
fi
Packit Service a8c26c
exec 3> /dev/null
Packit Service a8c26c
print 'print foo "$@"' > $tmp/scriptx
Packit Service a8c26c
[[ $( print "($tmp/scriptx bar)" | $SHELL 2>/dev/null) == 'foo bar' ]] || err_exit 'script pipe to shell fails'
Packit Service a8c26c
print "#! $SHELL" > $tmp/scriptx
Packit Service a8c26c
print 'print  -- $0' >> $tmp/scriptx
Packit Service a8c26c
chmod +x $tmp/scriptx
Packit Service a8c26c
[[ $($tmp/scriptx) == $tmp/scriptx ]] || err_exit  "\$0 is $0 instead of $tmp/scriptx"
Packit Service a8c26c
cat > $tmp/scriptx <<- \EOF
Packit Service a8c26c
	myfilter() { x=$(print ok | cat); print  -r -- $SECONDS;}
Packit Service a8c26c
	set -o pipefail
Packit Service a8c26c
	sleep 3 | myfilter
Packit Service a8c26c
EOF
Packit Service a8c26c
(( $($SHELL $tmp/scriptx) > 2.0 )) && err_exit 'command substitution causes pipefail option to hang'
Packit Service a8c26c
exec 3<&-
Packit Service a8c26c
( typeset -r foo=bar) 2> /dev/null || err_exit 'readonly variables set in a subshell cannot unset'
Packit Service a8c26c
$SHELL -c 'x=${ print hello;}; [[ $x == hello ]]' 2> /dev/null || err_exit '${ command;} not supported'
Packit Service a8c26c
$SHELL 2> /dev/null <<- \EOF || err_exit 'multiline ${...} command substitution not supported'
Packit Service a8c26c
	x=${
Packit Service a8c26c
		print hello
Packit Service a8c26c
	}
Packit Service a8c26c
	[[ $x == hello ]]
Packit Service a8c26c
EOF
Packit Service a8c26c
$SHELL 2> /dev/null <<- \EOF || err_exit '${...} command substitution with side effects not supported '
Packit Service a8c26c
	y=bye
Packit Service a8c26c
	x=${
Packit Service a8c26c
		y=hello
Packit Service a8c26c
		print hello
Packit Service a8c26c
	}
Packit Service a8c26c
	[[ $y == $x ]]
Packit Service a8c26c
EOF
Packit Service a8c26c
$SHELL   2> /dev/null <<- \EOF || err_exit 'nested ${...} command substitution not supported'
Packit Service a8c26c
	x=${
Packit Service a8c26c
		print ${ print hello;} $(print world)
Packit Service a8c26c
	}
Packit Service a8c26c
	[[ $x == 'hello world' ]]
Packit Service a8c26c
EOF
Packit Service a8c26c
$SHELL   2> /dev/null <<- \EOF || err_exit 'terminating } is not a reserved word with ${ command }'
Packit Service a8c26c
	x=${	{ print -n } ; print -n hello ; }  ; print ' world' }
Packit Service a8c26c
	[[ $x == '}hello world' ]]
Packit Service a8c26c
EOF
Packit Service a8c26c
$SHELL   2> /dev/null <<- \EOF || err_exit '${ command;}xxx not working'
Packit Service a8c26c
	f()
Packit Service a8c26c
	{
Packit Service a8c26c
		print foo
Packit Service a8c26c
	}
Packit Service a8c26c
	[[ ${ f;}bar == foobar ]]
Packit Service a8c26c
EOF
Packit Service a8c26c
Packit Service a8c26c
unset foo
Packit Service a8c26c
[[ ! ${foo[@]} ]] || err_exit '${foo[@]} is not empty when foo is unset'
Packit Service a8c26c
[[ ! ${foo[3]} ]] || err_exit '${foo[3]} is not empty when foo is unset'
Packit Service a8c26c
[[ $(print  "[${ print foo }]") == '[foo]' ]] || err_exit '${...} not working when } is followed by ]'
Packit Service a8c26c
[[ $(print  "${ print "[${ print foo }]" }") == '[foo]' ]] || err_exit 'nested ${...} not working when } is followed by ]'
Packit Service a8c26c
unset foo
Packit Service a8c26c
foo=$(false) > /dev/null && err_exit 'failed command substitution with redirection not returning false'
Packit Service a8c26c
expected=foreback
Packit Service a8c26c
got=$(print -n fore; (sleep 2;print back)&)
Packit Service a8c26c
[[ $got == $expected ]] || err_exit "command substitution background process output error -- got '$got', expected '$expected'"
Packit Service a8c26c
Packit Service a8c26c
binfalse=$(whence -p false)
Packit Service a8c26c
for false in false $binfalse
Packit Service a8c26c
do	x=$($false) && err_exit "x=\$($false) should fail"
Packit Service a8c26c
	$($false) && err_exit "\$($false) should fail"
Packit Service a8c26c
	$($false) > /dev/null && err_exit "\$($false) > /dev/null should fail"
Packit Service a8c26c
done
Packit Service a8c26c
if	env x-a=y >/dev/null 2>&1
Packit Service a8c26c
then	[[ $(env 'x-a=y'  $SHELL -c 'env | grep x-a') == *x-a=y* ]] || err_exit 'invalid environment variables not preserved'
Packit Service a8c26c
fi
Packit Service a8c26c
float s=SECONDS
Packit Service a8c26c
sleep=$(whence -p sleep)
Packit Service a8c26c
for i in 1 2
Packit Service a8c26c
do      print $i
Packit Service a8c26c
done | while read sec; do ( $sleep $sec; $sleep $sec) done
Packit Service a8c26c
(( (SECONDS-s)  < 4)) && err_exit '"command | while read...done" finishing too fast'
Packit Service a8c26c
s=SECONDS
Packit Service a8c26c
set -o pipefail
Packit Service a8c26c
for ((i=0; i < 30; i++))
Packit Service a8c26c
do	print hello
Packit Service a8c26c
	sleep .1
Packit Service a8c26c
done |  $sleep 1
Packit Service a8c26c
(( (SECONDS-s) < 2 )) || err_exit 'early termination not causing broken pipe'
Packit Service a8c26c
[[ $({ trap 'print trap' 0; print -n | $(whence -p cat); } & wait $!) == trap ]] || err_exit 'trap on exit not getting triggered'
Packit Service a8c26c
var=$({ trap 'print trap' ERR; print -n | $binfalse; } & wait $!)
Packit Service a8c26c
[[ $var == trap ]] || err_exit 'trap on ERR not getting triggered'
Packit Service a8c26c
Packit Service a8c26c
exp=
Packit Service a8c26c
got=$(
Packit Service a8c26c
	function fun
Packit Service a8c26c
	{
Packit Service a8c26c
		$binfalse && echo FAILED
Packit Service a8c26c
	}
Packit Service a8c26c
	: works if this line deleted : |
Packit Service a8c26c
	fun
Packit Service a8c26c
	: works if this line deleted :
Packit Service a8c26c
)
Packit Service a8c26c
[[ $got == $exp ]] || err_exit "pipe to function with conditional fails -- expected '$exp', got '$got'"
Packit Service a8c26c
got=$(
Packit Service a8c26c
	: works if this line deleted : |
Packit Service a8c26c
	{ $binfalse && echo FAILED; }
Packit Service a8c26c
	: works if this line deleted :
Packit Service a8c26c
)
Packit Service a8c26c
[[ $got == $exp ]] || err_exit "pipe to { ... } with conditional fails -- expected '$exp', got '$got'"
Packit Service a8c26c
Packit Service a8c26c
got=$(
Packit Service a8c26c
	: works if this line deleted : |
Packit Service a8c26c
	( $binfalse && echo FAILED )
Packit Service a8c26c
	: works if this line deleted :
Packit Service a8c26c
)
Packit Service a8c26c
[[ $got == $exp ]] || err_exit "pipe to ( ... ) with conditional fails -- expected '$exp', got '$got'"
Packit Service a8c26c
Packit Service a8c26c
( $SHELL -c 'trap : DEBUG; x=( $foo); exit 0') 2> /dev/null  || err_exit 'trap DEBUG fails'
Packit Service a8c26c
Packit Service a8c26c
bintrue=$(whence -p true)
Packit Service a8c26c
set -o pipefail
Packit Service a8c26c
float start=$SECONDS end 
Packit Service a8c26c
for ((i=0; i < 2; i++))
Packit Service a8c26c
do	print foo
Packit Service a8c26c
	sleep 1.5
Packit Service a8c26c
done | { read; $bintrue; end=$SECONDS ;}
Packit Service a8c26c
(( (SECONDS-start) < 1 )) && err_exit "pipefail not waiting for pipe to finish"
Packit Service a8c26c
set +o pipefail
Packit Service a8c26c
(( (SECONDS-end) > 2 )) &&  err_exit "pipefail causing $bintrue to wait for other end of pipe"
Packit Service a8c26c
Packit Service a8c26c
Packit Service a8c26c
{ env A__z=C+SHLVL $SHELL -c : ;} 2> /dev/null || err_exit "SHLVL with wrong attribute fails"
Packit Service a8c26c
Packit Service a8c26c
if [[ $bintrue ]]
Packit Service a8c26c
then	float t0=SECONDS
Packit Service a8c26c
	{ time sleep 1.5 | $bintrue ;} 2> /dev/null
Packit Service a8c26c
	(( (SECONDS-t0) < 1 )) && err_exit 'time not waiting for pipeline to complete' 
Packit Service a8c26c
fi
Packit Service a8c26c
Packit Service a8c26c
cat > $tmp/foo.sh <<- \EOF
Packit Service a8c26c
	eval "cat > /dev/null  < /dev/null"
Packit Service a8c26c
	sleep 1
Packit Service a8c26c
EOF
Packit Service a8c26c
float sec=SECONDS
Packit Service a8c26c
. $tmp/foo.sh  | cat > /dev/null
Packit Service a8c26c
(( (SECONDS-sec) < .7 ))  && err_exit '. script does not restore output redirection with eval'
Packit Service a8c26c
Packit Service a8c26c
file=$tmp/foobar
Packit Service a8c26c
builtin cat
Packit Service a8c26c
for ((n=0; n < 1000; n++))
Packit Service a8c26c
do
Packit Service a8c26c
	> $file
Packit Service a8c26c
	{ sleep .001;echo $? >$file;} | cat > /dev/null
Packit Service a8c26c
	if	[[ !  -s $file ]]
Packit Service a8c26c
	then	err_exit 'output from pipe is lost with pipe to builtin'
Packit Service a8c26c
		break;
Packit Service a8c26c
	fi
Packit Service a8c26c
done
Packit Service a8c26c
Packit Service a8c26c
$SHELL -c 'kill -0 123456789123456789123456789' 2> /dev/null && err_exit 'kill not catching process id overflows'
Packit Service a8c26c
Packit Service a8c26c
[[ $($SHELL -c '{ cd..; print ok;}' 2> /dev/null) == ok ]] || err_exit 'command name ending in .. causes shell to abort'
Packit Service a8c26c
Packit Service a8c26c
$SHELL -xc '$(LD_LIBRARY_PATH=$LD_LIBRARY_PATH exec $SHELL -c :)' > /dev/null 2>&1  || err_exit "ksh -xc '(name=value exec ksh)' fails with err=$?"
Packit Service a8c26c
Packit Service a8c26c
$SHELL 2> /dev/null -c $'for i;\ndo :;done' || err_exit 'for i ; <newline> not vaid'
Packit Service a8c26c
Packit Service a8c26c
exit $((Errors<125?Errors:125))