14887Schin######################################################################## 24887Schin# # 34887Schin# This software is part of the ast package # 4*10898Sroland.mainz@nrubsig.org# Copyright (c) 1982-2009 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 31*10898Sroland.mainz@nrubsig.orgtmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 32*10898Sroland.mainz@nrubsig.orgtrap "cd /; rm -rf $tmp" EXIT 33*10898Sroland.mainz@nrubsig.org 348462SApril.Chin@Sun.COMunset HISTFILE 358462SApril.Chin@Sun.COM 364887Schinfunction fun 374887Schin{ 38*10898Sroland.mainz@nrubsig.org while command exec 3>&1 39*10898Sroland.mainz@nrubsig.org do break 404887Schin done 2> /dev/null 414887Schin print -u3 good 424887Schin} 43*10898Sroland.mainz@nrubsig.orgprint 'read -r a;print -r -u$1 -- "$a"' > $tmp/mycat 44*10898Sroland.mainz@nrubsig.orgchmod 755 $tmp/mycat 454887Schinfor ((i=3; i < 10; i++)) 464887Schindo 47*10898Sroland.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>&- 53*10898Sroland.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 62*10898Sroland.mainz@nrubsig.orgexp=foo 63*10898Sroland.mainz@nrubsig.orgif [[ $line != $exp ]] 64*10898Sroland.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 70*10898Sroland.mainz@nrubsig.org 71*10898Sroland.mainz@nrubsig.orgFDFS=( 72*10898Sroland.mainz@nrubsig.org ( dir=/proc/self/fd semantics='open' ) 73*10898Sroland.mainz@nrubsig.org ( dir=/proc/$$/fd semantics='open' ) 74*10898Sroland.mainz@nrubsig.org ( dir=/dev/fd semantics='open|dup' ) 75*10898Sroland.mainz@nrubsig.org ( dir=/dev/fd semantics='dup' ) 76*10898Sroland.mainz@nrubsig.org) 77*10898Sroland.mainz@nrubsig.orgfor ((fdfs=0; fdfs<${#FDFS[@]}-1; fdfs++)) 78*10898Sroland.mainz@nrubsig.orgdo [[ -e ${FDFS[fdfs].dir} ]] && { command : > ${FDFS[fdfs].dir}/1; } 2>/dev/null && break 79*10898Sroland.mainz@nrubsig.orgdone 80*10898Sroland.mainz@nrubsig.org 81*10898Sroland.mainz@nrubsig.orgexec 3<> file1 82*10898Sroland.mainz@nrubsig.orgif command exec 4< ${FDFS[fdfs].dir}/3 83*10898Sroland.mainz@nrubsig.orgthen read -u3 got 84*10898Sroland.mainz@nrubsig.org read -u4 got 85*10898Sroland.mainz@nrubsig.org exp='foo|bar' 86*10898Sroland.mainz@nrubsig.org case $got in 87*10898Sroland.mainz@nrubsig.org foo) semantics='open' ;; 88*10898Sroland.mainz@nrubsig.org bar) semantics='dup' ;; 89*10898Sroland.mainz@nrubsig.org *) semantics='failed' ;; 90*10898Sroland.mainz@nrubsig.org esac 91*10898Sroland.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 93*10898Sroland.mainz@nrubsig.org 94*10898Sroland.mainz@nrubsig.org# 2004-11-25 ancient /dev/fd/N redirection bug fix 95*10898Sroland.mainz@nrubsig.orggot=$( 96*10898Sroland.mainz@nrubsig.org { 97*10898Sroland.mainz@nrubsig.org print -n 1 98*10898Sroland.mainz@nrubsig.org print -n 2 > ${FDFS[fdfs].dir}/2 99*10898Sroland.mainz@nrubsig.org print -n 3 100*10898Sroland.mainz@nrubsig.org print -n 4 > ${FDFS[fdfs].dir}/2 101*10898Sroland.mainz@nrubsig.org } 2>&1 102*10898Sroland.mainz@nrubsig.org) 103*10898Sroland.mainz@nrubsig.orgexp='1234|4' 104*10898Sroland.mainz@nrubsig.orgcase $got in 105*10898Sroland.mainz@nrubsig.org1234) semantics='dup' ;; 106*10898Sroland.mainz@nrubsig.org4) semantics='open' ;; 107*10898Sroland.mainz@nrubsig.org*) semantics='failed' ;; 108*10898Sroland.mainz@nrubsig.orgesac 109*10898Sroland.mainz@nrubsig.org[[ $semantics == @(${FDFS[fdfs].semantics}) ]] || err_exit "${FDFS[fdfs].dir}/N $semantics semantics instead of ${FDFS[fdfs].semantics} -- expected '$exp', got '$got'" 110*10898Sroland.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 ' 130*10898Sroland.mainz@nrubsig.org trap "rm -f in out" EXIT 1314887Schin for ((i = 0; i < 1000; i++)) 1324887Schin do print -r -- "This is a test" 133*10898Sroland.mainz@nrubsig.org done > in 134*10898Sroland.mainz@nrubsig.org > out 135*10898Sroland.mainz@nrubsig.org exec 1<> out 1364887Schin builtin cat 137*10898Sroland.mainz@nrubsig.org print -r -- "$(<in)" 138*10898Sroland.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 161*10898Sroland.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 176*10898Sroland.mainz@nrubsig.orgcat > $tmp/1 <<- ++EOF++ 177*10898Sroland.mainz@nrubsig.org script=$tmp/2 178*10898Sroland.mainz@nrubsig.org trap "rm -f \$script" EXIT 179*10898Sroland.mainz@nrubsig.org exec 9> \$script 1804887Schin for ((i=3; i<9; i++)) 181*10898Sroland.mainz@nrubsig.org do eval "while read -u\$i; do : ;done \$i</dev/null" 182*10898Sroland.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<&- 189*10898Sroland.mainz@nrubsig.org chmod +x \$script 190*10898Sroland.mainz@nrubsig.org \$script 1914887Schin++EOF++ 192*10898Sroland.mainz@nrubsig.orgchmod +x $tmp/1 193*10898Sroland.mainz@nrubsig.org[[ $($SHELL $tmp/1) == ok ]] || err_exit "parent i/o causes child script to fail" 194*10898Sroland.mainz@nrubsig.org# 2004-12-20 redirection loss bug fix 195*10898Sroland.mainz@nrubsig.orgcat > $tmp/1 <<- \++EOF++ 1964887Schin function a 1974887Schin { 1984887Schin trap 'print ok' EXIT 1994887Schin : > /dev/null 2004887Schin } 2014887Schin a 2024887Schin++EOF++ 203*10898Sroland.mainz@nrubsig.orgchmod +x $tmp/1 204*10898Sroland.mainz@nrubsig.org[[ $($tmp/1) == ok ]] || err_exit "trap on EXIT loses last command redirection" 205*10898Sroland.mainz@nrubsig.orgprint > /dev/null {n}> $tmp/1 206*10898Sroland.mainz@nrubsig.org[[ ! -s $tmp/1 ]] && newio=1 207*10898Sroland.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} 217*10898Sroland.mainz@nrubsig.orgdone > $tmp/seek 218*10898Sroland.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" 221*10898Sroland.mainz@nrubsig.org command exec 3<# ((40*8)) || err_exit "absolute seek fails" 2224887Schin read -u3 223*10898Sroland.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 227*10898Sroland.mainz@nrubsig.org [[ $REPLY == {39}(l) ]] || err_exit "expected lll..., got $REPLY" 2284887Schin command exec 3<# ((EOF-80)) 2294887Schin read -u3 230*10898Sroland.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 235*10898Sroland.mainz@nrubsig.org [[ $REPLY == +(@) ]] || err_exit "expected @@@..., got $REPLY" 2364887Schin read -u3 237*10898Sroland.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" 241*10898Sroland.mainz@nrubsig.org command exec 3<# ((40*62)) 2424887Schin read -u3 243*10898Sroland.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" 253*10898Sroland.mainz@nrubsig.org cat $tmp/seek | read -r <# *WWW* 2544887Schin [[ $REPLY == *WWWWW* ]] || err_exit '<# not working for pipes' 255*10898Sroland.mainz@nrubsig.org { < $tmp/seek <# ((2358336120)) ;} 2> /dev/null || err_exit 'long seek not working' 256*10898Sroland.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} 261*10898Sroland.mainz@nrubsig.orgdone > $tmp/seek 262*10898Sroland.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" 282*10898Sroland.mainz@nrubsig.org$SHELL -c "{ > $tmp/1 ; date;} >&- 2> /dev/null" > $tmp/2 283*10898Sroland.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' 296*10898Sroland.mainz@nrubsig.orgprint hello > $tmp/1 297*10898Sroland.mainz@nrubsig.orgif ! $SHELL -c "false >; $tmp/1" 2> /dev/null 298*10898Sroland.mainz@nrubsig.orgthen [[ $(<$tmp/1) == hello ]] || err_exit '>; not preserving file on failure' 299*10898Sroland.mainz@nrubsig.orgfi 300*10898Sroland.mainz@nrubsig.orgif ! $SHELL -c "sed -e 's/hello/hello world/' $tmp/1" >; $tmp/1 2> /dev/null 301*10898Sroland.mainz@nrubsig.orgthen [[ $(<$tmp/1) == 'hello world' ]] || err_exit '>; not updating file on success' 3028462SApril.Chin@Sun.COMfi 303*10898Sroland.mainz@nrubsig.org 304*10898Sroland.mainz@nrubsig.org$SHELL -c 'exec 3<>; /dev/null' 2> /dev/null && err_exit '<>; with exec should be an error' 305*10898Sroland.mainz@nrubsig.org$SHELL -c ': 3<>; /dev/null' 2> /dev/null || err_exit '<>; not working with at all' 306*10898Sroland.mainz@nrubsig.orgprint $'hello\nworld' > $tmp/1 307*10898Sroland.mainz@nrubsig.orgif ! $SHELL -c "false <>; $tmp/1" 2> /dev/null 308*10898Sroland.mainz@nrubsig.orgthen [[ $(<$tmp/1) == $'hello\nworld' ]] || err_exit '<>; not preserving file on failure' 309*10898Sroland.mainz@nrubsig.orgfi 310*10898Sroland.mainz@nrubsig.orgif ! $SHELL -c "head -1 $tmp/1" <>; $tmp/1 2> /dev/null 311*10898Sroland.mainz@nrubsig.orgthen [[ $(<$tmp/1) == hello ]] || err_exit '<>; not truncating file on success of head' 312*10898Sroland.mainz@nrubsig.orgfi 313*10898Sroland.mainz@nrubsig.orgprint $'hello\nworld' > $tmp/1 314*10898Sroland.mainz@nrubsig.orgif ! $SHELL -c head < $tmp/1 <#((6)) <>; $tmp/1 2> /dev/null 315*10898Sroland.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' 340*10898Sroland.mainz@nrubsig.orgif mkfifo $tmp/fifo 2> /dev/null 341*10898Sroland.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' 345*10898Sroland.mainz@nrubsig.org } 5< $tmp/fifo 3468462SApril.Chin@Sun.COM [[ $a == a ]] || err_exit 'read -n3 from fifo not working' 347*10898Sroland.mainz@nrubsig.org rm -f $tmp/fifo 348*10898Sroland.mainz@nrubsig.org mkfifo $tmp/fifo 2> /dev/null 349*10898Sroland.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' 353*10898Sroland.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 357*10898Sroland.mainz@nrubsig.org( 358*10898Sroland.mainz@nrubsig.org print -n 'prompt1: ' 359*10898Sroland.mainz@nrubsig.org sleep .1 360*10898Sroland.mainz@nrubsig.org print line2 361*10898Sroland.mainz@nrubsig.org sleep .1 362*10898Sroland.mainz@nrubsig.org print -n 'prompt2: ' 363*10898Sroland.mainz@nrubsig.org sleep .1 364*10898Sroland.mainz@nrubsig.org) | { 365*10898Sroland.mainz@nrubsig.org read -t2 -n 1000 line1 366*10898Sroland.mainz@nrubsig.org read -t2 -n 1000 line2 367*10898Sroland.mainz@nrubsig.org read -t2 -n 1000 line3 368*10898Sroland.mainz@nrubsig.org read -t2 -n 1000 line4 369*10898Sroland.mainz@nrubsig.org} 370*10898Sroland.mainz@nrubsig.org[[ $? == 0 ]] && err_exit 'should have time out' 371*10898Sroland.mainz@nrubsig.org[[ $line1 == 'prompt1: ' ]] || err_exit "line1 should be 'prompt1: '" 372*10898Sroland.mainz@nrubsig.org[[ $line2 == line2 ]] || err_exit "line2 should be line2" 373*10898Sroland.mainz@nrubsig.org[[ $line3 == 'prompt2: ' ]] || err_exit "line3 should be 'prompt2: '" 374*10898Sroland.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 423*10898Sroland.mainz@nrubsig.orgexec 3<&2 424*10898Sroland.mainz@nrubsig.orgfile=$tmp/file 425*10898Sroland.mainz@nrubsig.orgredirect 5>$file 2>&5 426*10898Sroland.mainz@nrubsig.orgprint -u5 -f 'This is a test\n' 427*10898Sroland.mainz@nrubsig.orgprint -u2 OK 428*10898Sroland.mainz@nrubsig.orgexec 2<&3 429*10898Sroland.mainz@nrubsig.orgexp=$'This is a test\nOK' 430*10898Sroland.mainz@nrubsig.orggot=$(< $file) 431*10898Sroland.mainz@nrubsig.org[[ $got == $exp ]] || err_exit "output garbled when stderr is duped -- expected $(printf %q "$exp"), got $(printf %q "$got")" 432*10898Sroland.mainz@nrubsig.orgprint 'hello world' > $file 433*10898Sroland.mainz@nrubsig.org1<>; $file 1># ((5)) 434*10898Sroland.mainz@nrubsig.org(( $(wc -c < $file) == 5 )) || err_exit "$file was not truncate to 5 bytes" 435*10898Sroland.mainz@nrubsig.org 436*10898Sroland.mainz@nrubsig.org$SHELL -c "PS4=':2:' 437*10898Sroland.mainz@nrubsig.org exec 1> $tmp/21.out 2> $tmp/22.out 438*10898Sroland.mainz@nrubsig.org set -x 439*10898Sroland.mainz@nrubsig.org printf ':1:A:' 440*10898Sroland.mainz@nrubsig.org print \$(:) 441*10898Sroland.mainz@nrubsig.org print :1:Z:" 1> $tmp/11.out 2> $tmp/12.out 442*10898Sroland.mainz@nrubsig.org[[ -s $tmp/11.out ]] && err_exit "standard output leaked past redirection" 443*10898Sroland.mainz@nrubsig.org[[ -s $tmp/12.out ]] && err_exit "standard error leaked past redirection" 444*10898Sroland.mainz@nrubsig.orgexp=$':1:A:\n:1:Z:' 445*10898Sroland.mainz@nrubsig.orggot=$(<$tmp/21.out) 446*10898Sroland.mainz@nrubsig.org[[ $exp == "$got" ]] || err_exit "standard output garbled -- expected $(printf %q "$exp"), got $(printf %q "$got")" 447*10898Sroland.mainz@nrubsig.orgexp=$':2:printf :1:A:\n:2::\n:2:print\n:2:print :1:Z:' 448*10898Sroland.mainz@nrubsig.orggot=$(<$tmp/22.out) 449*10898Sroland.mainz@nrubsig.org[[ $exp == "$got" ]] || err_exit "standard error garbled -- expected $(printf %q "$exp"), got $(printf %q "$got")" 450*10898Sroland.mainz@nrubsig.org 4514887Schinexit $((Errors)) 452