1######################################################################## 2# # 3# This software is part of the ast package # 4# Copyright (c) 1982-2008 AT&T Intellectual Property # 5# and is licensed under the # 6# Common Public License, Version 1.0 # 7# by AT&T Intellectual Property # 8# # 9# A copy of the License is available at # 10# http://www.opensource.org/licenses/cpl1.0.txt # 11# (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) # 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 31unset HISTFILE 32 33function fun 34{ 35 while command exec 3>&1 36 do break 37 done 2> /dev/null 38 print -u3 good 39} 40print 'read -r a;print -r -u$1 -- "$a"' > /tmp/mycat$$ 41chmod 755 /tmp/mycat$$ 42for ((i=3; i < 10; i++)) 43do 44 eval "a=\$(print foo | /tmp/mycat$$" $i $i'>&1 > /dev/null |cat)' 2> /dev/null 45 [[ $a == foo ]] || err_exit "bad file descriptor $i in comsub script" 46done 47rm -f /tmp/mycat$$ 48exec 3> /dev/null 49[[ $(fun) == good ]] || err_exit 'file 3 closed before subshell completes' 50exec 3>&- 51mkdir /tmp/ksh$$ || err_exit "mkdir /tmp/ksh$$ failed" 52trap 'rm -rf /tmp/ksh$$' EXIT 53cd /tmp/ksh$$ || err_exit "cd /tmp/ksh$$ failed" 54print foo > file1 55print bar >> file1 56if [[ $(<file1) != $'foo\nbar' ]] 57then err_exit 'append (>>) not working' 58fi 59set -o noclobber 60exec 3<> file1 61read -u3 line 62if [[ $line != foo ]] 63then err_exit '<> not working right with read' 64fi 65if ( 4> file1 ) 2> /dev/null 66then err_exit 'noclobber not causing exclusive open' 67fi 68set +o noclobber 69if command exec 4< /dev/fd/3 70then read -u4 line 71 if [[ $line != bar ]] 72 then '4< /dev/fd/3 not working correctly' 73 fi 74fi 75cat > close0 <<\! 76exec 0<&- 77echo $(./close1) 78! 79print "echo abc" > close1 80chmod +x close0 close1 81x=$(./close0) 82if [[ $x != "abc" ]] 83then err_exit "picked up file descriptor zero for opening script file" 84fi 85cat > close0 <<\! 86 for ((i=0; i < 1100; i++)) 87 do exec 4< /dev/null 88 read -u4 89 done 90 exit 0 91! 92./close0 2> /dev/null || err_exit "multiple exec 4< /dev/null can fail" 93$SHELL -c ' 94 trap "rm -f in$$ out$$" EXIT 95 for ((i = 0; i < 1000; i++)) 96 do print -r -- "This is a test" 97 done > in$$ 98 > out$$ 99 exec 1<> out$$ 100 builtin cat 101 print -r -- "$(cat in$$)" 102 cmp -s in$$ out$$' 2> /dev/null 103[[ $? == 0 ]] || err_exit 'builtin cat truncates files' 104cat >| script <<-\! 105print hello 106( exec 3<&- 4<&-) 107exec 3<&- 4<&- 108print world 109! 110chmod +x script 111[[ $( $SHELL ./script) == $'hello\nworld' ]] || err_exit 'closing 3 & 4 causes script to fail' 112cd ~- || err_exit "cd back failed" 113( exec > '' ) 2> /dev/null && err_exit '> "" does not fail' 114unset x 115( exec > ${x} ) 2> /dev/null && err_exit '> $x, where x null does not fail' 116exec <<! 117foo 118bar 119! 120( exec 0< /dev/null) 121read line 122if [[ $line != foo ]] 123then err_exit 'file descriptor not restored after exec in subshell' 124fi 125exec 3>&- 4>&-; cd /; rm -r /tmp/ksh$$ || err_exit "rm -r /tmp/ksh$$ failed" 126[[ $( { 127 read -r line;print -r -- "$line" 128 ( 129 read -r line;print -r -- "$line" 130 ) & wait 131 while read -r line 132 do print -r -- "$line" 133 done 134 } << ! 135line 1 136line 2 137line 3 138!) == $'line 1\nline 2\nline 3' ]] || err_exit 'read error with subshells' 139# 2004-05-11 bug fix 140cat > /tmp/io$$.1 <<- \++EOF++ 141 script=/tmp/io$$.2 142 trap 'rm -f $script' EXIT 143 exec 9> $script 144 for ((i=3; i<9; i++)) 145 do eval "while read -u$i; do : ;done $i</dev/null" 146 print -u9 "exec $i< /dev/null" 147 done 148 for ((i=0; i < 60; i++)) 149 do print -u9 -f "%.80c\n" ' ' 150 done 151 print -u9 'print ok' 152 exec 9<&- 153 chmod +x $script 154 $script 155++EOF++ 156chmod +x /tmp/io$$.1 157[[ $($SHELL /tmp/io$$.1) == ok ]] || err_exit "parent i/o causes child script to fail" 158rm -rf /tmp/io$$.[12] 159# 2004-11-25 ancient /dev/fd/NN redirection bug fix 160x=$( 161 { 162 print -n 1 163 print -n 2 > /dev/fd/2 164 print -n 3 165 print -n 4 > /dev/fd/2 166 } 2>&1 167) 168[[ $x == "1234" ]] || err_exit "/dev/fd/NN redirection fails to dup" 169# 2004-12-20 redirction loss bug fix 170cat > /tmp/io$$.1 <<- \++EOF++ 171 function a 172 { 173 trap 'print ok' EXIT 174 : > /dev/null 175 } 176 a 177++EOF++ 178chmod +x /tmp/io$$.1 179[[ $(/tmp/io$$.1) == ok ]] || err_exit "trap on EXIT loses last command redirection" 180print > /dev/null {n}> /tmp/io$$.1 181[[ ! -s /tmp/io$$.1 ]] && newio=1 182rm -rf /tmp/io$$.1 183if [[ $newio && $(print hello | while read -u$n; do print $REPLY; done {n}<&0) != hello ]] 184then err_exit "{n}<&0 not working with for loop" 185fi 186[[ $({ read -r;read -u3 3<&0; print -- "$REPLY" ;} <<! 187hello 188world 189!) == world ]] || err_exit 'I/O not synchronized with <&' 190trap 'rm -f /tmp/seek$$; exit $((Errors+1))' EXIT 191x="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNSPQRSTUVWXYZ1234567890" 192for ((i=0; i < 62; i++)) 193do printf "%.39c\n" ${x:i:1} 194done > /tmp/seek$$ 195if command exec 3<> /tmp/seek$$ 196then (( $(3<#) == 0 )) || err_exit "not at position 0" 197 (( $(3<# ((EOF))) == 40*62 )) || err_exit "not at end-of-file" 198 command exec 3<# ((40*8)) || err_exit "absolute seek fails" 199 read -u3 200 [[ $REPLY == +(i) ]] || err_exit "expecting iiii..." 201 [[ $(3<#) == $(3<# ((CUR)) ) ]] || err_exit '$(3<#)!=$(3<#((CUR)))' 202 command exec 3<# ((CUR+80)) 203 read -u3 204 [[ $REPLY == {39}(l) ]] || err_exit "expecting lll..." 205 command exec 3<# ((EOF-80)) 206 read -u3 207 [[ $REPLY == +(9) ]] || err_exit "expecting 999...; got $REPLY" 208 command exec 3># ((80)) 209 print -u3 -f "%.39c\n" @ 210 command exec 3># ((80)) 211 read -u3 212 [[ $REPLY == +(@) ]] || err_exit "expecting @@@..." 213 read -u3 214 [[ $REPLY == +(d) ]] || err_exit "expecting ddd..." 215 command exec 3># ((EOF)) 216 print -u3 -f "%.39c\n" ^ 217 (( $(3<# ((CUR-0))) == 40*63 )) || err_exit "not at extended end-of-file" 218 command exec 3<# ((40*62)) 219 read -u3 220 [[ $REPLY == +(^) ]] || err_exit "expecting ddd..." 221 command exec 3<# ((0)) 222 command exec 3<# *jjjj* 223 read -u3 224 [[ $REPLY == {39}(j) ]] || err_exit "<# pattern failed" 225 [[ $(command exec 3<## *llll*) = {39}(k) ]] || err_exit "<## pattern not saving standard output" 226 read -u3 227 [[ $REPLY == {39}(l) ]] || err_exit "<## pattern failed to position" 228 command exec 3<# *abc* 229 read -u3 && err_exit "not found pattern not positioning at eof" 230 cat /tmp/seek$$ | read -r <# *WWW* 231 [[ $REPLY == *WWWWW* ]] || err_exit '<# not working for pipes' 232 { < /tmp/seek$$ <# ((2358336120)) ;} 2> /dev/null || err_exit 'long seek not working' 233else err_exit "/tmp/seek$$: cannot open for reading" 234fi 235command exec 3<&- || 'cannot close 3' 236for ((i=0; i < 62; i++)) 237do printf "%.39c\n" ${x:i:1} 238done > /tmp/seek$$ 239if command exec {n}<> /tmp/seek$$ 240then { command exec {n}<#((EOF)) ;} 2> /dev/null || err_exit '{n}<# not working' 241 if $SHELL -c '{n}</dev/null' 2> /dev/null 242 then (( $({n}<#) == 40*62)) || err_exit '$({n}<#) not working' 243 else err_exit 'not able to parse {n}</dev/null' 244 fi 245fi 246trap "" EXIT 247rm -f /tmp/seek$$ 248$SHELL -ic ' 249{ 250 print -u2 || exit 2 251 print -u3 || exit 3 252 print -u4 || exit 4 253 print -u5 || exit 5 254 print -u6 || exit 6 255 print -u7 || exit 7 256 print -u8 || exit 8 257 print -u9 || exit 9 258} 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 259exitval=$? 260(( exitval )) && err_exit "print to unit $exitval failed" 261trap 'rm -rf /tmp/io.sh$$*' EXIT 262$SHELL -c "{ > /tmp/io.sh$$.1 ; date;} >&- 2> /dev/null" > /tmp/io.sh$$.2 263[[ -s /tmp/io.sh$$.1 || -s /tmp/io.sh$$.2 ]] && err_exit 'commands with standard output closed produce output' 264$SHELL -c "$SHELL -c ': 3>&1' 1>&- 2>/dev/null" && err_exit 'closed standard output not passed to subshell' 265[[ $(cat <<- \EOF | $SHELL 266 do_it_all() 267 { 268 dd 2>/dev/null # not a ksh93 buildin 269 return $? 270 } 271 do_it_all ; exit $? 272 hello world 273EOF) == 'hello world' ]] || err_exit 'invalid readahead on stdin' 274$SHELL -c 'exec 3>; /dev/null' 2> /dev/null && err_exit '>; with exec should be an error' 275$SHELL -c ': 3>; /dev/null' 2> /dev/null || err_exit '>; not working with at all' 276print hello > /tmp/io.sh$$.1 277if ! $SHELL -c "false >; /tmp/io.sh$$.1" 2> /dev/null 278then [[ $(</tmp/io.sh$$.1) == hello ]] || err_exit '>; not preserving file on failure' 279fi 280if ! $SHELL -c "sed -e 's/hello/hello world/' /tmp/io.sh$$.1" >; /tmp/io.sh$$.1 2> /dev/null 281then [[ $(</tmp/io.sh$$.1) == 'hello world' ]] || err_exit '>; not updating file on success' 282fi 283 284unset y 285read -n1 y <<! 286abc 287! 288if [[ $y != a ]] 289then err_exit 'read -n1 not working' 290fi 291unset a 292{ read -N3 a; read -N1 b;} <<! 293abcdefg 294! 295[[ $a == abc ]] || err_exit 'read -N3 here-document not working' 296[[ $b == d ]] || err_exit 'read -N1 here-document not working' 297read -n3 a <<! 298abcdefg 299! 300[[ $a == abc ]] || err_exit 'read -n3 here-document not working' 301(print -n a;sleep 1; print -n bcde) | { read -N3 a; read -N1 b;} 302[[ $a == abc ]] || err_exit 'read -N3 from pipe not working' 303[[ $b == d ]] || err_exit 'read -N1 from pipe not working' 304(print -n a;sleep 1; print -n bcde) |read -n3 a 305[[ $a == a ]] || err_exit 'read -n3 from pipe not working' 306rm -f /tmp/fifo$$ 307if mkfifo /tmp/fifo$$ 2> /dev/null 308then (print -n a; sleep 1;print -n bcde) > /tmp/fifo$$ & 309 { 310 read -u5 -n3 -t2 a || err_exit 'read -n3 from fifo timedout' 311 read -u5 -n1 -t2 b || err_exit 'read -n1 from fifo timedout' 312 } 5< /tmp/fifo$$ 313 [[ $a == a ]] || err_exit 'read -n3 from fifo not working' 314 rm -f /tmp/fifo$$ 315 mkfifo /tmp/fifo$$ 2> /dev/null 316 (print -n a; sleep 1;print -n bcde) > /tmp/fifo$$ & 317 { 318 read -u5 -N3 -t2 a || err_exit 'read -N3 from fifo timed out' 319 read -u5 -N1 -t2 b || err_exit 'read -N1 from fifo timedout' 320 } 5< /tmp/fifo$$ 321 [[ $a == abc ]] || err_exit 'read -N3 from fifo not working' 322 [[ $b == d ]] || err_exit 'read -N1 from fifo not working' 323fi 324rm -f /tmp/fifo$$ 325 326if $SHELL -c "export LC_ALL=en_US.UTF-8; c=$'\342\202\254'; [[ \${#c} == 1 ]]" 2>/dev/null 327then lc_utf8=en_US.UTF-8 328else lc_utf8='' 329fi 330 331typeset -a e o=(-n2 -N2) 332integer i 333set -- \ 334 'a' 'bcd' 'a bcd' 'ab cd' \ 335 'ab' 'cd' 'ab cd' 'ab cd' \ 336 'abc' 'd' 'ab cd' 'ab cd' \ 337 'abcd' '' 'ab cd' 'ab cd' 338while (( $# >= 3 )) 339do a=$1 340 b=$2 341 e[0]=$3 342 e[1]=$4 343 shift 4 344 for ((i = 0; i < 2; i++)) 345 do for lc_all in C $lc_utf8 346 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; }") 347 [[ $g == "${e[i]}" ]] || err_exit "LC_ALL=$lc_all read ${o[i]} from pipe '$a $b' failed -- expected '${e[i]}', got '$g'" 348 done 349 done 350done 351 352if [[ $lc_utf8 ]] 353then export LC_ALL=en_US.UTF-8 354 typeset -a c=( '' 'A' $'\303\274' $'\342\202\254' ) 355 integer i w 356 typeset o 357 if (( ${#c[2]} == 1 && ${#c[3]} == 1 )) 358 then for i in 1 2 3 359 do for o in n N 360 do for w in 1 2 3 361 do print -nr "${c[w]}" | read -${o}${i} g 362 if [[ $o == N ]] && (( i > 1 )) 363 then e='' 364 else e=${c[w]} 365 fi 366 [[ $g == "$e" ]] || err_exit "read -${o}${i} failed for '${c[w]}' -- expected '$e', got '$g'" 367 done 368 done 369 done 370 fi 371fi 372 373exit $((Errors)) 374