1########################################################################
2#                                                                      #
3#               This software is part of the ast package               #
4#          Copyright (c) 1982-2012 AT&T Intellectual Property          #
5#                      and is licensed under the                       #
6#                 Eclipse Public License, Version 1.0                  #
7#                    by AT&T Intellectual Property                     #
8#                                                                      #
9#                A copy of the License is available at                 #
10#          http://www.eclipse.org/org/documents/epl-v10.html           #
11#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
12#                                                                      #
13#              Information and Software Systems Research               #
14#                            AT&T Research                             #
15#                           Florham Park NJ                            #
16#                                                                      #
17#                  David Korn <dgk@research.att.com>                   #
18#                                                                      #
19########################################################################
20function err_exit
21{
22	print -u2 -n "\t"
23	print -u2 -r ${Command}[$1]: "${@:2}"
24	let Errors+=1
25}
26alias err_exit='err_exit $LINENO'
27
28Command=${0##*/}
29integer Errors=0
30
31tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
32trap "cd /; rm -rf $tmp" EXIT
33
34# test shell builtin commands
35builtin getconf
36: ${foo=bar} || err_exit ": failed"
37[[ $foo == bar ]] || err_exit ": side effects failed"
38set -- - foobar
39[[ $# == 2 && $1 == - && $2 == foobar ]] || err_exit "set -- - foobar failed"
40set -- -x foobar
41[[ $# == 2 && $1 == -x && $2 == foobar ]] || err_exit "set -- -x foobar failed"
42getopts :x: foo || err_exit "getopts :x: returns false"
43[[ $foo == x && $OPTARG == foobar ]] || err_exit "getopts :x: failed"
44OPTIND=1
45getopts :r:s var -r
46if	[[ $var != : || $OPTARG != r ]]
47then	err_exit "'getopts :r:s var -r' not working"
48fi
49OPTIND=1
50getopts :d#u OPT -d 16177
51if	[[ $OPT != d || $OPTARG != 16177 ]]
52then	err_exit "'getopts :d#u OPT=d OPTARG=16177' failed -- OPT=$OPT OPTARG=$OPTARG"
53fi
54OPTIND=1
55while getopts 'ab' option -a -b
56do	[[ $OPTIND == $((OPTIND)) ]] || err_exit "OPTIND optimization bug"
57done
58
59USAGE=$'[-][S:server?Operate on the specified \asubservice\a:]:[subservice:=pmserver]
60    {
61        [p:pmserver]
62        [r:repserver]
63        [11:notifyd]
64    }'
65set pmser p rep r notifyd -11
66while	(( $# > 1 ))
67do	OPTIND=1
68	getopts "$USAGE" OPT -S $1
69	[[ $OPT == S && $OPTARG == $2 ]] || err_exit "OPT=$OPT OPTARG=$OPTARG -- expected OPT=S OPTARG=$2"
70	shift 2
71done
72
73false ${foo=bar} &&  err_exit "false failed"
74read <<!
75hello world
76!
77[[ $REPLY == 'hello world' ]] || err_exit "read builtin failed"
78print x:y | IFS=: read a b
79if	[[ $a != x ]]
80then	err_exit "IFS=: read ... not working"
81fi
82read <<!
83hello \
84world
85!
86[[ $REPLY == 'hello world' ]] || err_exit "read continuation failed"
87read -d x <<!
88hello worldxfoobar
89!
90[[ $REPLY == 'hello world' ]] || err_exit "read builtin failed"
91read <<\!
92hello \
93	world \
94
95!
96[[ $REPLY == 'hello 	world' ]] || err_exit "read continuation2 failed"
97print "one\ntwo" | { read line
98	print $line | /bin/cat > /dev/null
99	read line
100}
101read <<\!
102\
103a\
104\
105\
106b
107!
108if	[[ $REPLY != ab ]]
109then	err_exit "read multiple continuation failed"
110fi
111if	[[ $line != two ]]
112then	err_exit "read from pipeline failed"
113fi
114line=two
115read line < /dev/null
116if	[[ $line != "" ]]
117then	err_exit "read from /dev/null failed"
118fi
119if	[[ $(print -R -) != - ]]
120then	err_exit "print -R not working correctly"
121fi
122if	[[ $(print -- -) != - ]]
123then	err_exit "print -- not working correctly"
124fi
125print -f "hello%nbar\n" size > /dev/null
126if	((	size != 5 ))
127then	err_exit "%n format of printf not working"
128fi
129print -n -u2 2>&1-
130[[ -w /dev/fd/1 ]] || err_exit "2<&1- with built-ins has side effects"
131x=$0
132if	[[ $(eval 'print $0') != $x ]]
133then	err_exit '$0 not correct for eval'
134fi
135$SHELL -c 'read x <<< hello' 2> /dev/null || err_exit 'syntax <<< not recognized'
136($SHELL -c 'read x[1] <<< hello') 2> /dev/null || err_exit 'read x[1] not working'
137unset x
138readonly x
139set -- $(readonly)
140if      [[ " $@ " != *" x "* ]]
141then    err_exit 'unset readonly variables are not displayed'
142fi
143if	[[ $(	for i in foo bar
144		do	print $i
145			continue 10
146		done
147	    ) != $'foo\nbar' ]]
148then	err_exit 'continue breaks out of loop'
149fi
150(continue bad 2>/dev/null && err_exit 'continue bad should return an error')
151(break bad 2>/dev/null && err_exit 'break bad should return an error')
152(continue 0 2>/dev/null && err_exit 'continue 0 should return an error')
153(break 0 2>/dev/null && err_exit 'break 0 should return an error')
154breakfun() { break;}
155continuefun() { continue;}
156for fun in break continue
157do	if	[[ $(	for i in foo
158			do	${fun}fun
159				print $i
160			done
161		) != foo ]]
162	then	err_exit "$fun call in ${fun}fun breaks out of for loop"
163	fi
164done
165if	[[ $(print -f "%b" "\a\n\v\b\r\f\E\03\\oo") != $'\a\n\v\b\r\f\E\03\\oo' ]]
166then	err_exit 'print -f "%b" not working'
167fi
168if	[[ $(print -f "%P" "[^x].*b\$") != '*[!x]*b' ]]
169then	err_exit 'print -f "%P" not working'
170fi
171if	[[ $(print -f "%(pattern)q" "[^x].*b\$") != '*[!x]*b' ]]
172then	err_exit 'print -f "%(pattern)q" not working'
173fi
174if	[[ $(abc: for i in foo bar;do print $i;break abc;done) != foo ]]
175then	err_exit 'break labels not working'
176fi
177if	[[ $(command -v if)	!= if ]]
178then	err_exit	'command -v not working'
179fi
180read -r var <<\!
181
182!
183if	[[ $var != "" ]]
184then	err_exit "read -r of blank line not working"
185fi
186mkdir -p $tmp/a/b/c 2>/dev/null || err_exit  "mkdir -p failed"
187$SHELL -c "cd $tmp/a/b; cd c" 2>/dev/null || err_exit "initial script relative cd fails"
188
189trap 'print TERM' TERM
190exp=$'trap -- \'print TERM\' TERM\ntrap -- \'cd /; rm -rf '$tmp$'\' EXIT'
191got=$(trap)
192[[ $got == $exp ]] || err_exit "\$(trap) failed -- expected \"$exp\", got \"$got\""
193exp='print TERM'
194got=$(trap -p TERM)
195[[ $got == $exp ]] || err_exit "\$(trap -p TERM) failed -- expected \"$exp\", got \"$got\""
196
197[[ $($SHELL -c 'trap "print ok" SIGTERM; kill -s SIGTERM $$' 2> /dev/null) == ok ]] || err_exit 'SIGTERM not recognized'
198[[ $($SHELL -c 'trap "print ok" sigterm; kill -s sigterm $$' 2> /dev/null) == ok ]] || err_exit 'SIGTERM not recognized'
199[[ $($SHELL -c '( trap "" TERM);kill $$;print bad' == bad) ]] 2> /dev/null && err_exit 'trap ignored in subshell causes it to be ignored by parent'
200${SHELL} -c 'kill -1 -$$' 2> /dev/null
201[[ $(kill -l $?) == HUP ]] || err_exit 'kill -1 -pid not working'
202${SHELL} -c 'kill -1 -$$' 2> /dev/null
203[[ $(kill -l $?) == HUP ]] || err_exit 'kill -n1 -pid not working'
204${SHELL} -c 'kill -s HUP -$$' 2> /dev/null
205[[ $(kill -l $?) == HUP ]] || err_exit 'kill -HUP -pid not working'
206n=123
207typeset -A base
208base[o]=8#
209base[x]=16#
210base[X]=16#
211for i in d i o u x X
212do	if	(( $(( ${base[$i]}$(printf "%$i" $n) )) != n  ))
213	then	err_exit "printf %$i not working"
214	fi
215done
216if	[[ $(printf -eexist) != -eexist ]]
217then	err_exit 'printf -eexist ... not working'
218fi
219if	[[ $(printf -- "%s" foo) != foo ]]
220then	err_exit 'printf -- not working'
221fi
222if	[[ $(printf -- --) != -- ]]
223then	err_exit 'printf -- -- ... not working'
224fi
225if	[[ $(printf -- -eexist) != -eexist ]]
226then	err_exit 'printf -- -eexist. not working'
227fi
228if	[[ $( trap 'print done' EXIT) != done ]]
229then	err_exit 'trap on EXIT not working'
230fi
231if	[[ $( trap 'print done' EXIT; trap - EXIT) == done ]]
232then	err_exit 'trap on EXIT not being cleared'
233fi
234if	[[ $(LC_MESSAGES=C type test) != 'test is a shell builtin' ]]
235then	err_exit 'whence -v test not a builtin'
236fi
237builtin -d test
238if	[[ $(type test) == *builtin* ]]
239then	err_exit 'whence -v test after builtin -d incorrect'
240fi
241typeset -Z3 percent=$(printf '%o\n' "'%'")
242forrmat=\\${percent}s
243if      [[ $(printf "$forrmat") != %s ]]
244then    err_exit "printf $forrmat not working"
245fi
246if	(( $(printf 'x\0y' | wc -c) != 3 ))
247then	err_exit 'printf \0 not working'
248fi
249if	[[ $(printf "%bx%s\n" 'f\to\cbar') != $'f\to' ]]
250then	err_exit 'printf %bx%s\n  not working'
251fi
252alpha=abcdefghijklmnop
253if	[[ $(printf "%10.*s\n" 5 $alpha) != '     abcde' ]]
254then	err_exit 'printf %10.%s\n  not working'
255fi
256float x2=.0000625
257if	[[ $(printf "%10.5E\n" x2) != 6.25000E-05 ]]
258then	err_exit 'printf "%10.5E" not normalizing correctly'
259fi
260x2=.000000001
261if	[[ $(printf "%g\n" x2 2>/dev/null) != 1e-09 ]]
262then	err_exit 'printf "%g" not working correctly'
263fi
264#FIXME#($SHELL read -s foobar <<\!
265#FIXME#testing
266#FIXME#!
267#FIXME#) 2> /dev/null || err_exit ksh read -s var fails
268if	[[ $(printf +3 2>/dev/null) !=   +3 ]]
269then	err_exit 'printf is not processing formats beginning with + correctly'
270fi
271if	printf "%d %d\n" 123bad 78 >/dev/null 2>/dev/null
272then	err_exit "printf not exiting non-zero with conversion errors"
273fi
274if	[[ $(trap --version 2> /dev/null;print done) != done ]]
275then	err_exit 'trap builtin terminating after --version'
276fi
277if	[[ $(set --version 2> /dev/null;print done) != done ]]
278then	err_exit 'set builtin terminating after --veresion'
279fi
280unset -f foobar
281function foobar
282{
283	print 'hello world'
284}
285OPTIND=1
286if	[[ $(getopts  $'[+?X\ffoobar\fX]' v --man 2>&1) != *'Xhello world'X* ]]
287then	err_exit '\f...\f not working in getopts usage strings'
288fi
289if	[[ $(printf '%H\n' $'<>"& \'\tabc') != '&lt;&gt;&quot;&amp;&nbsp;&apos;&#9;abc' ]]
290then	err_exit 'printf %H not working'
291fi
292if	[[ $(printf '%(html)q\n' $'<>"& \'\tabc') != '&lt;&gt;&quot;&amp;&nbsp;&apos;&#9;abc' ]]
293then	err_exit 'printf %(html)q not working'
294fi
295if	[[ $( printf 'foo://ab_c%(url)q\n' $'<>"& \'\tabc') != 'foo://ab_c%3C%3E%22%26%20%27%09abc' ]]
296then	err_exit 'printf %(url)q not working'
297fi
298if	[[ $(printf '%R %R %R %R\n' 'a.b' '*.c' '^'  '!(*.*)') != '^a\.b$ \.c$ ^\^$ ^(.*\..*)!$' ]]
299then	err_exit 'printf %T not working'
300fi
301if	[[ $(printf '%(ere)q %(ere)q %(ere)q %(ere)q\n' 'a.b' '*.c' '^'  '!(*.*)') != '^a\.b$ \.c$ ^\^$ ^(.*\..*)!$' ]]
302then	err_exit 'printf %(ere)q not working'
303fi
304if	[[ $(printf '%..:c\n' abc) != a:b:c ]]
305then	err_exit "printf '%..:c' not working"
306fi
307if	[[ $(printf '%..*c\n' : abc) != a:b:c ]]
308then	err_exit "printf '%..*c' not working"
309fi
310if	[[ $(printf '%..:s\n' abc def ) != abc:def ]]
311then	err_exit "printf '%..:s' not working"
312fi
313if	[[ $(printf '%..*s\n' : abc def) != abc:def ]]
314then	err_exit "printf '%..*s' not working"
315fi
316[[ $(printf '%q\n') == '' ]] || err_exit 'printf "%q" with missing arguments'
317# we won't get hit by the one second boundary twice, right?
318[[ $(printf '%T\n' now) == "$(date)" ]] ||
319[[ $(printf '%T\n' now) == "$(date)" ]] ||
320err_exit 'printf "%T" now'
321behead()
322{
323	read line
324	left=$(cat)
325}
326print $'line1\nline2' | behead
327if	[[ $left != line2 ]]
328then	err_exit "read reading ahead on a pipe"
329fi
330read -n1 y <<!
331abc
332!
333exp=a
334if      [[ $y != $exp ]]
335then    err_exit "read -n1 failed -- expected '$exp', got '$y'"
336fi
337print -n $'{ read -r line;print $line;}\nhello' > $tmp/script
338chmod 755 $tmp/script
339if	[[ $($SHELL < $tmp/script) != hello ]]
340then	err_exit 'read of incomplete line not working correctly'
341fi
342set -f
343set -- *
344if      [[ $1 != '*' ]]
345then    err_exit 'set -f not working'
346fi
347unset pid1 pid2
348false &
349pid1=$!
350pid2=$(
351	wait $pid1
352	(( $? == 127 )) || err_exit "job known to subshell"
353	print $!
354)
355wait $pid1
356(( $? == 1 )) || err_exit "wait not saving exit value"
357wait $pid2
358(( $? == 127 )) || err_exit "subshell job known to parent"
359env=
360v=$(getconf LIBPATH)
361for v in ${v//,/ }
362do	v=${v#*:}
363	v=${v%%:*}
364	eval [[ \$$v ]] && env="$env $v=\"\$$v\""
365done
366if	[[ $(foo=bar; eval foo=\$foo $env exec -c \$SHELL -c \'print \$foo\') != bar ]]
367then	err_exit '"name=value exec -c ..." not working'
368fi
369$SHELL -c 'OPTIND=-1000000; getopts a opt -a' 2> /dev/null
370[[ $? == 1 ]] || err_exit 'getopts with negative OPTIND not working'
371getopts 'n#num' opt  -n 3
372[[ $OPTARG == 3 ]] || err_exit 'getopts with numerical arguments failed'
373if	[[ $($SHELL -c $'printf \'%2$s %1$s\n\' world hello') != 'hello world' ]]
374then	err_exit 'printf %2$s %1$s not working'
375fi
376val=$(( 'C' ))
377set -- \
378	"'C"	$val	0	\
379	"'C'"	$val	0	\
380	'"C'	$val	0	\
381	'"C"'	$val	0	\
382	"'CX"	$val	1	\
383	"'CX'"	$val	1	\
384	"'C'X"	$val	1	\
385	'"CX'	$val	1	\
386	'"CX"'	$val	1	\
387	'"C"X'	$val	1
388while (( $# >= 3 ))
389do	arg=$1 val=$2 code=$3
390	shift 3
391	for fmt in '%d' '%g'
392	do	out=$(printf "$fmt" "$arg" 2>/dev/null)
393		err=$(printf "$fmt" "$arg" 2>&1 >/dev/null)
394		printf "$fmt" "$arg" >/dev/null 2>&1
395		ret=$?
396		[[ $out == $val ]] || err_exit "printf $fmt $arg failed -- expected '$val', got '$out'"
397		if	(( $code ))
398		then	[[ $err ]] || err_exit "printf $fmt $arg failed, error message expected"
399		else	[[ $err ]] && err_exit "$err: printf $fmt $arg failed, error message not expected -- got '$err'"
400		fi
401		(( $ret == $code )) || err_exit "printf $fmt $arg failed -- expected exit code $code, got $ret"
402	done
403done
404((n=0))
405((n++)); ARGC[$n]=1 ARGV[$n]=""
406((n++)); ARGC[$n]=2 ARGV[$n]="-a"
407((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2"
408((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2 x"
409((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2 x y"
410for ((i=1; i<=n; i++))
411do	set -- ${ARGV[$i]}
412	OPTIND=0
413	while	getopts -a tst "av:" OPT
414	do	:
415	done
416	if	[[ $OPTIND != ${ARGC[$i]} ]]
417	then	err_exit "\$OPTIND after getopts loop incorrect -- expected ${ARGC[$i]}, got $OPTIND"
418	fi
419done
420options=ab:c
421optarg=foo
422set -- -a -b $optarg -c bar
423while	getopts $options opt
424do	case $opt in
425	a|c)	[[ $OPTARG ]] && err_exit "getopts $options \$OPTARG for flag $opt failed, expected \"\", got \"$OPTARG\"" ;;
426	b)	[[ $OPTARG == $optarg ]] || err_exit "getopts $options \$OPTARG failed -- \"$optarg\" expected, got \"$OPTARG\"" ;;
427	*)	err_exit "getopts $options failed -- got flag $opt" ;;
428	esac
429done
430
431[[ $($SHELL 2> /dev/null -c 'readonly foo; getopts a: foo -a blah; echo foo') == foo ]] || err_exit 'getopts with readonly variable causes script to abort'
432
433unset a
434{ read -N3 a; read -N1 b;}  <<!
435abcdefg
436!
437exp=abc
438[[ $a == $exp ]] || err_exit "read -N3 here-document failed -- expected '$exp', got '$a'"
439exp=d
440[[ $b == $exp ]] || err_exit "read -N1 here-document failed -- expected '$exp', got '$b'"
441read -n3 a <<!
442abcdefg
443!
444exp=abc
445[[ $a == $exp ]] || err_exit "read -n3 here-document failed -- expected '$exp', got '$a'"
446#(print -n a;sleep 1; print -n bcde) | { read -N3 a; read -N1 b;}
447#[[ $a == $exp ]] || err_exit "read -N3 from pipe failed -- expected '$exp', got '$a'"
448#exp=d
449#[[ $b == $exp ]] || err_exit "read -N1 from pipe failed -- expected '$exp', got '$b'"
450#(print -n a;sleep 1; print -n bcde) | read -n3 a
451#exp=a
452#[[ $a == $exp ]] || err_exit "read -n3 from pipe failed -- expected '$exp', got '$a'"
453#rm -f $tmp/fifo
454#if	mkfifo $tmp/fifo 2> /dev/null
455#then	(print -n a; sleep 1;print -n bcde)  > $tmp/fifo &
456#	{
457#	read -u5 -n3 -t2 a || err_exit 'read -n3 from fifo timedout'
458#	read -u5 -n1 -t2 b || err_exit 'read -n1 from fifo timedout'
459#	} 5< $tmp/fifo
460#	exp=a
461#	[[ $a == $exp ]] || err_exit "read -n3 from fifo failed -- expected '$exp', got '$a'"
462#	rm -f $tmp/fifo
463#	mkfifo $tmp/fifo 2> /dev/null
464#	(print -n a; sleep 1;print -n bcde) > $tmp/fifo &
465#	{
466#	read -u5 -N3 -t2 a || err_exit 'read -N3 from fifo timed out'
467#	read -u5 -N1 -t2 b || err_exit 'read -N1 from fifo timedout'
468#	} 5< $tmp/fifo
469#	exp=abc
470#	[[ $a == $exp ]] || err_exit "read -N3 from fifo failed -- expected '$exp', got '$a'"
471#	exp=d
472#	[[ $b == $exp ]] || err_exit "read -N1 from fifo failed -- expected '$exp', got '$b'"
473#fi
474#rm -f $tmp/fifo
475
476function longline
477{
478	integer i
479	for((i=0; i < $1; i++))
480	do	print argument$i
481	done
482}
483# test command -x option
484integer sum=0 n=10000
485if	! ${SHELL:-ksh} -c 'print $#' count $(longline $n) > /dev/null  2>&1
486then	for i in $(command command -x ${SHELL:-ksh} -c 'print $#;[[ $1 != argument0 ]]' count $(longline $n) 2> /dev/null)
487	do	((sum += $i))
488	done
489	(( sum == n )) || err_exit "command -x processed only $sum arguments"
490	command -p command -x ${SHELL:-ksh} -c 'print $#;[[ $1 == argument0 ]]' count $(longline $n) > /dev/null  2>&1
491	[[ $? != 1 ]] && err_exit 'incorrect exit status for command -x'
492fi
493# test command -x option with extra arguments
494integer sum=0 n=10000
495if      ! ${SHELL:-ksh} -c 'print $#' count $(longline $n) > /dev/null  2>&1
496then    for i in $(command command -x ${SHELL:-ksh} -c 'print $#;[[ $1 != argument0 ]]' count $(longline $n) one two three) #2> /dev/null)
497	do      ((sum += $i))
498	done
499	(( sum  > n )) || err_exit "command -x processed only $sum arguments"
500	(( (sum-n)%3==0 )) || err_exit "command -x processed only $sum arguments"
501	(( sum == n+3)) && err_exit "command -x processed only $sum arguments"
502	command -p command -x ${SHELL:-ksh} -c 'print $#;[[ $1 == argument0 ]]' count $(longline $n) > /dev/null  2>&1
503	[[ $? != 1 ]] && err_exit 'incorrect exit status for command -x'
504fi
505# test for debug trap
506[[ $(typeset -i i=0
507	trap 'print $i' DEBUG
508	while (( i <2))
509	do	(( i++))
510	done) == $'0\n0\n1\n1\n2' ]]  || err_exit  "DEBUG trap not working"
511getconf UNIVERSE - ucb
512[[ $($SHELL -c 'echo -3') == -3 ]] || err_exit "echo -3 not working in ucb universe"
513typeset -F3 start_x=SECONDS total_t delay=0.02
514typeset reps=50 leeway=5
515sleep $(( 2 * leeway * reps * delay )) |
516for (( i=0 ; i < reps ; i++ ))
517do	read -N1 -t $delay
518done
519(( total_t = SECONDS - start_x ))
520if	(( total_t > leeway * reps * delay ))
521then	err_exit "read -t in pipe taking $total_t secs - $(( reps * delay )) minimum - too long"
522elif	(( total_t < reps * delay ))
523then	err_exit "read -t in pipe taking $total_t secs - $(( reps * delay )) minimum - too fast"
524fi
525$SHELL -c 'sleep $(printf "%a" .95)' 2> /dev/null || err_exit "sleep doesn't except %a format constants"
526$SHELL -c 'test \( ! -e \)' 2> /dev/null ; [[ $? == 1 ]] || err_exit 'test \( ! -e \) not working'
527[[ $(ulimit) == "$(ulimit -fS)" ]] || err_exit 'ulimit is not the same as ulimit -fS'
528tmpfile=$tmp/file.2
529print $'\nprint -r -- "${.sh.file} ${LINENO} ${.sh.lineno}"' > $tmpfile
530[[ $( . "$tmpfile") == "$tmpfile 2 1" ]] || err_exit 'dot command not working'
531print -r -- "'xxx" > $tmpfile
532[[ $($SHELL -c ". $tmpfile"$'\n print ok' 2> /dev/null) == ok ]] || err_exit 'syntax error in dot command affects next command'
533
534float sec=$SECONDS del=4
535exec 3>&2 2>/dev/null
536$SHELL -c "( sleep 1; kill -ALRM \$\$ ) & sleep $del" 2> /dev/null
537exitval=$?
538(( sec = SECONDS - sec ))
539exec 2>&3-
540(( exitval )) && err_exit "sleep doesn't exit 0 with ALRM interupt"
541(( sec > (del - 1) )) || err_exit "ALRM signal causes sleep to terminate prematurely -- expected 3 sec, got $sec"
542typeset -r z=3
543y=5
544for i in 123 z  %x a.b.c
545do	( unset $i)  2>/dev/null && err_exit "unset $i should fail"
546done
547a=()
548for i in y y  y[8] t[abc] y.d a.b  a
549do	unset $i ||  print -u2  "err_exit unset $i should not fail"
550done
551[[ $($SHELL -c 'y=3; unset 123 y;print $?$y') == 1 ]] 2> /dev/null ||  err_exit 'y is not getting unset with unset 123 y'
552[[ $($SHELL -c 'trap foo TERM; (trap;(trap) )') == 'trap -- foo TERM' ]] || err_exit 'traps not getting reset when subshell is last process'
553
554n=$(printf "%b" 'a\0b\0c' | wc -c)
555(( n == 5 )) || err_exit '\0 not working with %b format with printf'
556
557t=$(ulimit -t)
558[[ $($SHELL -c 'ulimit -v 15000 2>/dev/null; ulimit -t') == "$t" ]] || err_exit 'ulimit -v changes ulimit -t'
559
560$SHELL 2> /dev/null -c 'cd ""' && err_exit 'cd "" not producing an error'
561[[ $($SHELL 2> /dev/null -c 'cd "";print hi') != hi ]] && err_exit 'cd "" should not terminate script'
562
563bincat=$(whence -p cat)
564builtin cat
565out=$tmp/seq.out
566seq 11 >$out
567cmp -s <(print -- "$($bincat<( $bincat $out ) )") <(print -- "$(cat <( cat $out ) )") || err_exit "builtin cat differs from $bincat"
568
569[[ $($SHELL -c '{ printf %R "["; print ok;}' 2> /dev/null) == ok ]] || err_exit $'\'printf %R "["\' causes shell to abort'
570
571v=$( $SHELL -c $'
572	trap \'print "usr1"\' USR1
573	trap exit USR2
574	sleep 1 && {
575		kill -USR1 $$ && sleep 1
576		kill -0 $$ 2>/dev/null && kill -USR2 $$
577	} &
578	sleep 2 | read
579	echo done
580' ) 2> /dev/null
581[[ $v == $'usr1\ndone' ]] ||  err_exit 'read not terminating when receiving USR1 signal'
582
583mkdir $tmp/tmpdir1
584cd $tmp/tmpdir1
585pwd=$PWD
586cd ../tmpdir1
587[[ $PWD == "$pwd" ]] || err_exit 'cd ../tmpdir1 causes directory to change'
588cd "$pwd"
589mv $tmp/tmpdir1 $tmp/tmpdir2
590cd ..  2> /dev/null || err_exit 'cannot change directory to .. after current directory has been renamed'
591[[ $PWD == "$tmp" ]] || err_exit 'after "cd $tmp/tmpdir1; cd .." directory is not $tmp'
592
593cd "$tmp"
594mkdir $tmp/tmpdir2/foo
595pwd=$PWD
596cd $tmp/tmpdir2/foo
597mv $tmp/tmpdir2 $tmp/tmpdir1
598cd ../.. 2> /dev/null || err_exit 'cannot change directory to ../.. after current directory has been renamed'
599[[ $PWD == "$tmp" ]] || err_exit 'after "cd $tmp/tmpdir2; cd ../.." directory is not $tmp'
600cd "$tmp"
601rm -rf tmpdir1
602
603cd /etc
604cd ..
605[[ $(pwd) == / ]] || err_exit 'cd /etc;cd ..;pwd is not /'
606cd /etc
607cd ../..
608[[ $(pwd) == / ]] || err_exit 'cd /etc;cd ../..;pwd is not /'
609cd /etc
610cd .././..
611[[ $(pwd) == / ]] || err_exit 'cd /etc;cd .././..;pwd is not /'
612cd /usr/bin
613cd ../..
614[[ $(pwd) == / ]] || err_exit 'cd /usr/bin;cd ../..;pwd is not /'
615cd /usr/bin
616cd ..
617[[ $(pwd) == /usr ]] || err_exit 'cd /usr/bin;cd ..;pwd is not /usr'
618cd "$tmp"
619if	mkdir $tmp/t1
620then	(
621		cd $tmp/t1
622		> real_t1
623		(
624			cd ..
625			mv t1 t2
626			mkdir t1
627		)
628		[[ -f real_t1 ]] || err_exit 'real_t1 not found after parent directory renamed in subshell'
629	)
630fi
631cd "$tmp"
632
633$SHELL +E -i <<- \! && err_exit 'interactive shell should not exit 0 after false'
634	false
635	exit
636!
637
638if	kill -L > /dev/null 2>&1
639then	[[ $(kill -l HUP) == "$(kill -L HUP)" ]] || err_exit 'kill -l and kill -L are not the same when given a signal name'
640	[[ $(kill -l 9) == "$(kill -L 9)" ]] || err_exit 'kill -l and kill -L are not the same when given a signal number'
641	[[ $(kill -L) == *'9) KILL'* ]] || err_exit 'kill -L output does not contain 9) KILL'
642fi
643
644unset ENV
645v=$($SHELL 2> /dev/null +o rc -ic $'getopts a:bc: opt --man\nprint $?')
646[[ $v == 2* ]] || err_exit 'getopts --man does not exit 2 for interactive shells'
647
648read baz <<< 'foo\\\\bar'
649[[ $baz == 'foo\\bar' ]] || err_exit 'read of foo\\\\bar not getting foo\\bar'
650
651: ~root
652[[ $(builtin) == *.sh.tilde* ]] &&  err_exit 'builtin contains .sh.tilde'
653
654exit $((Errors<125?Errors:125))
655