1*4887Schin########################################################################
2*4887Schin#                                                                      #
3*4887Schin#               This software is part of the ast package               #
4*4887Schin#           Copyright (c) 1982-2007 AT&T Knowledge Ventures            #
5*4887Schin#                      and is licensed under the                       #
6*4887Schin#                  Common Public License, Version 1.0                  #
7*4887Schin#                      by AT&T Knowledge Ventures                      #
8*4887Schin#                                                                      #
9*4887Schin#                A copy of the License is available at                 #
10*4887Schin#            http://www.opensource.org/licenses/cpl1.0.txt             #
11*4887Schin#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
12*4887Schin#                                                                      #
13*4887Schin#              Information and Software Systems Research               #
14*4887Schin#                            AT&T Research                             #
15*4887Schin#                           Florham Park NJ                            #
16*4887Schin#                                                                      #
17*4887Schin#                  David Korn <dgk@research.att.com>                   #
18*4887Schin#                                                                      #
19*4887Schin########################################################################
20*4887Schinfunction err_exit
21*4887Schin{
22*4887Schin	print -u2 -n "\t"
23*4887Schin	print -u2 -r ${Command}[$1]: "${@:2}"
24*4887Schin	let Errors+=1
25*4887Schin}
26*4887Schinalias err_exit='err_exit $LINENO'
27*4887Schin
28*4887Schin# test shell builtin commands
29*4887SchinCommand=${0##*/}
30*4887Schininteger Errors=0
31*4887Schinbuiltin getconf
32*4887Schin: ${foo=bar} || err_exit ": failed"
33*4887Schin[[ $foo = bar ]] || err_exit ": side effects failed"
34*4887Schinset -- - foobar
35*4887Schin[[ $# = 2 && $1 = - && $2 = foobar ]] || err_exit "set -- - foobar failed"
36*4887Schinset -- -x foobar
37*4887Schin[[ $# = 2 && $1 = -x && $2 = foobar ]] || err_exit "set -- -x foobar failed"
38*4887Schingetopts :x: foo || err_exit "getopts :x: returns false"
39*4887Schin[[ $foo = x && $OPTARG = foobar ]] || err_exit "getopts :x: failed"
40*4887SchinOPTIND=1
41*4887Schingetopts :r:s var -r
42*4887Schinif	[[ $var != : || $OPTARG != r ]]
43*4887Schinthen	err_exit "'getopts :r:s var -r' not working"
44*4887Schinfi
45*4887SchinOPTIND=1
46*4887Schingetopts :d#u var -d 100
47*4887Schinif	[[ $var != d || $OPTARG != 100 ]]
48*4887Schinthen	err_exit "'getopts :d#u var -d 100' not working var=$var"
49*4887Schinfi
50*4887SchinOPTIND=1
51*4887Schinwhile getopts 'ab' option -a -b
52*4887Schindo	[[ $OPTIND == $((OPTIND)) ]] || err_exit "OPTIND optimization bug"
53*4887Schindone
54*4887Schin
55*4887SchinUSAGE=$'[-][S:server?Operate on the specified \asubservice\a:]:[subservice:=pmserver]
56*4887Schin    {
57*4887Schin        [p:pmserver]
58*4887Schin        [r:repserver]
59*4887Schin        [11:notifyd]
60*4887Schin    }'
61*4887Schinset pmser p rep r notifyd -11
62*4887Schinwhile	(( $# > 1 ))
63*4887Schindo	OPTIND=1
64*4887Schin	getopts "$USAGE" OPT -S $1
65*4887Schin	[[ $OPT == S && $OPTARG == $2 ]] || err_exit "OPT=$OPT OPTARG=$OPTARG -- expected OPT=S OPTARG=$2"
66*4887Schin	shift 2
67*4887Schindone
68*4887Schin
69*4887Schinfalse ${foo=bar} &&  err_exit "false failed"
70*4887Schinread <<!
71*4887Schinhello world
72*4887Schin!
73*4887Schin[[ $REPLY = 'hello world' ]] || err_exit "read builtin failed"
74*4887Schinprint x:y | IFS=: read a b
75*4887Schinif	[[ $a != x ]]
76*4887Schinthen	err_exit "IFS=: read ... not working"
77*4887Schinfi
78*4887Schinread <<!
79*4887Schinhello \
80*4887Schinworld
81*4887Schin!
82*4887Schin[[ $REPLY = 'hello world' ]] || err_exit "read continuation failed"
83*4887Schinread -d x <<!
84*4887Schinhello worldxfoobar
85*4887Schin!
86*4887Schin[[ $REPLY = 'hello world' ]] || err_exit "read builtin failed"
87*4887Schinread <<\!
88*4887Schinhello \
89*4887Schin	world \
90*4887Schin
91*4887Schin!
92*4887Schin[[ $REPLY == 'hello 	world' ]] || err_exit "read continuation2 failed"
93*4887Schinprint "one\ntwo" | { read line
94*4887Schin	print $line | /bin/cat > /dev/null
95*4887Schin	read line
96*4887Schin}
97*4887Schinread <<\!
98*4887Schin\
99*4887Schina\
100*4887Schin\
101*4887Schin\
102*4887Schinb
103*4887Schin!
104*4887Schinif	[[ $REPLY != ab ]]
105*4887Schinthen	err_exit "read multiple continuation failed"
106*4887Schinfi
107*4887Schinif	[[ $line != two ]]
108*4887Schinthen	err_exit "read from pipeline failed"
109*4887Schinfi
110*4887Schinline=two
111*4887Schinread line < /dev/null
112*4887Schinif	[[ $line != "" ]]
113*4887Schinthen	err_exit "read from /dev/null failed"
114*4887Schinfi
115*4887Schinif	[[ $(print -R -) != - ]]
116*4887Schinthen	err_exit "print -R not working correctly"
117*4887Schinfi
118*4887Schinif	[[ $(print -- -) != - ]]
119*4887Schinthen	err_exit "print -- not working correctly"
120*4887Schinfi
121*4887Schinprint -f "hello%nbar\n" size > /dev/null
122*4887Schinif	((	size != 5 ))
123*4887Schinthen	err_exit "%n format of printf not working"
124*4887Schinfi
125*4887Schinprint -n -u2 2>&1-
126*4887Schin[[ -w /dev/fd/1 ]] || err_exit "2<&1- with built-ins has side effects"
127*4887Schinx=$0
128*4887Schinif	[[ $(eval 'print $0') != $x ]]
129*4887Schinthen	err_exit '$0 not correct for eval'
130*4887Schinfi
131*4887Schinunset x
132*4887Schinreadonly x
133*4887Schinset -- $(readonly)
134*4887Schinif      [[ " $@ " != *" x "* ]]
135*4887Schinthen    err_exit 'unset readonly variables are not displayed'
136*4887Schinfi
137*4887Schinif	[[ $(	for i in foo bar
138*4887Schin		do	print $i
139*4887Schin			continue 10
140*4887Schin		done
141*4887Schin	    ) != $'foo\nbar' ]]
142*4887Schinthen	err_exit 'continue breaks out of loop'
143*4887Schinfi
144*4887Schin(continue bad 2>/dev/null && err_exit 'continue bad should return an error')
145*4887Schin(break bad 2>/dev/null && err_exit 'break bad should return an error')
146*4887Schin(continue 0 2>/dev/null && err_exit 'continue 0 should return an error')
147*4887Schin(break 0 2>/dev/null && err_exit 'break 0 should return an error')
148*4887Schinbreakfun() { break;}
149*4887Schincontinuefun() { continue;}
150*4887Schinfor fun in break continue
151*4887Schindo	if	[[ $(	for i in foo
152*4887Schin			do	${fun}fun
153*4887Schin				print $i
154*4887Schin			done
155*4887Schin		) != foo ]]
156*4887Schin	then	err_exit "$fun call in ${fun}fun breaks out of for loop"
157*4887Schin	fi
158*4887Schindone
159*4887Schinif	[[ $(print -f "%b" "\a\n\v\b\r\f\E\03\\oo") != $'\a\n\v\b\r\f\E\03\\oo' ]]
160*4887Schinthen	err_exit 'print -f "%b" not working'
161*4887Schinfi
162*4887Schinif	[[ $(print -f "%P" "[^x].*b$") != '*[!x]*b' ]]
163*4887Schinthen	err_exit 'print -f "%P" not working'
164*4887Schinfi
165*4887Schinif	[[ $(abc: for i in foo bar;do print $i;break abc;done) != foo ]]
166*4887Schinthen	err_exit 'break labels not working'
167*4887Schinfi
168*4887Schinif	[[ $(command -v if)	!= if ]]
169*4887Schinthen	err_exit	'command -v not working'
170*4887Schinfi
171*4887Schinread -r var <<\!
172*4887Schin
173*4887Schin!
174*4887Schinif	[[ $var != "" ]]
175*4887Schinthen	err_exit "read -r of blank line not working"
176*4887Schinfi
177*4887Schinmkdir -p /tmp/ksh$$/a/b/c 2>/dev/null || err_exit  "mkdir -p failed"
178*4887Schin$SHELL -c "cd /tmp/ksh$$/a/b; cd c" 2>/dev/null || err_exit "initial script relative cd fails"
179*4887Schinrm -r /tmp/ksh$$ || err_exit "rm -r /tmp/ksh$$ failed"
180*4887Schintrap 'print HUP' HUP
181*4887Schinif	[[ $(trap) != "trap -- 'print HUP' HUP" ]]
182*4887Schinthen	err_exit '$(trap) not working'
183*4887Schinfi
184*4887Schinif	[[ $(trap -p HUP) != 'print HUP' ]]
185*4887Schinthen	err_exit '$(trap -p HUP) not working'
186*4887Schinfi
187*4887Schin[[ $($SHELL -c 'trap "print ok" SIGTERM; kill -s SIGTERM $$' 2> /dev/null) == ok
188*4887Schin ]] || err_exit 'SIGTERM not recognized'
189*4887Schin[[ $($SHELL -c 'trap "print ok" sigterm; kill -s sigterm $$' 2> /dev/null) == ok
190*4887Schin ]] || err_exit 'SIGTERM not recognized'
191*4887Schin${SHELL} -c 'kill -1 -$$' 2> /dev/null
192*4887Schin[[ $(kill -l $?) == HUP ]] || err_exit 'kill -1 -pid not working'
193*4887Schin${SHELL} -c 'kill -1 -$$' 2> /dev/null
194*4887Schin[[ $(kill -l $?) == HUP ]] || err_exit 'kill -n1 -pid not working'
195*4887Schin${SHELL} -c 'kill -s HUP -$$' 2> /dev/null
196*4887Schin[[ $(kill -l $?) == HUP ]] || err_exit 'kill -HUP -pid not working'
197*4887Schinn=123
198*4887Schintypeset -A base
199*4887Schinbase[o]=8#
200*4887Schinbase[x]=16#
201*4887Schinbase[X]=16#
202*4887Schinfor i in d i o u x X
203*4887Schindo	if	(( $(( ${base[$i]}$(printf "%$i" $n) )) != n  ))
204*4887Schin	then	err_exit "printf %$i not working"
205*4887Schin	fi
206*4887Schindone
207*4887Schinif	[[ $( trap 'print done' EXIT) != done ]]
208*4887Schinthen	err_exit 'trap on EXIT not working'
209*4887Schinfi
210*4887Schinif	[[ $( trap 'print done' EXIT; trap - EXIT) == done ]]
211*4887Schinthen	err_exit 'trap on EXIT not being cleared'
212*4887Schinfi
213*4887Schinif	[[ $(type test) != 'test is a shell builtin' ]]
214*4887Schinthen	err_exit 'whence -v test not a builtin'
215*4887Schinfi
216*4887Schinbuiltin -d test
217*4887Schinif	[[ $(type test) == *builtin* ]]
218*4887Schinthen	err_exit 'whence -v test after builtin -d incorrect'
219*4887Schinfi
220*4887Schintypeset -Z3 percent=$(printf '%o\n' "'%'")
221*4887Schinforrmat=\\${percent}s
222*4887Schinif      [[ $(printf "$forrmat") != %s ]]
223*4887Schinthen    err_exit "printf $forrmat not working"
224*4887Schinfi
225*4887Schinif	(( $(printf 'x\0y' | wc -c) != 3 ))
226*4887Schinthen	err_exit 'printf \0 not working'
227*4887Schinfi
228*4887Schinif	[[ $(printf "%bx%s\n" 'f\to\cbar') != $'f\to' ]]
229*4887Schinthen	err_exit 'printf %bx%s\n  not working'
230*4887Schinfi
231*4887Schinalpha=abcdefghijklmnop
232*4887Schinif	[[ $(printf "%10.*s\n" 5 $alpha) != '     abcde' ]]
233*4887Schinthen	err_exit 'printf %10.%s\n  not working'
234*4887Schinfi
235*4887Schinfloat x2=.0000625
236*4887Schinif	[[ $(printf "%10.5E\n" x2) != 6.25000E-05 ]]
237*4887Schinthen	err_exit 'printf "%10.5E" not normalizing correctly'
238*4887Schinfi
239*4887Schinx2=.000000001
240*4887Schinif	[[ $(printf "%g\n" x2 2>/dev/null) != 1e-09 ]]
241*4887Schinthen	err_exit 'printf "%g" not working correctly'
242*4887Schinfi
243*4887Schin#FIXME#($SHELL read -s foobar <<\!
244*4887Schin#FIXME#testing
245*4887Schin#FIXME#!
246*4887Schin#FIXME#) 2> /dev/null || err_exit ksh read -s var fails
247*4887Schinif	[[ $(printf +3 2>/dev/null) !=   +3 ]]
248*4887Schinthen	err_exit 'printf is not processing formats beginning with + correctly'
249*4887Schinfi
250*4887Schinif	printf "%d %d\n" 123bad 78 >/dev/null 2>/dev/null
251*4887Schinthen	err_exit "printf not exiting non-zero with conversion errors"
252*4887Schinfi
253*4887Schinif	[[ $(trap --version 2> /dev/null;print done) != done ]]
254*4887Schinthen	err_exit 'trap builtin terminating after --version'
255*4887Schinfi
256*4887Schinif	[[ $(set --version 2> /dev/null;print done) != done ]]
257*4887Schinthen	err_exit 'set builtin terminating after --veresion'
258*4887Schinfi
259*4887Schinunset -f foobar
260*4887Schinfunction foobar
261*4887Schin{
262*4887Schin	print 'hello world'
263*4887Schin}
264*4887SchinOPTIND=1
265*4887Schinif	[[ $(getopts  $'[+?X\ffoobar\fX]' v --man 2>&1) != *'Xhello world'X* ]]
266*4887Schinthen	err_exit '\f...\f not working in getopts usage strings'
267*4887Schinfi
268*4887Schinif	[[	$(printf '%H\n' $'<>"& \'\tabc') != '&lt;&gt;&quot;&amp;&nbsp;&apos;&#9;abc' ]]
269*4887Schinthen	err_exit 'printf %H not working'
270*4887Schinfi
271*4887Schinif	[[	$(printf '%R %R %R %R\n' 'a.b' '*.c' '^'  '!(*.*)') != '^a\.b$ \.c$ ^\^$ ^(.*\..*)!$' ]]
272*4887Schinthen	err_exit 'printf %R not working'
273*4887Schinfi
274*4887Schinif	[[ $(printf '%..:c\n' abc) != a:b:c ]]
275*4887Schinthen	err_exit	"printf '%..:c' not working"
276*4887Schinfi
277*4887Schinif	[[ $(printf '%..*c\n' : abc) != a:b:c ]]
278*4887Schinthen	err_exit	"printf '%..*c' not working"
279*4887Schinfi
280*4887Schinif	[[ $(printf '%..:s\n' abc def ) != abc:def ]]
281*4887Schinthen	err_exit	"printf '%..:s' not working"
282*4887Schinfi
283*4887Schinif	[[ $(printf '%..*s\n' : abc def) != abc:def ]]
284*4887Schinthen	err_exit	"printf '%..*s' not working"
285*4887Schinfi
286*4887Schin[[ $(printf '%q\n') == '' ]] || err_exit 'printf "%q" with missing arguments'
287*4887Schin# we won't get hit by the one second boundary twice, right?
288*4887Schin[[ $(printf '%T\n' now) == "$(date)" ]] ||
289*4887Schin[[ $(printf '%T\n' now) == "$(date)" ]] ||
290*4887Schinerr_exit 'printf "%T" now'
291*4887Schinbehead()
292*4887Schin{
293*4887Schin	read line
294*4887Schin	left=$(cat)
295*4887Schin}
296*4887Schinprint $'line1\nline2' | behead
297*4887Schinif	[[ $left != line2 ]]
298*4887Schinthen	err_exit  "read reading ahead on a pipe"
299*4887Schinfi
300*4887Schinread -n1 y <<!
301*4887Schinabc
302*4887Schin!
303*4887Schinif      [[ $y != a ]]
304*4887Schinthen    err_exit  'read -n1 not working'
305*4887Schinfi
306*4887Schinprint -n $'{ read -r line;print $line;}\nhello' > /tmp/ksh$$
307*4887Schinchmod 755 /tmp/ksh$$
308*4887Schintrap 'rm -rf /tmp/ksh$$' EXIT
309*4887Schinif	[[ $($SHELL < /tmp/ksh$$) != hello ]]
310*4887Schinthen	err_exit 'read of incomplete line not working correctly'
311*4887Schinfi
312*4887Schinset -f
313*4887Schinset -- *
314*4887Schinif      [[ $1 != '*' ]]
315*4887Schinthen    err_exit 'set -f not working'
316*4887Schinfi
317*4887Schinunset pid1 pid2
318*4887Schinfalse &
319*4887Schinpid1=$!
320*4887Schinpid2=$(
321*4887Schin	wait $pid1
322*4887Schin	(( $? == 127 )) || err_exit "job known to subshell"
323*4887Schin	print $!
324*4887Schin)
325*4887Schinwait $pid1
326*4887Schin(( $? == 1 )) || err_exit "wait not saving exit value"
327*4887Schinwait $pid2
328*4887Schin(( $? == 127 )) || err_exit "subshell job known to parent"
329*4887Schinset --noglob
330*4887Schinifs=$IFS
331*4887SchinIFS=,
332*4887Schinset -- $(getconf LIBPATH)
333*4887SchinIFS=$ifs
334*4887Schinenv=
335*4887Schinfor v
336*4887Schindo	IFS=:
337*4887Schin	set -- $v
338*4887Schin	IFS=$ifs
339*4887Schin	eval [[ \$$2 ]] && env="$env $2=\"\$$2\""
340*4887Schindone
341*4887Schinset --glob
342*4887Schinif	[[ $(foo=bar; eval foo=\$foo $env exec -c \$SHELL -c \'print \$foo\') != bar ]]
343*4887Schinthen	err_exit '"name=value exec -c ..." not working'
344*4887Schinfi
345*4887Schin$SHELL -c 'OPTIND=-1000000; getopts a opt -a' 2> /dev/null
346*4887Schin[[ $? == 1 ]] || err_exit 'getopts with negative OPTIND not working'
347*4887Schingetopts 'n#num' opt  -n 3
348*4887Schin[[ $OPTARG == 3 ]] || err_exit 'getopts with numerical arguments failed'
349*4887Schinif	[[ $($SHELL -c $'printf \'%2$s %1$s\n\' world hello') != 'hello world' ]]
350*4887Schinthen	err_exit 'printf %2$s %1$s not working'
351*4887Schinfi
352*4887Schin((n=0))
353*4887Schin((n++)); ARGC[$n]=1 ARGV[$n]=""
354*4887Schin((n++)); ARGC[$n]=2 ARGV[$n]="-a"
355*4887Schin((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2"
356*4887Schin((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2 x"
357*4887Schin((n++)); ARGC[$n]=4 ARGV[$n]="-a -v 2 x y"
358*4887Schinfor ((i=1; i<=n; i++))
359*4887Schindo	set -- ${ARGV[$i]}
360*4887Schin	OPTIND=0
361*4887Schin	while	getopts -a tst "av:" OPT
362*4887Schin	do	:
363*4887Schin	done
364*4887Schin	if	[[ $OPTIND != ${ARGC[$i]} ]]
365*4887Schin	then	err_exit "\$OPTIND after getopts loop incorrect -- got $OPTIND, expected ${ARGC[$i]}"
366*4887Schin	fi
367*4887Schindone
368*4887Schinunset a
369*4887Schin{ read -N3 a; read -N1 b;}  <<!
370*4887Schinabcdefg
371*4887Schin!
372*4887Schin[[ $a == abc ]] || err_exit 'read -N3 here-document not working'
373*4887Schin[[ $b == d ]] || err_exit 'read -N1 here-document not working'
374*4887Schinread -n3 a <<!
375*4887Schinabcdefg
376*4887Schin!
377*4887Schin[[ $a == abc ]] || err_exit 'read -n3 here-document not working'
378*4887Schin(print -n a;sleep 1; print -n bcde) | { read -N3 a; read -N1 b;}
379*4887Schin[[ $a == abc ]] || err_exit 'read -N3 from pipe not working'
380*4887Schin[[ $b == d ]] || err_exit 'read -N1 from pipe not working'
381*4887Schin(print -n a;sleep 1; print -n bcde) |read -n3 a
382*4887Schin[[ $a == a ]] || err_exit 'read -n3 from pipe not working'
383*4887Schinrm -f /tmp/fifo$$
384*4887Schinif	mkfifo /tmp/fifo$$ 2> /dev/null
385*4887Schinthen	(print -n a; sleep 1;print -n bcde)  > /tmp/fifo$$ &
386*4887Schin	{
387*4887Schin	read -u5 -n3  -t2 a  || err_exit 'read -n3 from fifo timedout'
388*4887Schin	read -u5 -n1 -t2 b || err_exit 'read -n1 from fifo timedout'
389*4887Schin	} 5< /tmp/fifo$$
390*4887Schin	[[ $a == a ]] || err_exit 'read -n3 from fifo not working'
391*4887Schin	rm -f /tmp/fifo$$
392*4887Schin	mkfifo /tmp/fifo$$ 2> /dev/null
393*4887Schin	(print -n a; sleep 1;print -n bcde)  > /tmp/fifo$$ &
394*4887Schin	{
395*4887Schin	read -u5 -N3 -t2 a || err_exit 'read -N3 from fifo timed out'
396*4887Schin	read -u5 -N1 -t2 b || err_exit 'read -N1 from fifo timedout'
397*4887Schin	} 5< /tmp/fifo$$
398*4887Schin	[[ $a == abc ]] || err_exit 'read -N3 from fifo not working'
399*4887Schin	[[ $b == d ]] || err_exit 'read -N1 from fifo not working'
400*4887Schinfi
401*4887Schinrm -f /tmp/fifo$$
402*4887Schinfunction longline
403*4887Schin{
404*4887Schin	integer i
405*4887Schin	for((i=0; i < $1; i++))
406*4887Schin	do	print argument$i
407*4887Schin	done
408*4887Schin}
409*4887Schin# test command -x option
410*4887Schininteger sum=0 n=10000
411*4887Schinif	! ${SHELL:-ksh} -c 'print $#' count $(longline $n) > /dev/null  2>&1
412*4887Schinthen	for i in $(command command -x ${SHELL:-ksh} -c 'print $#;[[ $1 != argument0 ]]' count $(longline $n) 2> /dev/null)
413*4887Schin	do	((sum += $i))
414*4887Schin	done
415*4887Schin	(( sum == n )) || err_exit "command -x processed only $sum arguments"
416*4887Schin	command -p command -x ${SHELL:-ksh} -c 'print $#;[[ $1 == argument0 ]]' count $(longline $n) > /dev/null  2>&1
417*4887Schin	[[ $? != 1 ]] && err_exit 'incorrect exit status for command -x'
418*4887Schinfi
419*4887Schin# test command -x option with extra arguments
420*4887Schininteger sum=0 n=10000
421*4887Schinif      ! ${SHELL:-ksh} -c 'print $#' count $(longline $n) > /dev/null  2>&1
422*4887Schinthen    for i in $(command command -x ${SHELL:-ksh} -c 'print $#;[[ $1 != argument0 ]]' count $(longline $n) one two three) #2> /dev/null)
423*4887Schin	do      ((sum += $i))
424*4887Schin	done
425*4887Schin	(( sum  > n )) || err_exit "command -x processed only $sum arguments"
426*4887Schin	(( (sum-n)%3==0 )) || err_exit "command -x processed only $sum arguments"
427*4887Schin	(( sum == n+3)) && err_exit "command -x processed only $sum arguments"
428*4887Schin	command -p command -x ${SHELL:-ksh} -c 'print $#;[[ $1 == argument0 ]]' count $(longline $n) > /dev/null  2>&1
429*4887Schin	[[ $? != 1 ]] && err_exit 'incorrect exit status for command -x'
430*4887Schinfi
431*4887Schin# test for debug trap
432*4887Schin[[ $(typeset -i i=0
433*4887Schin	trap 'print $i' DEBUG
434*4887Schin	while (( i <2))
435*4887Schin	do	(( i++))
436*4887Schin	done) == $'0\n0\n1\n1\n2' ]]  || err_exit  "DEBUG trap not working"
437*4887Schingetconf UNIVERSE - ucb
438*4887Schin[[ $($SHELL -c 'echo -3') == -3 ]] || err_exit "echo -3 not working in ucb universe"
439*4887Schintypeset -F3 start_x=SECONDS total_t delay=0.02
440*4887Schintypeset reps=50 leeway=5
441*4887Schinsleep $(( 2 * leeway * reps * delay )) |
442*4887Schinfor (( i=0 ; i < reps ; i++ ))
443*4887Schindo	read -N1 -t $delay
444*4887Schindone
445*4887Schin(( total_t = SECONDS - start_x ))
446*4887Schinif	(( total_t > leeway * reps * delay ))
447*4887Schinthen	err_exit "read -t in pipe taking $total_t secs - $(( reps * delay )) minimum - too long"
448*4887Schinelif	(( total_t < reps * delay ))
449*4887Schinthen	err_exit "read -t in pipe taking $total_t secs - $(( reps * delay )) minimum - too fast"
450*4887Schinfi
451*4887Schinexit $((Errors))
452