14887Schin######################################################################## 24887Schin# # 34887Schin# This software is part of the ast package # 4*8462SApril.Chin@Sun.COM# Copyright (c) 1982-2008 AT&T Intellectual Property # 54887Schin# and is licensed under the # 64887Schin# Common Public License, Version 1.0 # 7*8462SApril.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 30*8462SApril.Chin@Sun.COM 31*8462SApril.Chin@Sun.COMunset HISTFILE 32*8462SApril.Chin@Sun.COM 334887Schinfunction fun 344887Schin{ 354887Schin while command exec 3>&1 364887Schin do break 374887Schin done 2> /dev/null 384887Schin print -u3 good 394887Schin} 404887Schinprint 'read -r a;print -r -u$1 -- "$a"' > /tmp/mycat$$ 414887Schinchmod 755 /tmp/mycat$$ 424887Schinfor ((i=3; i < 10; i++)) 434887Schindo 444887Schin eval "a=\$(print foo | /tmp/mycat$$" $i $i'>&1 > /dev/null |cat)' 2> /dev/null 454887Schin [[ $a == foo ]] || err_exit "bad file descriptor $i in comsub script" 464887Schindone 474887Schinrm -f /tmp/mycat$$ 484887Schinexec 3> /dev/null 494887Schin[[ $(fun) == good ]] || err_exit 'file 3 closed before subshell completes' 504887Schinexec 3>&- 514887Schinmkdir /tmp/ksh$$ || err_exit "mkdir /tmp/ksh$$ failed" 524887Schintrap 'rm -rf /tmp/ksh$$' EXIT 534887Schincd /tmp/ksh$$ || err_exit "cd /tmp/ksh$$ failed" 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 624887Schinif [[ $line != foo ]] 634887Schinthen err_exit '<> not working right with read' 644887Schinfi 654887Schinif ( 4> file1 ) 2> /dev/null 664887Schinthen err_exit 'noclobber not causing exclusive open' 674887Schinfi 684887Schinset +o noclobber 694887Schinif command exec 4< /dev/fd/3 704887Schinthen read -u4 line 714887Schin if [[ $line != bar ]] 724887Schin then '4< /dev/fd/3 not working correctly' 734887Schin fi 744887Schinfi 754887Schincat > close0 <<\! 764887Schinexec 0<&- 774887Schinecho $(./close1) 784887Schin! 794887Schinprint "echo abc" > close1 804887Schinchmod +x close0 close1 814887Schinx=$(./close0) 824887Schinif [[ $x != "abc" ]] 834887Schinthen err_exit "picked up file descriptor zero for opening script file" 844887Schinfi 854887Schincat > close0 <<\! 864887Schin for ((i=0; i < 1100; i++)) 874887Schin do exec 4< /dev/null 884887Schin read -u4 894887Schin done 904887Schin exit 0 914887Schin! 924887Schin./close0 2> /dev/null || err_exit "multiple exec 4< /dev/null can fail" 934887Schin$SHELL -c ' 944887Schin trap "rm -f in$$ out$$" EXIT 954887Schin for ((i = 0; i < 1000; i++)) 964887Schin do print -r -- "This is a test" 974887Schin done > in$$ 984887Schin > out$$ 994887Schin exec 1<> out$$ 1004887Schin builtin cat 1014887Schin print -r -- "$(cat in$$)" 1024887Schin cmp -s in$$ out$$' 2> /dev/null 1034887Schin[[ $? == 0 ]] || err_exit 'builtin cat truncates files' 1044887Schincat >| script <<-\! 1054887Schinprint hello 1064887Schin( exec 3<&- 4<&-) 1074887Schinexec 3<&- 4<&- 1084887Schinprint world 1094887Schin! 1104887Schinchmod +x script 1114887Schin[[ $( $SHELL ./script) == $'hello\nworld' ]] || err_exit 'closing 3 & 4 causes script to fail' 1124887Schincd ~- || err_exit "cd back failed" 1134887Schin( exec > '' ) 2> /dev/null && err_exit '> "" does not fail' 1144887Schinunset x 1154887Schin( exec > ${x} ) 2> /dev/null && err_exit '> $x, where x null does not fail' 1164887Schinexec <<! 1174887Schinfoo 1184887Schinbar 1194887Schin! 1204887Schin( exec 0< /dev/null) 1214887Schinread line 1224887Schinif [[ $line != foo ]] 1234887Schinthen err_exit 'file descriptor not restored after exec in subshell' 1244887Schinfi 1254887Schinexec 3>&- 4>&-; cd /; rm -r /tmp/ksh$$ || err_exit "rm -r /tmp/ksh$$ failed" 1264887Schin[[ $( { 1274887Schin read -r line;print -r -- "$line" 1284887Schin ( 1294887Schin read -r line;print -r -- "$line" 1304887Schin ) & wait 1314887Schin while read -r line 1324887Schin do print -r -- "$line" 1334887Schin done 1344887Schin } << ! 1354887Schinline 1 1364887Schinline 2 1374887Schinline 3 1384887Schin!) == $'line 1\nline 2\nline 3' ]] || err_exit 'read error with subshells' 1394887Schin# 2004-05-11 bug fix 1404887Schincat > /tmp/io$$.1 <<- \++EOF++ 1414887Schin script=/tmp/io$$.2 1424887Schin trap 'rm -f $script' EXIT 1434887Schin exec 9> $script 1444887Schin for ((i=3; i<9; i++)) 1454887Schin do eval "while read -u$i; do : ;done $i</dev/null" 1464887Schin print -u9 "exec $i< /dev/null" 1474887Schin done 1484887Schin for ((i=0; i < 60; i++)) 1494887Schin do print -u9 -f "%.80c\n" ' ' 1504887Schin done 1514887Schin print -u9 'print ok' 1524887Schin exec 9<&- 1534887Schin chmod +x $script 1544887Schin $script 1554887Schin++EOF++ 1564887Schinchmod +x /tmp/io$$.1 1574887Schin[[ $($SHELL /tmp/io$$.1) == ok ]] || err_exit "parent i/o causes child script to fail" 1584887Schinrm -rf /tmp/io$$.[12] 1594887Schin# 2004-11-25 ancient /dev/fd/NN redirection bug fix 1604887Schinx=$( 1614887Schin { 1624887Schin print -n 1 1634887Schin print -n 2 > /dev/fd/2 1644887Schin print -n 3 1654887Schin print -n 4 > /dev/fd/2 1664887Schin } 2>&1 1674887Schin) 1684887Schin[[ $x == "1234" ]] || err_exit "/dev/fd/NN redirection fails to dup" 1694887Schin# 2004-12-20 redirction loss bug fix 1704887Schincat > /tmp/io$$.1 <<- \++EOF++ 1714887Schin function a 1724887Schin { 1734887Schin trap 'print ok' EXIT 1744887Schin : > /dev/null 1754887Schin } 1764887Schin a 1774887Schin++EOF++ 1784887Schinchmod +x /tmp/io$$.1 1794887Schin[[ $(/tmp/io$$.1) == ok ]] || err_exit "trap on EXIT loses last command redirection" 1804887Schinprint > /dev/null {n}> /tmp/io$$.1 1814887Schin[[ ! -s /tmp/io$$.1 ]] && newio=1 1824887Schinrm -rf /tmp/io$$.1 1834887Schinif [[ $newio && $(print hello | while read -u$n; do print $REPLY; done {n}<&0) != hello ]] 1844887Schinthen err_exit "{n}<&0 not working with for loop" 1854887Schinfi 1864887Schin[[ $({ read -r;read -u3 3<&0; print -- "$REPLY" ;} <<! 1874887Schinhello 1884887Schinworld 1894887Schin!) == world ]] || err_exit 'I/O not synchronized with <&' 1904887Schintrap 'rm -f /tmp/seek$$; exit $((Errors+1))' EXIT 1914887Schinx="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNSPQRSTUVWXYZ1234567890" 1924887Schinfor ((i=0; i < 62; i++)) 1934887Schindo printf "%.39c\n" ${x:i:1} 1944887Schindone > /tmp/seek$$ 1954887Schinif command exec 3<> /tmp/seek$$ 1964887Schinthen (( $(3<#) == 0 )) || err_exit "not at position 0" 1974887Schin (( $(3<# ((EOF))) == 40*62 )) || err_exit "not at end-of-file" 1984887Schin command exec 3<# ((40*8)) || err_exit "absolute seek fails" 1994887Schin read -u3 2004887Schin [[ $REPLY == +(i) ]] || err_exit "expecting iiii..." 2014887Schin [[ $(3<#) == $(3<# ((CUR)) ) ]] || err_exit '$(3<#)!=$(3<#((CUR)))' 2024887Schin command exec 3<# ((CUR+80)) 2034887Schin read -u3 2044887Schin [[ $REPLY == {39}(l) ]] || err_exit "expecting lll..." 2054887Schin command exec 3<# ((EOF-80)) 2064887Schin read -u3 2074887Schin [[ $REPLY == +(9) ]] || err_exit "expecting 999...; got $REPLY" 2084887Schin command exec 3># ((80)) 2094887Schin print -u3 -f "%.39c\n" @ 2104887Schin command exec 3># ((80)) 2114887Schin read -u3 2124887Schin [[ $REPLY == +(@) ]] || err_exit "expecting @@@..." 2134887Schin read -u3 2144887Schin [[ $REPLY == +(d) ]] || err_exit "expecting ddd..." 2154887Schin command exec 3># ((EOF)) 2164887Schin print -u3 -f "%.39c\n" ^ 2174887Schin (( $(3<# ((CUR-0))) == 40*63 )) || err_exit "not at extended end-of-file" 2184887Schin command exec 3<# ((40*62)) 2194887Schin read -u3 2204887Schin [[ $REPLY == +(^) ]] || err_exit "expecting ddd..." 2214887Schin command exec 3<# ((0)) 2224887Schin command exec 3<# *jjjj* 2234887Schin read -u3 2244887Schin [[ $REPLY == {39}(j) ]] || err_exit "<# pattern failed" 2254887Schin [[ $(command exec 3<## *llll*) = {39}(k) ]] || err_exit "<## pattern not saving standard output" 2264887Schin read -u3 2274887Schin [[ $REPLY == {39}(l) ]] || err_exit "<## pattern failed to position" 2284887Schin command exec 3<# *abc* 2294887Schin read -u3 && err_exit "not found pattern not positioning at eof" 2304887Schin cat /tmp/seek$$ | read -r <# *WWW* 2314887Schin [[ $REPLY == *WWWWW* ]] || err_exit '<# not working for pipes' 232*8462SApril.Chin@Sun.COM { < /tmp/seek$$ <# ((2358336120)) ;} 2> /dev/null || err_exit 'long seek not working' 2334887Schinelse err_exit "/tmp/seek$$: cannot open for reading" 2344887Schinfi 235*8462SApril.Chin@Sun.COMcommand exec 3<&- || 'cannot close 3' 236*8462SApril.Chin@Sun.COMfor ((i=0; i < 62; i++)) 237*8462SApril.Chin@Sun.COMdo printf "%.39c\n" ${x:i:1} 238*8462SApril.Chin@Sun.COMdone > /tmp/seek$$ 239*8462SApril.Chin@Sun.COMif command exec {n}<> /tmp/seek$$ 240*8462SApril.Chin@Sun.COMthen { command exec {n}<#((EOF)) ;} 2> /dev/null || err_exit '{n}<# not working' 241*8462SApril.Chin@Sun.COM if $SHELL -c '{n}</dev/null' 2> /dev/null 242*8462SApril.Chin@Sun.COM then (( $({n}<#) == 40*62)) || err_exit '$({n}<#) not working' 243*8462SApril.Chin@Sun.COM else err_exit 'not able to parse {n}</dev/null' 244*8462SApril.Chin@Sun.COM fi 245*8462SApril.Chin@Sun.COMfi 2464887Schintrap "" EXIT 2474887Schinrm -f /tmp/seek$$ 2484887Schin$SHELL -ic ' 2494887Schin{ 2504887Schin print -u2 || exit 2 2514887Schin print -u3 || exit 3 2524887Schin print -u4 || exit 4 2534887Schin print -u5 || exit 5 2544887Schin print -u6 || exit 6 2554887Schin print -u7 || exit 7 2564887Schin print -u8 || exit 8 2574887Schin print -u9 || exit 9 2584887Schin} 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 2594887Schinexitval=$? 2604887Schin(( exitval )) && err_exit "print to unit $exitval failed" 2614887Schintrap 'rm -rf /tmp/io.sh$$*' EXIT 2624887Schin$SHELL -c "{ > /tmp/io.sh$$.1 ; date;} >&- 2> /dev/null" > /tmp/io.sh$$.2 2634887Schin[[ -s /tmp/io.sh$$.1 || -s /tmp/io.sh$$.2 ]] && err_exit 'commands with standard output closed produce output' 2644887Schin$SHELL -c "$SHELL -c ': 3>&1' 1>&- 2>/dev/null" && err_exit 'closed standard output not passed to subshell' 265*8462SApril.Chin@Sun.COM[[ $(cat <<- \EOF | $SHELL 266*8462SApril.Chin@Sun.COM do_it_all() 267*8462SApril.Chin@Sun.COM { 268*8462SApril.Chin@Sun.COM dd 2>/dev/null # not a ksh93 buildin 269*8462SApril.Chin@Sun.COM return $? 270*8462SApril.Chin@Sun.COM } 271*8462SApril.Chin@Sun.COM do_it_all ; exit $? 272*8462SApril.Chin@Sun.COM hello world 273*8462SApril.Chin@Sun.COMEOF) == 'hello world' ]] || err_exit 'invalid readahead on stdin' 274*8462SApril.Chin@Sun.COM$SHELL -c 'exec 3>; /dev/null' 2> /dev/null && err_exit '>; with exec should be an error' 275*8462SApril.Chin@Sun.COM$SHELL -c ': 3>; /dev/null' 2> /dev/null || err_exit '>; not working with at all' 276*8462SApril.Chin@Sun.COMprint hello > /tmp/io.sh$$.1 277*8462SApril.Chin@Sun.COMif ! $SHELL -c "false >; /tmp/io.sh$$.1" 2> /dev/null 278*8462SApril.Chin@Sun.COMthen [[ $(</tmp/io.sh$$.1) == hello ]] || err_exit '>; not preserving file on failure' 279*8462SApril.Chin@Sun.COMfi 280*8462SApril.Chin@Sun.COMif ! $SHELL -c "sed -e 's/hello/hello world/' /tmp/io.sh$$.1" >; /tmp/io.sh$$.1 2> /dev/null 281*8462SApril.Chin@Sun.COMthen [[ $(</tmp/io.sh$$.1) == 'hello world' ]] || err_exit '>; not updating file on success' 282*8462SApril.Chin@Sun.COMfi 283*8462SApril.Chin@Sun.COM 284*8462SApril.Chin@Sun.COMunset y 285*8462SApril.Chin@Sun.COMread -n1 y <<! 286*8462SApril.Chin@Sun.COMabc 287*8462SApril.Chin@Sun.COM! 288*8462SApril.Chin@Sun.COMif [[ $y != a ]] 289*8462SApril.Chin@Sun.COMthen err_exit 'read -n1 not working' 290*8462SApril.Chin@Sun.COMfi 291*8462SApril.Chin@Sun.COMunset a 292*8462SApril.Chin@Sun.COM{ read -N3 a; read -N1 b;} <<! 293*8462SApril.Chin@Sun.COMabcdefg 294*8462SApril.Chin@Sun.COM! 295*8462SApril.Chin@Sun.COM[[ $a == abc ]] || err_exit 'read -N3 here-document not working' 296*8462SApril.Chin@Sun.COM[[ $b == d ]] || err_exit 'read -N1 here-document not working' 297*8462SApril.Chin@Sun.COMread -n3 a <<! 298*8462SApril.Chin@Sun.COMabcdefg 299*8462SApril.Chin@Sun.COM! 300*8462SApril.Chin@Sun.COM[[ $a == abc ]] || err_exit 'read -n3 here-document not working' 301*8462SApril.Chin@Sun.COM(print -n a;sleep 1; print -n bcde) | { read -N3 a; read -N1 b;} 302*8462SApril.Chin@Sun.COM[[ $a == abc ]] || err_exit 'read -N3 from pipe not working' 303*8462SApril.Chin@Sun.COM[[ $b == d ]] || err_exit 'read -N1 from pipe not working' 304*8462SApril.Chin@Sun.COM(print -n a;sleep 1; print -n bcde) |read -n3 a 305*8462SApril.Chin@Sun.COM[[ $a == a ]] || err_exit 'read -n3 from pipe not working' 306*8462SApril.Chin@Sun.COMrm -f /tmp/fifo$$ 307*8462SApril.Chin@Sun.COMif mkfifo /tmp/fifo$$ 2> /dev/null 308*8462SApril.Chin@Sun.COMthen (print -n a; sleep 1;print -n bcde) > /tmp/fifo$$ & 309*8462SApril.Chin@Sun.COM { 310*8462SApril.Chin@Sun.COM read -u5 -n3 -t2 a || err_exit 'read -n3 from fifo timedout' 311*8462SApril.Chin@Sun.COM read -u5 -n1 -t2 b || err_exit 'read -n1 from fifo timedout' 312*8462SApril.Chin@Sun.COM } 5< /tmp/fifo$$ 313*8462SApril.Chin@Sun.COM [[ $a == a ]] || err_exit 'read -n3 from fifo not working' 314*8462SApril.Chin@Sun.COM rm -f /tmp/fifo$$ 315*8462SApril.Chin@Sun.COM mkfifo /tmp/fifo$$ 2> /dev/null 316*8462SApril.Chin@Sun.COM (print -n a; sleep 1;print -n bcde) > /tmp/fifo$$ & 317*8462SApril.Chin@Sun.COM { 318*8462SApril.Chin@Sun.COM read -u5 -N3 -t2 a || err_exit 'read -N3 from fifo timed out' 319*8462SApril.Chin@Sun.COM read -u5 -N1 -t2 b || err_exit 'read -N1 from fifo timedout' 320*8462SApril.Chin@Sun.COM } 5< /tmp/fifo$$ 321*8462SApril.Chin@Sun.COM [[ $a == abc ]] || err_exit 'read -N3 from fifo not working' 322*8462SApril.Chin@Sun.COM [[ $b == d ]] || err_exit 'read -N1 from fifo not working' 323*8462SApril.Chin@Sun.COMfi 324*8462SApril.Chin@Sun.COMrm -f /tmp/fifo$$ 325*8462SApril.Chin@Sun.COM 326*8462SApril.Chin@Sun.COMif $SHELL -c "export LC_ALL=en_US.UTF-8; c=$'\342\202\254'; [[ \${#c} == 1 ]]" 2>/dev/null 327*8462SApril.Chin@Sun.COMthen lc_utf8=en_US.UTF-8 328*8462SApril.Chin@Sun.COMelse lc_utf8='' 329*8462SApril.Chin@Sun.COMfi 330*8462SApril.Chin@Sun.COM 331*8462SApril.Chin@Sun.COMtypeset -a e o=(-n2 -N2) 332*8462SApril.Chin@Sun.COMinteger i 333*8462SApril.Chin@Sun.COMset -- \ 334*8462SApril.Chin@Sun.COM 'a' 'bcd' 'a bcd' 'ab cd' \ 335*8462SApril.Chin@Sun.COM 'ab' 'cd' 'ab cd' 'ab cd' \ 336*8462SApril.Chin@Sun.COM 'abc' 'd' 'ab cd' 'ab cd' \ 337*8462SApril.Chin@Sun.COM 'abcd' '' 'ab cd' 'ab cd' 338*8462SApril.Chin@Sun.COMwhile (( $# >= 3 )) 339*8462SApril.Chin@Sun.COMdo a=$1 340*8462SApril.Chin@Sun.COM b=$2 341*8462SApril.Chin@Sun.COM e[0]=$3 342*8462SApril.Chin@Sun.COM e[1]=$4 343*8462SApril.Chin@Sun.COM shift 4 344*8462SApril.Chin@Sun.COM for ((i = 0; i < 2; i++)) 345*8462SApril.Chin@Sun.COM do for lc_all in C $lc_utf8 346*8462SApril.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; }") 347*8462SApril.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'" 348*8462SApril.Chin@Sun.COM done 349*8462SApril.Chin@Sun.COM done 350*8462SApril.Chin@Sun.COMdone 351*8462SApril.Chin@Sun.COM 352*8462SApril.Chin@Sun.COMif [[ $lc_utf8 ]] 353*8462SApril.Chin@Sun.COMthen export LC_ALL=en_US.UTF-8 354*8462SApril.Chin@Sun.COM typeset -a c=( '' 'A' $'\303\274' $'\342\202\254' ) 355*8462SApril.Chin@Sun.COM integer i w 356*8462SApril.Chin@Sun.COM typeset o 357*8462SApril.Chin@Sun.COM if (( ${#c[2]} == 1 && ${#c[3]} == 1 )) 358*8462SApril.Chin@Sun.COM then for i in 1 2 3 359*8462SApril.Chin@Sun.COM do for o in n N 360*8462SApril.Chin@Sun.COM do for w in 1 2 3 361*8462SApril.Chin@Sun.COM do print -nr "${c[w]}" | read -${o}${i} g 362*8462SApril.Chin@Sun.COM if [[ $o == N ]] && (( i > 1 )) 363*8462SApril.Chin@Sun.COM then e='' 364*8462SApril.Chin@Sun.COM else e=${c[w]} 365*8462SApril.Chin@Sun.COM fi 366*8462SApril.Chin@Sun.COM [[ $g == "$e" ]] || err_exit "read -${o}${i} failed for '${c[w]}' -- expected '$e', got '$g'" 367*8462SApril.Chin@Sun.COM done 368*8462SApril.Chin@Sun.COM done 369*8462SApril.Chin@Sun.COM done 370*8462SApril.Chin@Sun.COM fi 371*8462SApril.Chin@Sun.COMfi 372*8462SApril.Chin@Sun.COM 3734887Schinexit $((Errors)) 374