xref: /onnv-gate/usr/src/lib/libshell/common/tests/io.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
308462SApril.Chin@Sun.COM
3110898Sroland.mainz@nrubsig.orgtmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
3210898Sroland.mainz@nrubsig.orgtrap "cd /; rm -rf $tmp" EXIT
3310898Sroland.mainz@nrubsig.org
348462SApril.Chin@Sun.COMunset HISTFILE
358462SApril.Chin@Sun.COM
364887Schinfunction fun
374887Schin{
3810898Sroland.mainz@nrubsig.org	while  command exec 3>&1
3910898Sroland.mainz@nrubsig.org	do	break
404887Schin	done 2>   /dev/null
414887Schin	print -u3 good
424887Schin}
4310898Sroland.mainz@nrubsig.orgprint 'read -r a;print -r -u$1 -- "$a"' > $tmp/mycat
4410898Sroland.mainz@nrubsig.orgchmod 755 $tmp/mycat
454887Schinfor ((i=3; i < 10; i++))
464887Schindo
4710898Sroland.mainz@nrubsig.org	eval "a=\$(print foo | $tmp/mycat" $i $i'>&1 > /dev/null |cat)' 2> /dev/null
484887Schin	[[ $a == foo ]] || err_exit "bad file descriptor $i in comsub script"
494887Schindone
504887Schinexec 3> /dev/null
514887Schin[[ $(fun) == good ]] || err_exit 'file 3 closed before subshell completes'
524887Schinexec 3>&-
5310898Sroland.mainz@nrubsig.orgcd $tmp || { err_exit "cd $tmp failed"; exit ; }
544887Schinprint foo > file1
554887Schinprint bar >> file1
564887Schinif	[[ $(<file1) != $'foo\nbar' ]]
574887Schinthen	err_exit 'append (>>) not working'
584887Schinfi
594887Schinset -o noclobber
604887Schinexec 3<> file1
614887Schinread -u3 line
6210898Sroland.mainz@nrubsig.orgexp=foo
6310898Sroland.mainz@nrubsig.orgif	[[ $line != $exp ]]
6410898Sroland.mainz@nrubsig.orgthen	err_exit "read on <> fd failed -- expected '$exp', got '$line'"
654887Schinfi
664887Schinif	( 4> file1 ) 2> /dev/null
674887Schinthen	err_exit 'noclobber not causing exclusive open'
684887Schinfi
694887Schinset +o noclobber
7010898Sroland.mainz@nrubsig.org
7110898Sroland.mainz@nrubsig.orgFDFS=(
7210898Sroland.mainz@nrubsig.org	( dir=/proc/self/fd	semantics='open'	)
7310898Sroland.mainz@nrubsig.org	( dir=/proc/$$/fd	semantics='open'	)
7410898Sroland.mainz@nrubsig.org	( dir=/dev/fd		semantics='open|dup'	)
7510898Sroland.mainz@nrubsig.org	( dir=/dev/fd		semantics='dup'	)
7610898Sroland.mainz@nrubsig.org)
7710898Sroland.mainz@nrubsig.orgfor ((fdfs=0; fdfs<${#FDFS[@]}-1; fdfs++))
7810898Sroland.mainz@nrubsig.orgdo	[[ -e ${FDFS[fdfs].dir} ]] && { command : > ${FDFS[fdfs].dir}/1; } 2>/dev/null && break
7910898Sroland.mainz@nrubsig.orgdone
8010898Sroland.mainz@nrubsig.org
8110898Sroland.mainz@nrubsig.orgexec 3<> file1
8210898Sroland.mainz@nrubsig.orgif	command exec 4< ${FDFS[fdfs].dir}/3
8310898Sroland.mainz@nrubsig.orgthen	read -u3 got
8410898Sroland.mainz@nrubsig.org	read -u4 got
8510898Sroland.mainz@nrubsig.org	exp='foo|bar'
8610898Sroland.mainz@nrubsig.org	case $got in
8710898Sroland.mainz@nrubsig.org	foo)	semantics='open' ;;
8810898Sroland.mainz@nrubsig.org	bar)	semantics='dup' ;;
8910898Sroland.mainz@nrubsig.org	*)	semantics='failed' ;;
9010898Sroland.mainz@nrubsig.org	esac
9110898Sroland.mainz@nrubsig.org	[[ $semantics == @(${FDFS[fdfs].semantics}) ]] || err_exit "'4< ${FDFS[fdfs].dir}/3' $semantics semantics instead of ${FDFS[fdfs].semantics} -- expected '$exp', got '$got'"
924887Schinfi
9310898Sroland.mainz@nrubsig.org
9410898Sroland.mainz@nrubsig.org# 2004-11-25 ancient /dev/fd/N redirection bug fix
9510898Sroland.mainz@nrubsig.orggot=$(
9610898Sroland.mainz@nrubsig.org	{
9710898Sroland.mainz@nrubsig.org		print -n 1
9810898Sroland.mainz@nrubsig.org		print -n 2 > ${FDFS[fdfs].dir}/2
9910898Sroland.mainz@nrubsig.org		print -n 3
10010898Sroland.mainz@nrubsig.org		print -n 4 > ${FDFS[fdfs].dir}/2
10110898Sroland.mainz@nrubsig.org	}  2>&1
10210898Sroland.mainz@nrubsig.org)
10310898Sroland.mainz@nrubsig.orgexp='1234|4'
10410898Sroland.mainz@nrubsig.orgcase $got in
10510898Sroland.mainz@nrubsig.org1234)	semantics='dup' ;;
10610898Sroland.mainz@nrubsig.org4)	semantics='open' ;;
10710898Sroland.mainz@nrubsig.org*)	semantics='failed' ;;
10810898Sroland.mainz@nrubsig.orgesac
10910898Sroland.mainz@nrubsig.org[[ $semantics == @(${FDFS[fdfs].semantics}) ]] || err_exit "${FDFS[fdfs].dir}/N $semantics semantics instead of ${FDFS[fdfs].semantics} -- expected '$exp', got '$got'"
11010898Sroland.mainz@nrubsig.org
1114887Schincat > close0 <<\!
1124887Schinexec 0<&-
1134887Schinecho $(./close1)
1144887Schin!
1154887Schinprint "echo abc" > close1
1164887Schinchmod +x close0 close1
1174887Schinx=$(./close0)
1184887Schinif	[[ $x != "abc" ]]
1194887Schinthen	err_exit "picked up file descriptor zero for opening script file"
1204887Schinfi
1214887Schincat > close0 <<\!
1224887Schin	for ((i=0; i < 1100; i++))
1234887Schin	do	exec 4< /dev/null
1244887Schin		read -u4
1254887Schin	done
1264887Schin	exit 0
1274887Schin!
1284887Schin./close0 2> /dev/null || err_exit "multiple exec 4< /dev/null can fail"
1294887Schin$SHELL -c '
13010898Sroland.mainz@nrubsig.org	trap "rm -f in out" EXIT
1314887Schin	for ((i = 0; i < 1000; i++))
1324887Schin	do	print -r -- "This is a test"
13310898Sroland.mainz@nrubsig.org	done > in
13410898Sroland.mainz@nrubsig.org	> out
13510898Sroland.mainz@nrubsig.org	exec 1<> out
1364887Schin	builtin cat
13710898Sroland.mainz@nrubsig.org	print -r -- "$(<in)"
13810898Sroland.mainz@nrubsig.org	cmp -s in out'  2> /dev/null
1394887Schin[[ $? == 0 ]] || err_exit 'builtin cat truncates files'
1404887Schincat >| script <<-\!
1414887Schinprint hello
1424887Schin( exec 3<&- 4<&-)
1434887Schinexec 3<&- 4<&-
1444887Schinprint world
1454887Schin!
1464887Schinchmod +x script
1474887Schin[[ $( $SHELL ./script) == $'hello\nworld' ]] || err_exit 'closing 3 & 4 causes script to fail'
1484887Schincd ~- || err_exit "cd back failed"
1494887Schin( exec  > '' ) 2> /dev/null  && err_exit '> "" does not fail'
1504887Schinunset x
1514887Schin( exec > ${x} ) 2> /dev/null && err_exit '> $x, where x null does not fail'
1524887Schinexec <<!
1534887Schinfoo
1544887Schinbar
1554887Schin!
1564887Schin( exec 0< /dev/null)
1574887Schinread line
1584887Schinif	[[ $line != foo ]]
1594887Schinthen	err_exit 'file descriptor not restored after exec in subshell'
1604887Schinfi
16110898Sroland.mainz@nrubsig.orgexec 3>&- 4>&-
1624887Schin[[ $( {
1634887Schin	read -r line;print -r -- "$line"
1644887Schin	(
1654887Schin	        read -r line;print -r -- "$line"
1664887Schin	) & wait
1674887Schin	while	read -r line
1684887Schin        do	print -r -- "$line"
1694887Schin	done
1704887Schin } << !
1714887Schinline 1
1724887Schinline 2
1734887Schinline 3
1744887Schin!) == $'line 1\nline 2\nline 3' ]] || err_exit 'read error with subshells'
1754887Schin# 2004-05-11 bug fix
17610898Sroland.mainz@nrubsig.orgcat > $tmp/1 <<- ++EOF++
17710898Sroland.mainz@nrubsig.org	script=$tmp/2
17810898Sroland.mainz@nrubsig.org	trap "rm -f \$script" EXIT
17910898Sroland.mainz@nrubsig.org	exec 9> \$script
1804887Schin	for ((i=3; i<9; i++))
18110898Sroland.mainz@nrubsig.org	do	eval "while read -u\$i; do : ;done \$i</dev/null"
18210898Sroland.mainz@nrubsig.org		print -u9 "exec \$i< /dev/null"
1834887Schin	done
1844887Schin	for ((i=0; i < 60; i++))
1854887Schin	do	print -u9 -f "%.80c\n"  ' '
1864887Schin	done
1874887Schin	print -u9 'print ok'
1884887Schin	exec 9<&-
18910898Sroland.mainz@nrubsig.org	chmod +x \$script
19010898Sroland.mainz@nrubsig.org	\$script
1914887Schin++EOF++
19210898Sroland.mainz@nrubsig.orgchmod +x $tmp/1
19310898Sroland.mainz@nrubsig.org[[ $($SHELL  $tmp/1) == ok ]]  || err_exit "parent i/o causes child script to fail"
19410898Sroland.mainz@nrubsig.org# 2004-12-20 redirection loss bug fix
19510898Sroland.mainz@nrubsig.orgcat > $tmp/1 <<- \++EOF++
1964887Schin	function a
1974887Schin	{
1984887Schin		trap 'print ok' EXIT
1994887Schin		: > /dev/null
2004887Schin	}
2014887Schin	a
2024887Schin++EOF++
20310898Sroland.mainz@nrubsig.orgchmod +x $tmp/1
20410898Sroland.mainz@nrubsig.org[[ $($tmp/1) == ok ]] || err_exit "trap on EXIT loses last command redirection"
20510898Sroland.mainz@nrubsig.orgprint > /dev/null {n}> $tmp/1
20610898Sroland.mainz@nrubsig.org[[ ! -s $tmp/1 ]] && newio=1
20710898Sroland.mainz@nrubsig.orgif	[[ $newio && $(print hello | while read -u$n; do print $REPLY; done {n}<&0) != hello ]]
2084887Schinthen	err_exit "{n}<&0 not working with for loop"
2094887Schinfi
2104887Schin[[ $({ read -r;read -u3 3<&0; print -- "$REPLY" ;} <<!
2114887Schinhello
2124887Schinworld
2134887Schin!) == world ]] || err_exit 'I/O not synchronized with <&'
2144887Schinx="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNSPQRSTUVWXYZ1234567890"
2154887Schinfor ((i=0; i < 62; i++))
2164887Schindo	printf "%.39c\n"  ${x:i:1}
21710898Sroland.mainz@nrubsig.orgdone >  $tmp/seek
21810898Sroland.mainz@nrubsig.orgif	command exec 3<> $tmp/seek
2194887Schinthen	(( $(3<#) == 0 )) || err_exit "not at position 0"
2204887Schin	(( $(3<# ((EOF))) == 40*62 )) || err_exit "not at end-of-file"
22110898Sroland.mainz@nrubsig.org	command exec 3<# ((40*8)) || err_exit "absolute seek fails"
2224887Schin	read -u3
22310898Sroland.mainz@nrubsig.org	[[ $REPLY == +(i) ]] || err_exit "expected iiii..., got $REPLY"
2244887Schin	[[ $(3<#) == $(3<# ((CUR)) ) ]] || err_exit '$(3<#)!=$(3<#((CUR)))'
2254887Schin	command exec 3<# ((CUR+80))
2264887Schin	read -u3
22710898Sroland.mainz@nrubsig.org	[[ $REPLY == {39}(l) ]] || err_exit "expected lll..., got $REPLY"
2284887Schin	command exec 3<# ((EOF-80))
2294887Schin	read -u3
23010898Sroland.mainz@nrubsig.org	[[ $REPLY == +(9) ]] || err_exit "expected 999..., got $REPLY"
2314887Schin	command exec 3># ((80))
2324887Schin	print -u3 -f "%.39c\n"  @
2334887Schin	command exec 3># ((80))
2344887Schin	read -u3
23510898Sroland.mainz@nrubsig.org	[[ $REPLY == +(@) ]] || err_exit "expected @@@..., got $REPLY"
2364887Schin	read -u3
23710898Sroland.mainz@nrubsig.org	[[ $REPLY == +(d) ]] || err_exit "expected ddd..., got $REPLY"
2384887Schin	command exec 3># ((EOF))
2394887Schin	print -u3 -f "%.39c\n"  ^
2404887Schin	(( $(3<# ((CUR-0))) == 40*63 )) || err_exit "not at extended end-of-file"
24110898Sroland.mainz@nrubsig.org	command exec 3<# ((40*62))
2424887Schin	read -u3
24310898Sroland.mainz@nrubsig.org	[[ $REPLY == +(^) ]] || err_exit "expected ddd..., got $REPLY"
2444887Schin	command exec 3<# ((0))
2454887Schin	command exec 3<# *jjjj*
2464887Schin	read -u3
2474887Schin	[[  $REPLY == {39}(j) ]] || err_exit "<# pattern failed"
2484887Schin	[[ $(command exec 3<## *llll*) = {39}(k) ]] || err_exit "<## pattern not saving standard output"
2494887Schin	read -u3
2504887Schin	[[  $REPLY == {39}(l) ]] || err_exit "<## pattern failed to position"
2514887Schin	command exec 3<# *abc*
2524887Schin	read -u3 && err_exit "not found pattern not positioning at eof"
25310898Sroland.mainz@nrubsig.org	cat $tmp/seek | read -r <# *WWW*
2544887Schin	[[ $REPLY == *WWWWW* ]] || err_exit '<# not working for pipes'
25510898Sroland.mainz@nrubsig.org	{ < $tmp/seek <# ((2358336120)) ;} 2> /dev/null || err_exit 'long seek not working'
25610898Sroland.mainz@nrubsig.orgelse	err_exit "$tmp/seek: cannot open for reading"
2574887Schinfi
2588462SApril.Chin@Sun.COMcommand exec 3<&- || 'cannot close 3'
2598462SApril.Chin@Sun.COMfor ((i=0; i < 62; i++))
2608462SApril.Chin@Sun.COMdo	printf "%.39c\n"  ${x:i:1}
26110898Sroland.mainz@nrubsig.orgdone >  $tmp/seek
26210898Sroland.mainz@nrubsig.orgif	command exec {n}<> $tmp/seek
2638462SApril.Chin@Sun.COMthen	{ command exec {n}<#((EOF)) ;} 2> /dev/null || err_exit '{n}<# not working'
2648462SApril.Chin@Sun.COM	if	$SHELL -c '{n}</dev/null' 2> /dev/null
2658462SApril.Chin@Sun.COM	then	(( $({n}<#) ==  40*62))  || err_exit '$({n}<#) not working'
2668462SApril.Chin@Sun.COM	else	err_exit 'not able to parse {n}</dev/null'
2678462SApril.Chin@Sun.COM	fi
2688462SApril.Chin@Sun.COMfi
2694887Schin$SHELL -ic '
2704887Schin{
2714887Schin    print -u2  || exit 2
2724887Schin    print -u3  || exit 3
2734887Schin    print -u4  || exit 4
2744887Schin    print -u5  || exit 5
2754887Schin    print -u6  || exit 6
2764887Schin    print -u7  || exit 7
2774887Schin    print -u8  || exit 8
2784887Schin    print -u9  || exit 9
2794887Schin}  3> /dev/null 4> /dev/null 5> /dev/null 6> /dev/null 7> /dev/null 8> /dev/null 9> /dev/null' > /dev/null 2>&1
2804887Schinexitval=$?
2814887Schin(( exitval ))  && err_exit  "print to unit $exitval failed"
28210898Sroland.mainz@nrubsig.org$SHELL -c "{ > $tmp/1 ; date;} >&- 2> /dev/null" > $tmp/2
28310898Sroland.mainz@nrubsig.org[[ -s $tmp/1 || -s $tmp/2 ]] && err_exit 'commands with standard output closed produce output'
2844887Schin$SHELL -c "$SHELL -c ': 3>&1' 1>&- 2>/dev/null" && err_exit 'closed standard output not passed to subshell'
2858462SApril.Chin@Sun.COM[[ $(cat  <<- \EOF | $SHELL
2868462SApril.Chin@Sun.COM	do_it_all()
2878462SApril.Chin@Sun.COM	{
2888462SApril.Chin@Sun.COM	 	dd 2>/dev/null  # not a ksh93 buildin
2898462SApril.Chin@Sun.COM	 	return $?
2908462SApril.Chin@Sun.COM	}
2918462SApril.Chin@Sun.COM	do_it_all ; exit $?
2928462SApril.Chin@Sun.COM	hello world
2938462SApril.Chin@Sun.COMEOF) == 'hello world' ]] || err_exit 'invalid readahead on stdin'
2948462SApril.Chin@Sun.COM$SHELL -c 'exec 3>; /dev/null'  2> /dev/null && err_exit '>; with exec should be an error'
2958462SApril.Chin@Sun.COM$SHELL -c ': 3>; /dev/null'  2> /dev/null || err_exit '>; not working with at all'
29610898Sroland.mainz@nrubsig.orgprint hello > $tmp/1
29710898Sroland.mainz@nrubsig.orgif	! $SHELL -c "false >; $tmp/1"  2> /dev/null
29810898Sroland.mainz@nrubsig.orgthen	[[ $(<$tmp/1) == hello ]] || err_exit '>; not preserving file on failure'
29910898Sroland.mainz@nrubsig.orgfi
30010898Sroland.mainz@nrubsig.orgif	! $SHELL -c "sed -e 's/hello/hello world/' $tmp/1" >; $tmp/1  2> /dev/null
30110898Sroland.mainz@nrubsig.orgthen	[[ $(<$tmp/1) == 'hello world' ]] || err_exit '>; not updating file on success'
3028462SApril.Chin@Sun.COMfi
30310898Sroland.mainz@nrubsig.org
30410898Sroland.mainz@nrubsig.org$SHELL -c 'exec 3<>; /dev/null'  2> /dev/null && err_exit '<>; with exec should be an error'
30510898Sroland.mainz@nrubsig.org$SHELL -c ': 3<>; /dev/null'  2> /dev/null || err_exit '<>; not working with at all'
30610898Sroland.mainz@nrubsig.orgprint $'hello\nworld' > $tmp/1
30710898Sroland.mainz@nrubsig.orgif      ! $SHELL -c "false <>; $tmp/1"  2> /dev/null
30810898Sroland.mainz@nrubsig.orgthen    [[ $(<$tmp/1) == $'hello\nworld' ]] || err_exit '<>; not preserving file on failure'
30910898Sroland.mainz@nrubsig.orgfi
31010898Sroland.mainz@nrubsig.orgif	! $SHELL -c "head -1 $tmp/1" <>; $tmp/1  2> /dev/null
31110898Sroland.mainz@nrubsig.orgthen	[[ $(<$tmp/1) == hello ]] || err_exit '<>; not truncating file on success of head'
31210898Sroland.mainz@nrubsig.orgfi
31310898Sroland.mainz@nrubsig.orgprint $'hello\nworld' > $tmp/1
31410898Sroland.mainz@nrubsig.orgif	! $SHELL -c head  < $tmp/1 <#((6)) <>; $tmp/1  2> /dev/null
31510898Sroland.mainz@nrubsig.orgthen	[[ $(<$tmp/1) == world ]] || err_exit '<>; not truncating file on success of behead'
3168462SApril.Chin@Sun.COMfi
3178462SApril.Chin@Sun.COM
3188462SApril.Chin@Sun.COMunset y
3198462SApril.Chin@Sun.COMread -n1 y <<!
3208462SApril.Chin@Sun.COMabc
3218462SApril.Chin@Sun.COM!
3228462SApril.Chin@Sun.COMif      [[ $y != a ]]
3238462SApril.Chin@Sun.COMthen    err_exit  'read -n1 not working'
3248462SApril.Chin@Sun.COMfi
3258462SApril.Chin@Sun.COMunset a
3268462SApril.Chin@Sun.COM{ read -N3 a; read -N1 b;}  <<!
3278462SApril.Chin@Sun.COMabcdefg
3288462SApril.Chin@Sun.COM!
3298462SApril.Chin@Sun.COM[[ $a == abc ]] || err_exit 'read -N3 here-document not working'
3308462SApril.Chin@Sun.COM[[ $b == d ]] || err_exit 'read -N1 here-document not working'
3318462SApril.Chin@Sun.COMread -n3 a <<!
3328462SApril.Chin@Sun.COMabcdefg
3338462SApril.Chin@Sun.COM!
3348462SApril.Chin@Sun.COM[[ $a == abc ]] || err_exit 'read -n3 here-document not working'
3358462SApril.Chin@Sun.COM(print -n a;sleep 1; print -n bcde) | { read -N3 a; read -N1 b;}
3368462SApril.Chin@Sun.COM[[ $a == abc ]] || err_exit 'read -N3 from pipe not working'
3378462SApril.Chin@Sun.COM[[ $b == d ]] || err_exit 'read -N1 from pipe not working'
3388462SApril.Chin@Sun.COM(print -n a;sleep 1; print -n bcde) |read -n3 a
3398462SApril.Chin@Sun.COM[[ $a == a ]] || err_exit 'read -n3 from pipe not working'
34010898Sroland.mainz@nrubsig.orgif	mkfifo $tmp/fifo 2> /dev/null
34110898Sroland.mainz@nrubsig.orgthen	(print -n a; sleep 1;print -n bcde)  > $tmp/fifo &
3428462SApril.Chin@Sun.COM	{
3438462SApril.Chin@Sun.COM	read -u5 -n3  -t2 a  || err_exit 'read -n3 from fifo timedout'
3448462SApril.Chin@Sun.COM	read -u5 -n1 -t2 b || err_exit 'read -n1 from fifo timedout'
34510898Sroland.mainz@nrubsig.org	} 5< $tmp/fifo
3468462SApril.Chin@Sun.COM	[[ $a == a ]] || err_exit 'read -n3 from fifo not working'
34710898Sroland.mainz@nrubsig.org	rm -f $tmp/fifo
34810898Sroland.mainz@nrubsig.org	mkfifo $tmp/fifo 2> /dev/null
34910898Sroland.mainz@nrubsig.org	(print -n a; sleep 1;print -n bcde)  > $tmp/fifo &
3508462SApril.Chin@Sun.COM	{
3518462SApril.Chin@Sun.COM	read -u5 -N3 -t2 a || err_exit 'read -N3 from fifo timed out'
3528462SApril.Chin@Sun.COM	read -u5 -N1 -t2 b || err_exit 'read -N1 from fifo timedout'
35310898Sroland.mainz@nrubsig.org	} 5< $tmp/fifo
3548462SApril.Chin@Sun.COM	[[ $a == abc ]] || err_exit 'read -N3 from fifo not working'
3558462SApril.Chin@Sun.COM	[[ $b == d ]] || err_exit 'read -N1 from fifo not working'
3568462SApril.Chin@Sun.COMfi
35710898Sroland.mainz@nrubsig.org(
35810898Sroland.mainz@nrubsig.org	print -n 'prompt1: '
35910898Sroland.mainz@nrubsig.org	sleep .1
36010898Sroland.mainz@nrubsig.org	print line2
36110898Sroland.mainz@nrubsig.org	sleep .1
36210898Sroland.mainz@nrubsig.org	print -n 'prompt2: '
36310898Sroland.mainz@nrubsig.org	sleep .1
36410898Sroland.mainz@nrubsig.org) | {
36510898Sroland.mainz@nrubsig.org	read -t2 -n 1000 line1
36610898Sroland.mainz@nrubsig.org	read -t2 -n 1000 line2
36710898Sroland.mainz@nrubsig.org	read -t2 -n 1000 line3
36810898Sroland.mainz@nrubsig.org	read -t2 -n 1000 line4
36910898Sroland.mainz@nrubsig.org}
370*12068SRoger.Faulkner@Oracle.COM[[ $? == 0 ]]		 	&& err_exit 'should have timed out'
37110898Sroland.mainz@nrubsig.org[[ $line1 == 'prompt1: ' ]] 	|| err_exit "line1 should be 'prompt1: '"
37210898Sroland.mainz@nrubsig.org[[ $line2 == line2 ]]		|| err_exit "line2 should be line2"
37310898Sroland.mainz@nrubsig.org[[ $line3 == 'prompt2: ' ]]	|| err_exit "line3 should be 'prompt2: '"
37410898Sroland.mainz@nrubsig.org[[ ! $line4 ]]			|| err_exit "line4 should be empty"
3758462SApril.Chin@Sun.COM
3768462SApril.Chin@Sun.COMif	$SHELL -c "export LC_ALL=en_US.UTF-8; c=$'\342\202\254'; [[ \${#c} == 1 ]]" 2>/dev/null
3778462SApril.Chin@Sun.COMthen	lc_utf8=en_US.UTF-8
3788462SApril.Chin@Sun.COMelse	lc_utf8=''
3798462SApril.Chin@Sun.COMfi
3808462SApril.Chin@Sun.COM
3818462SApril.Chin@Sun.COMtypeset -a e o=(-n2 -N2)
3828462SApril.Chin@Sun.COMinteger i
3838462SApril.Chin@Sun.COMset -- \
3848462SApril.Chin@Sun.COM	'a'	'bcd'	'a bcd'	'ab cd' \
3858462SApril.Chin@Sun.COM	'ab'	'cd'	'ab cd'	'ab cd' \
3868462SApril.Chin@Sun.COM	'abc'	'd'	'ab cd'	'ab cd' \
3878462SApril.Chin@Sun.COM	'abcd'	''	'ab cd'	'ab cd'
3888462SApril.Chin@Sun.COMwhile	(( $# >= 3 ))
3898462SApril.Chin@Sun.COMdo	a=$1
3908462SApril.Chin@Sun.COM	b=$2
3918462SApril.Chin@Sun.COM	e[0]=$3
3928462SApril.Chin@Sun.COM	e[1]=$4
3938462SApril.Chin@Sun.COM	shift 4
3948462SApril.Chin@Sun.COM	for ((i = 0; i < 2; i++))
3958462SApril.Chin@Sun.COM	do	for lc_all in C $lc_utf8
3968462SApril.Chin@Sun.COM		do	g=$(LC_ALL=$lc_all $SHELL -c "{ print -n '$a'; sleep 0.2; print -n '$b'; sleep 0.2; } | { read ${o[i]} a; print -n \$a; read a; print -n \ \$a; }")
3978462SApril.Chin@Sun.COM			[[ $g == "${e[i]}" ]] || err_exit "LC_ALL=$lc_all read ${o[i]} from pipe '$a $b' failed -- expected '${e[i]}', got '$g'"
3988462SApril.Chin@Sun.COM		done
3998462SApril.Chin@Sun.COM	done
4008462SApril.Chin@Sun.COMdone
4018462SApril.Chin@Sun.COM
4028462SApril.Chin@Sun.COMif	[[ $lc_utf8 ]]
4038462SApril.Chin@Sun.COMthen	export LC_ALL=en_US.UTF-8
4048462SApril.Chin@Sun.COM	typeset -a c=( '' 'A' $'\303\274' $'\342\202\254' )
4058462SApril.Chin@Sun.COM	integer i w
4068462SApril.Chin@Sun.COM	typeset o
4078462SApril.Chin@Sun.COM	if	(( ${#c[2]} == 1 && ${#c[3]} == 1 ))
4088462SApril.Chin@Sun.COM	then	for i in 1 2 3
4098462SApril.Chin@Sun.COM		do	for o in n N
4108462SApril.Chin@Sun.COM			do	for w in 1 2 3
4118462SApril.Chin@Sun.COM				do	print -nr "${c[w]}" | read -${o}${i} g
4128462SApril.Chin@Sun.COM					if	[[ $o == N ]] && (( i > 1 ))
4138462SApril.Chin@Sun.COM					then	e=''
4148462SApril.Chin@Sun.COM					else	e=${c[w]}
4158462SApril.Chin@Sun.COM					fi
4168462SApril.Chin@Sun.COM					[[ $g == "$e" ]] || err_exit "read -${o}${i} failed for '${c[w]}' -- expected '$e', got '$g'"
4178462SApril.Chin@Sun.COM				done
4188462SApril.Chin@Sun.COM			done
4198462SApril.Chin@Sun.COM		done
4208462SApril.Chin@Sun.COM	fi
4218462SApril.Chin@Sun.COMfi
4228462SApril.Chin@Sun.COM
42310898Sroland.mainz@nrubsig.orgexec 3<&2
42410898Sroland.mainz@nrubsig.orgfile=$tmp/file
42510898Sroland.mainz@nrubsig.orgredirect 5>$file 2>&5
42610898Sroland.mainz@nrubsig.orgprint -u5 -f 'This is a test\n'
42710898Sroland.mainz@nrubsig.orgprint -u2 OK
42810898Sroland.mainz@nrubsig.orgexec 2<&3
42910898Sroland.mainz@nrubsig.orgexp=$'This is a test\nOK'
43010898Sroland.mainz@nrubsig.orggot=$(< $file)
43110898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "output garbled when stderr is duped -- expected $(printf %q "$exp"), got $(printf %q "$got")"
43210898Sroland.mainz@nrubsig.orgprint 'hello world' > $file
43310898Sroland.mainz@nrubsig.org1<>; $file  1># ((5))
43410898Sroland.mainz@nrubsig.org(( $(wc -c < $file) == 5 )) || err_exit "$file was not truncate to 5 bytes"
43510898Sroland.mainz@nrubsig.org
43610898Sroland.mainz@nrubsig.org$SHELL -c "PS4=':2:'
43710898Sroland.mainz@nrubsig.org	exec 1> $tmp/21.out 2> $tmp/22.out
43810898Sroland.mainz@nrubsig.org	set -x
43910898Sroland.mainz@nrubsig.org	printf ':1:A:'
44010898Sroland.mainz@nrubsig.org	print \$(:)
44110898Sroland.mainz@nrubsig.org	print :1:Z:" 1> $tmp/11.out 2> $tmp/12.out
44210898Sroland.mainz@nrubsig.org[[ -s $tmp/11.out ]] && err_exit "standard output leaked past redirection"
44310898Sroland.mainz@nrubsig.org[[ -s $tmp/12.out ]] && err_exit "standard error leaked past redirection"
44410898Sroland.mainz@nrubsig.orgexp=$':1:A:\n:1:Z:'
44510898Sroland.mainz@nrubsig.orggot=$(<$tmp/21.out)
44610898Sroland.mainz@nrubsig.org[[ $exp == "$got" ]] || err_exit "standard output garbled -- expected $(printf %q "$exp"), got $(printf %q "$got")"
44710898Sroland.mainz@nrubsig.orgexp=$':2:printf :1:A:\n:2::\n:2:print\n:2:print :1:Z:'
44810898Sroland.mainz@nrubsig.orggot=$(<$tmp/22.out)
44910898Sroland.mainz@nrubsig.org[[ $exp == "$got" ]] || err_exit "standard error garbled -- expected $(printf %q "$exp"), got $(printf %q "$got")"
45010898Sroland.mainz@nrubsig.org
4514887Schinexit $((Errors))
452