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*4887SchinCommand=${0##*/} 29*4887Schininteger Errors=0 30*4887Schin# cut here 31*4887Schinfunction fun 32*4887Schin{ 33*4887Schin while command exec 3>&1 34*4887Schin do break 35*4887Schin done 2> /dev/null 36*4887Schin print -u3 good 37*4887Schin} 38*4887Schinprint 'read -r a;print -r -u$1 -- "$a"' > /tmp/mycat$$ 39*4887Schinchmod 755 /tmp/mycat$$ 40*4887Schinfor ((i=3; i < 10; i++)) 41*4887Schindo 42*4887Schin eval "a=\$(print foo | /tmp/mycat$$" $i $i'>&1 > /dev/null |cat)' 2> /dev/null 43*4887Schin [[ $a == foo ]] || err_exit "bad file descriptor $i in comsub script" 44*4887Schindone 45*4887Schinrm -f /tmp/mycat$$ 46*4887Schinexec 3> /dev/null 47*4887Schin[[ $(fun) == good ]] || err_exit 'file 3 closed before subshell completes' 48*4887Schinexec 3>&- 49*4887Schinmkdir /tmp/ksh$$ || err_exit "mkdir /tmp/ksh$$ failed" 50*4887Schintrap 'rm -rf /tmp/ksh$$' EXIT 51*4887Schincd /tmp/ksh$$ || err_exit "cd /tmp/ksh$$ failed" 52*4887Schinprint foo > file1 53*4887Schinprint bar >> file1 54*4887Schinif [[ $(<file1) != $'foo\nbar' ]] 55*4887Schinthen err_exit 'append (>>) not working' 56*4887Schinfi 57*4887Schinset -o noclobber 58*4887Schinexec 3<> file1 59*4887Schinread -u3 line 60*4887Schinif [[ $line != foo ]] 61*4887Schinthen err_exit '<> not working right with read' 62*4887Schinfi 63*4887Schinif ( 4> file1 ) 2> /dev/null 64*4887Schinthen err_exit 'noclobber not causing exclusive open' 65*4887Schinfi 66*4887Schinset +o noclobber 67*4887Schinif command exec 4< /dev/fd/3 68*4887Schinthen read -u4 line 69*4887Schin if [[ $line != bar ]] 70*4887Schin then '4< /dev/fd/3 not working correctly' 71*4887Schin fi 72*4887Schinfi 73*4887Schincat > close0 <<\! 74*4887Schinexec 0<&- 75*4887Schinecho $(./close1) 76*4887Schin! 77*4887Schinprint "echo abc" > close1 78*4887Schinchmod +x close0 close1 79*4887Schinx=$(./close0) 80*4887Schinif [[ $x != "abc" ]] 81*4887Schinthen err_exit "picked up file descriptor zero for opening script file" 82*4887Schinfi 83*4887Schincat > close0 <<\! 84*4887Schin for ((i=0; i < 1100; i++)) 85*4887Schin do exec 4< /dev/null 86*4887Schin read -u4 87*4887Schin done 88*4887Schin exit 0 89*4887Schin! 90*4887Schin./close0 2> /dev/null || err_exit "multiple exec 4< /dev/null can fail" 91*4887Schin$SHELL -c ' 92*4887Schin trap "rm -f in$$ out$$" EXIT 93*4887Schin for ((i = 0; i < 1000; i++)) 94*4887Schin do print -r -- "This is a test" 95*4887Schin done > in$$ 96*4887Schin > out$$ 97*4887Schin exec 1<> out$$ 98*4887Schin builtin cat 99*4887Schin print -r -- "$(cat in$$)" 100*4887Schin cmp -s in$$ out$$' 2> /dev/null 101*4887Schin[[ $? == 0 ]] || err_exit 'builtin cat truncates files' 102*4887Schincat >| script <<-\! 103*4887Schinprint hello 104*4887Schin( exec 3<&- 4<&-) 105*4887Schinexec 3<&- 4<&- 106*4887Schinprint world 107*4887Schin! 108*4887Schinchmod +x script 109*4887Schin[[ $( $SHELL ./script) == $'hello\nworld' ]] || err_exit 'closing 3 & 4 causes script to fail' 110*4887Schincd ~- || err_exit "cd back failed" 111*4887Schin( exec > '' ) 2> /dev/null && err_exit '> "" does not fail' 112*4887Schinunset x 113*4887Schin( exec > ${x} ) 2> /dev/null && err_exit '> $x, where x null does not fail' 114*4887Schinexec <<! 115*4887Schinfoo 116*4887Schinbar 117*4887Schin! 118*4887Schin( exec 0< /dev/null) 119*4887Schinread line 120*4887Schinif [[ $line != foo ]] 121*4887Schinthen err_exit 'file descriptor not restored after exec in subshell' 122*4887Schinfi 123*4887Schinexec 3>&- 4>&-; cd /; rm -r /tmp/ksh$$ || err_exit "rm -r /tmp/ksh$$ failed" 124*4887Schin[[ $( { 125*4887Schin read -r line;print -r -- "$line" 126*4887Schin ( 127*4887Schin read -r line;print -r -- "$line" 128*4887Schin ) & wait 129*4887Schin while read -r line 130*4887Schin do print -r -- "$line" 131*4887Schin done 132*4887Schin } << ! 133*4887Schinline 1 134*4887Schinline 2 135*4887Schinline 3 136*4887Schin!) == $'line 1\nline 2\nline 3' ]] || err_exit 'read error with subshells' 137*4887Schin# 2004-05-11 bug fix 138*4887Schincat > /tmp/io$$.1 <<- \++EOF++ 139*4887Schin script=/tmp/io$$.2 140*4887Schin trap 'rm -f $script' EXIT 141*4887Schin exec 9> $script 142*4887Schin for ((i=3; i<9; i++)) 143*4887Schin do eval "while read -u$i; do : ;done $i</dev/null" 144*4887Schin print -u9 "exec $i< /dev/null" 145*4887Schin done 146*4887Schin for ((i=0; i < 60; i++)) 147*4887Schin do print -u9 -f "%.80c\n" ' ' 148*4887Schin done 149*4887Schin print -u9 'print ok' 150*4887Schin exec 9<&- 151*4887Schin chmod +x $script 152*4887Schin $script 153*4887Schin++EOF++ 154*4887Schinchmod +x /tmp/io$$.1 155*4887Schin[[ $($SHELL /tmp/io$$.1) == ok ]] || err_exit "parent i/o causes child script to fail" 156*4887Schinrm -rf /tmp/io$$.[12] 157*4887Schin# 2004-11-25 ancient /dev/fd/NN redirection bug fix 158*4887Schinx=$( 159*4887Schin { 160*4887Schin print -n 1 161*4887Schin print -n 2 > /dev/fd/2 162*4887Schin print -n 3 163*4887Schin print -n 4 > /dev/fd/2 164*4887Schin } 2>&1 165*4887Schin) 166*4887Schin[[ $x == "1234" ]] || err_exit "/dev/fd/NN redirection fails to dup" 167*4887Schin# 2004-12-20 redirction loss bug fix 168*4887Schincat > /tmp/io$$.1 <<- \++EOF++ 169*4887Schin function a 170*4887Schin { 171*4887Schin trap 'print ok' EXIT 172*4887Schin : > /dev/null 173*4887Schin } 174*4887Schin a 175*4887Schin++EOF++ 176*4887Schinchmod +x /tmp/io$$.1 177*4887Schin[[ $(/tmp/io$$.1) == ok ]] || err_exit "trap on EXIT loses last command redirection" 178*4887Schinprint > /dev/null {n}> /tmp/io$$.1 179*4887Schin[[ ! -s /tmp/io$$.1 ]] && newio=1 180*4887Schinrm -rf /tmp/io$$.1 181*4887Schinif [[ $newio && $(print hello | while read -u$n; do print $REPLY; done {n}<&0) != hello ]] 182*4887Schinthen err_exit "{n}<&0 not working with for loop" 183*4887Schinfi 184*4887Schin[[ $({ read -r;read -u3 3<&0; print -- "$REPLY" ;} <<! 185*4887Schinhello 186*4887Schinworld 187*4887Schin!) == world ]] || err_exit 'I/O not synchronized with <&' 188*4887Schintrap 'rm -f /tmp/seek$$; exit $((Errors+1))' EXIT 189*4887Schinx="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNSPQRSTUVWXYZ1234567890" 190*4887Schinfor ((i=0; i < 62; i++)) 191*4887Schindo printf "%.39c\n" ${x:i:1} 192*4887Schindone > /tmp/seek$$ 193*4887Schinif command exec 3<> /tmp/seek$$ 194*4887Schinthen (( $(3<#) == 0 )) || err_exit "not at position 0" 195*4887Schin (( $(3<# ((EOF))) == 40*62 )) || err_exit "not at end-of-file" 196*4887Schin command exec 3<# ((40*8)) || err_exit "absolute seek fails" 197*4887Schin read -u3 198*4887Schin [[ $REPLY == +(i) ]] || err_exit "expecting iiii..." 199*4887Schin [[ $(3<#) == $(3<# ((CUR)) ) ]] || err_exit '$(3<#)!=$(3<#((CUR)))' 200*4887Schin command exec 3<# ((CUR+80)) 201*4887Schin read -u3 202*4887Schin [[ $REPLY == {39}(l) ]] || err_exit "expecting lll..." 203*4887Schin command exec 3<# ((EOF-80)) 204*4887Schin read -u3 205*4887Schin [[ $REPLY == +(9) ]] || err_exit "expecting 999...; got $REPLY" 206*4887Schin command exec 3># ((80)) 207*4887Schin print -u3 -f "%.39c\n" @ 208*4887Schin command exec 3># ((80)) 209*4887Schin read -u3 210*4887Schin [[ $REPLY == +(@) ]] || err_exit "expecting @@@..." 211*4887Schin read -u3 212*4887Schin [[ $REPLY == +(d) ]] || err_exit "expecting ddd..." 213*4887Schin command exec 3># ((EOF)) 214*4887Schin print -u3 -f "%.39c\n" ^ 215*4887Schin (( $(3<# ((CUR-0))) == 40*63 )) || err_exit "not at extended end-of-file" 216*4887Schin command exec 3<# ((40*62)) 217*4887Schin read -u3 218*4887Schin [[ $REPLY == +(^) ]] || err_exit "expecting ddd..." 219*4887Schin command exec 3<# ((0)) 220*4887Schin command exec 3<# *jjjj* 221*4887Schin read -u3 222*4887Schin [[ $REPLY == {39}(j) ]] || err_exit "<# pattern failed" 223*4887Schin [[ $(command exec 3<## *llll*) = {39}(k) ]] || err_exit "<## pattern not saving standard output" 224*4887Schin read -u3 225*4887Schin [[ $REPLY == {39}(l) ]] || err_exit "<## pattern failed to position" 226*4887Schin command exec 3<# *abc* 227*4887Schin read -u3 && err_exit "not found pattern not positioning at eof" 228*4887Schin cat /tmp/seek$$ | read -r <# *WWW* 229*4887Schin [[ $REPLY == *WWWWW* ]] || err_exit '<# not working for pipes' 230*4887Schinelse err_exit "/tmp/seek$$: cannot open for reading" 231*4887Schinfi 232*4887Schintrap "" EXIT 233*4887Schinrm -f /tmp/seek$$ 234*4887Schin$SHELL -ic ' 235*4887Schin{ 236*4887Schin print -u2 || exit 2 237*4887Schin print -u3 || exit 3 238*4887Schin print -u4 || exit 4 239*4887Schin print -u5 || exit 5 240*4887Schin print -u6 || exit 6 241*4887Schin print -u7 || exit 7 242*4887Schin print -u8 || exit 8 243*4887Schin print -u9 || exit 9 244*4887Schin} 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 245*4887Schinexitval=$? 246*4887Schin(( exitval )) && err_exit "print to unit $exitval failed" 247*4887Schintrap 'rm -rf /tmp/io.sh$$*' EXIT 248*4887Schin$SHELL -c "{ > /tmp/io.sh$$.1 ; date;} >&- 2> /dev/null" > /tmp/io.sh$$.2 249*4887Schin[[ -s /tmp/io.sh$$.1 || -s /tmp/io.sh$$.2 ]] && err_exit 'commands with standard output closed produce output' 250*4887Schin$SHELL -c "$SHELL -c ': 3>&1' 1>&- 2>/dev/null" && err_exit 'closed standard output not passed to subshell' 251*4887Schinexit $((Errors)) 252