1da2e3ebdSchin######################################################################## 2da2e3ebdSchin# # 3da2e3ebdSchin# This software is part of the ast package # 4*3e14f97fSRoger A. Faulkner# Copyright (c) 1982-2010 AT&T Intellectual Property # 5da2e3ebdSchin# and is licensed under the # 6da2e3ebdSchin# Common Public License, Version 1.0 # 77c2fbfb3SApril Chin# by AT&T Intellectual Property # 8da2e3ebdSchin# # 9da2e3ebdSchin# A copy of the License is available at # 10da2e3ebdSchin# http://www.opensource.org/licenses/cpl1.0.txt # 11da2e3ebdSchin# (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) # 12da2e3ebdSchin# # 13da2e3ebdSchin# Information and Software Systems Research # 14da2e3ebdSchin# AT&T Research # 15da2e3ebdSchin# Florham Park NJ # 16da2e3ebdSchin# # 17da2e3ebdSchin# David Korn <dgk@research.att.com> # 18da2e3ebdSchin# # 19da2e3ebdSchin######################################################################## 20da2e3ebdSchinfunction err_exit 21da2e3ebdSchin{ 22da2e3ebdSchin print -u2 -n "\t" 23da2e3ebdSchin print -u2 -r ${Command}[$1]: "${@:2}" 24da2e3ebdSchin let Errors+=1 25da2e3ebdSchin} 26da2e3ebdSchinalias err_exit='err_exit $LINENO' 27da2e3ebdSchin 28da2e3ebdSchinCommand=${0##*/} 29da2e3ebdSchininteger Errors=0 307c2fbfb3SApril Chin 3134f9b3eeSRoland Mainztmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 3234f9b3eeSRoland Mainztrap "cd /; rm -rf $tmp" EXIT 3334f9b3eeSRoland Mainz 347c2fbfb3SApril Chinunset HISTFILE 357c2fbfb3SApril Chin 36da2e3ebdSchinfunction fun 37da2e3ebdSchin{ 38da2e3ebdSchin while command exec 3>&1 39da2e3ebdSchin do break 40da2e3ebdSchin done 2> /dev/null 41da2e3ebdSchin print -u3 good 42da2e3ebdSchin} 4334f9b3eeSRoland Mainzprint 'read -r a;print -r -u$1 -- "$a"' > $tmp/mycat 4434f9b3eeSRoland Mainzchmod 755 $tmp/mycat 45da2e3ebdSchinfor ((i=3; i < 10; i++)) 46da2e3ebdSchindo 4734f9b3eeSRoland Mainz eval "a=\$(print foo | $tmp/mycat" $i $i'>&1 > /dev/null |cat)' 2> /dev/null 48da2e3ebdSchin [[ $a == foo ]] || err_exit "bad file descriptor $i in comsub script" 49da2e3ebdSchindone 50da2e3ebdSchinexec 3> /dev/null 51da2e3ebdSchin[[ $(fun) == good ]] || err_exit 'file 3 closed before subshell completes' 52da2e3ebdSchinexec 3>&- 5334f9b3eeSRoland Mainzcd $tmp || { err_exit "cd $tmp failed"; exit ; } 54da2e3ebdSchinprint foo > file1 55da2e3ebdSchinprint bar >> file1 56da2e3ebdSchinif [[ $(<file1) != $'foo\nbar' ]] 57da2e3ebdSchinthen err_exit 'append (>>) not working' 58da2e3ebdSchinfi 59da2e3ebdSchinset -o noclobber 60da2e3ebdSchinexec 3<> file1 61da2e3ebdSchinread -u3 line 6234f9b3eeSRoland Mainzexp=foo 6334f9b3eeSRoland Mainzif [[ $line != $exp ]] 6434f9b3eeSRoland Mainzthen err_exit "read on <> fd failed -- expected '$exp', got '$line'" 65da2e3ebdSchinfi 66da2e3ebdSchinif ( 4> file1 ) 2> /dev/null 67da2e3ebdSchinthen err_exit 'noclobber not causing exclusive open' 68da2e3ebdSchinfi 69da2e3ebdSchinset +o noclobber 7034f9b3eeSRoland Mainz 7134f9b3eeSRoland MainzFDFS=( 7234f9b3eeSRoland Mainz ( dir=/proc/self/fd semantics='open' ) 7334f9b3eeSRoland Mainz ( dir=/proc/$$/fd semantics='open' ) 7434f9b3eeSRoland Mainz ( dir=/dev/fd semantics='open|dup' ) 7534f9b3eeSRoland Mainz ( dir=/dev/fd semantics='dup' ) 7634f9b3eeSRoland Mainz) 7734f9b3eeSRoland Mainzfor ((fdfs=0; fdfs<${#FDFS[@]}-1; fdfs++)) 7834f9b3eeSRoland Mainzdo [[ -e ${FDFS[fdfs].dir} ]] && { command : > ${FDFS[fdfs].dir}/1; } 2>/dev/null && break 7934f9b3eeSRoland Mainzdone 8034f9b3eeSRoland Mainz 8134f9b3eeSRoland Mainzexec 3<> file1 8234f9b3eeSRoland Mainzif command exec 4< ${FDFS[fdfs].dir}/3 8334f9b3eeSRoland Mainzthen read -u3 got 8434f9b3eeSRoland Mainz read -u4 got 8534f9b3eeSRoland Mainz exp='foo|bar' 8634f9b3eeSRoland Mainz case $got in 8734f9b3eeSRoland Mainz foo) semantics='open' ;; 8834f9b3eeSRoland Mainz bar) semantics='dup' ;; 8934f9b3eeSRoland Mainz *) semantics='failed' ;; 9034f9b3eeSRoland Mainz esac 9134f9b3eeSRoland Mainz [[ $semantics == @(${FDFS[fdfs].semantics}) ]] || err_exit "'4< ${FDFS[fdfs].dir}/3' $semantics semantics instead of ${FDFS[fdfs].semantics} -- expected '$exp', got '$got'" 92da2e3ebdSchinfi 9334f9b3eeSRoland Mainz 9434f9b3eeSRoland Mainz# 2004-11-25 ancient /dev/fd/N redirection bug fix 9534f9b3eeSRoland Mainzgot=$( 9634f9b3eeSRoland Mainz { 9734f9b3eeSRoland Mainz print -n 1 9834f9b3eeSRoland Mainz print -n 2 > ${FDFS[fdfs].dir}/2 9934f9b3eeSRoland Mainz print -n 3 10034f9b3eeSRoland Mainz print -n 4 > ${FDFS[fdfs].dir}/2 10134f9b3eeSRoland Mainz } 2>&1 10234f9b3eeSRoland Mainz) 10334f9b3eeSRoland Mainzexp='1234|4' 10434f9b3eeSRoland Mainzcase $got in 10534f9b3eeSRoland Mainz1234) semantics='dup' ;; 10634f9b3eeSRoland Mainz4) semantics='open' ;; 10734f9b3eeSRoland Mainz*) semantics='failed' ;; 10834f9b3eeSRoland Mainzesac 10934f9b3eeSRoland Mainz[[ $semantics == @(${FDFS[fdfs].semantics}) ]] || err_exit "${FDFS[fdfs].dir}/N $semantics semantics instead of ${FDFS[fdfs].semantics} -- expected '$exp', got '$got'" 11034f9b3eeSRoland Mainz 111da2e3ebdSchincat > close0 <<\! 112da2e3ebdSchinexec 0<&- 113da2e3ebdSchinecho $(./close1) 114da2e3ebdSchin! 115da2e3ebdSchinprint "echo abc" > close1 116da2e3ebdSchinchmod +x close0 close1 117da2e3ebdSchinx=$(./close0) 118da2e3ebdSchinif [[ $x != "abc" ]] 119da2e3ebdSchinthen err_exit "picked up file descriptor zero for opening script file" 120da2e3ebdSchinfi 121da2e3ebdSchincat > close0 <<\! 122da2e3ebdSchin for ((i=0; i < 1100; i++)) 123da2e3ebdSchin do exec 4< /dev/null 124da2e3ebdSchin read -u4 125da2e3ebdSchin done 126da2e3ebdSchin exit 0 127da2e3ebdSchin! 128da2e3ebdSchin./close0 2> /dev/null || err_exit "multiple exec 4< /dev/null can fail" 129da2e3ebdSchin$SHELL -c ' 13034f9b3eeSRoland Mainz trap "rm -f in out" EXIT 131da2e3ebdSchin for ((i = 0; i < 1000; i++)) 132da2e3ebdSchin do print -r -- "This is a test" 13334f9b3eeSRoland Mainz done > in 13434f9b3eeSRoland Mainz > out 13534f9b3eeSRoland Mainz exec 1<> out 136da2e3ebdSchin builtin cat 13734f9b3eeSRoland Mainz print -r -- "$(<in)" 13834f9b3eeSRoland Mainz cmp -s in out' 2> /dev/null 139da2e3ebdSchin[[ $? == 0 ]] || err_exit 'builtin cat truncates files' 140da2e3ebdSchincat >| script <<-\! 141da2e3ebdSchinprint hello 142da2e3ebdSchin( exec 3<&- 4<&-) 143da2e3ebdSchinexec 3<&- 4<&- 144da2e3ebdSchinprint world 145da2e3ebdSchin! 146da2e3ebdSchinchmod +x script 147da2e3ebdSchin[[ $( $SHELL ./script) == $'hello\nworld' ]] || err_exit 'closing 3 & 4 causes script to fail' 148da2e3ebdSchincd ~- || err_exit "cd back failed" 149da2e3ebdSchin( exec > '' ) 2> /dev/null && err_exit '> "" does not fail' 150da2e3ebdSchinunset x 151da2e3ebdSchin( exec > ${x} ) 2> /dev/null && err_exit '> $x, where x null does not fail' 152da2e3ebdSchinexec <<! 153da2e3ebdSchinfoo 154da2e3ebdSchinbar 155da2e3ebdSchin! 156da2e3ebdSchin( exec 0< /dev/null) 157da2e3ebdSchinread line 158da2e3ebdSchinif [[ $line != foo ]] 159da2e3ebdSchinthen err_exit 'file descriptor not restored after exec in subshell' 160da2e3ebdSchinfi 16134f9b3eeSRoland Mainzexec 3>&- 4>&- 162da2e3ebdSchin[[ $( { 163da2e3ebdSchin read -r line;print -r -- "$line" 164da2e3ebdSchin ( 165da2e3ebdSchin read -r line;print -r -- "$line" 166da2e3ebdSchin ) & wait 167da2e3ebdSchin while read -r line 168da2e3ebdSchin do print -r -- "$line" 169da2e3ebdSchin done 170da2e3ebdSchin } << ! 171da2e3ebdSchinline 1 172da2e3ebdSchinline 2 173da2e3ebdSchinline 3 174da2e3ebdSchin!) == $'line 1\nline 2\nline 3' ]] || err_exit 'read error with subshells' 175da2e3ebdSchin# 2004-05-11 bug fix 17634f9b3eeSRoland Mainzcat > $tmp/1 <<- ++EOF++ 17734f9b3eeSRoland Mainz script=$tmp/2 17834f9b3eeSRoland Mainz trap "rm -f \$script" EXIT 17934f9b3eeSRoland Mainz exec 9> \$script 180da2e3ebdSchin for ((i=3; i<9; i++)) 18134f9b3eeSRoland Mainz do eval "while read -u\$i; do : ;done \$i</dev/null" 18234f9b3eeSRoland Mainz print -u9 "exec \$i< /dev/null" 183da2e3ebdSchin done 184da2e3ebdSchin for ((i=0; i < 60; i++)) 185da2e3ebdSchin do print -u9 -f "%.80c\n" ' ' 186da2e3ebdSchin done 187da2e3ebdSchin print -u9 'print ok' 188da2e3ebdSchin exec 9<&- 18934f9b3eeSRoland Mainz chmod +x \$script 19034f9b3eeSRoland Mainz \$script 191da2e3ebdSchin++EOF++ 19234f9b3eeSRoland Mainzchmod +x $tmp/1 19334f9b3eeSRoland Mainz[[ $($SHELL $tmp/1) == ok ]] || err_exit "parent i/o causes child script to fail" 19434f9b3eeSRoland Mainz# 2004-12-20 redirection loss bug fix 19534f9b3eeSRoland Mainzcat > $tmp/1 <<- \++EOF++ 196da2e3ebdSchin function a 197da2e3ebdSchin { 198da2e3ebdSchin trap 'print ok' EXIT 199da2e3ebdSchin : > /dev/null 200da2e3ebdSchin } 201da2e3ebdSchin a 202da2e3ebdSchin++EOF++ 20334f9b3eeSRoland Mainzchmod +x $tmp/1 20434f9b3eeSRoland Mainz[[ $($tmp/1) == ok ]] || err_exit "trap on EXIT loses last command redirection" 20534f9b3eeSRoland Mainzprint > /dev/null {n}> $tmp/1 20634f9b3eeSRoland Mainz[[ ! -s $tmp/1 ]] && newio=1 207da2e3ebdSchinif [[ $newio && $(print hello | while read -u$n; do print $REPLY; done {n}<&0) != hello ]] 208da2e3ebdSchinthen err_exit "{n}<&0 not working with for loop" 209da2e3ebdSchinfi 210da2e3ebdSchin[[ $({ read -r;read -u3 3<&0; print -- "$REPLY" ;} <<! 211da2e3ebdSchinhello 212da2e3ebdSchinworld 213da2e3ebdSchin!) == world ]] || err_exit 'I/O not synchronized with <&' 214da2e3ebdSchinx="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNSPQRSTUVWXYZ1234567890" 215da2e3ebdSchinfor ((i=0; i < 62; i++)) 216da2e3ebdSchindo printf "%.39c\n" ${x:i:1} 21734f9b3eeSRoland Mainzdone > $tmp/seek 21834f9b3eeSRoland Mainzif command exec 3<> $tmp/seek 219da2e3ebdSchinthen (( $(3<#) == 0 )) || err_exit "not at position 0" 220da2e3ebdSchin (( $(3<# ((EOF))) == 40*62 )) || err_exit "not at end-of-file" 221da2e3ebdSchin command exec 3<# ((40*8)) || err_exit "absolute seek fails" 222da2e3ebdSchin read -u3 22334f9b3eeSRoland Mainz [[ $REPLY == +(i) ]] || err_exit "expected iiii..., got $REPLY" 224da2e3ebdSchin [[ $(3<#) == $(3<# ((CUR)) ) ]] || err_exit '$(3<#)!=$(3<#((CUR)))' 225da2e3ebdSchin command exec 3<# ((CUR+80)) 226da2e3ebdSchin read -u3 22734f9b3eeSRoland Mainz [[ $REPLY == {39}(l) ]] || err_exit "expected lll..., got $REPLY" 228da2e3ebdSchin command exec 3<# ((EOF-80)) 229da2e3ebdSchin read -u3 23034f9b3eeSRoland Mainz [[ $REPLY == +(9) ]] || err_exit "expected 999..., got $REPLY" 231da2e3ebdSchin command exec 3># ((80)) 232da2e3ebdSchin print -u3 -f "%.39c\n" @ 233da2e3ebdSchin command exec 3># ((80)) 234da2e3ebdSchin read -u3 23534f9b3eeSRoland Mainz [[ $REPLY == +(@) ]] || err_exit "expected @@@..., got $REPLY" 236da2e3ebdSchin read -u3 23734f9b3eeSRoland Mainz [[ $REPLY == +(d) ]] || err_exit "expected ddd..., got $REPLY" 238da2e3ebdSchin command exec 3># ((EOF)) 239da2e3ebdSchin print -u3 -f "%.39c\n" ^ 240da2e3ebdSchin (( $(3<# ((CUR-0))) == 40*63 )) || err_exit "not at extended end-of-file" 241da2e3ebdSchin command exec 3<# ((40*62)) 242da2e3ebdSchin read -u3 24334f9b3eeSRoland Mainz [[ $REPLY == +(^) ]] || err_exit "expected ddd..., got $REPLY" 244da2e3ebdSchin command exec 3<# ((0)) 245da2e3ebdSchin command exec 3<# *jjjj* 246da2e3ebdSchin read -u3 247da2e3ebdSchin [[ $REPLY == {39}(j) ]] || err_exit "<# pattern failed" 248da2e3ebdSchin [[ $(command exec 3<## *llll*) = {39}(k) ]] || err_exit "<## pattern not saving standard output" 249da2e3ebdSchin read -u3 250da2e3ebdSchin [[ $REPLY == {39}(l) ]] || err_exit "<## pattern failed to position" 251da2e3ebdSchin command exec 3<# *abc* 252da2e3ebdSchin read -u3 && err_exit "not found pattern not positioning at eof" 25334f9b3eeSRoland Mainz cat $tmp/seek | read -r <# *WWW* 254da2e3ebdSchin [[ $REPLY == *WWWWW* ]] || err_exit '<# not working for pipes' 25534f9b3eeSRoland Mainz { < $tmp/seek <# ((2358336120)) ;} 2> /dev/null || err_exit 'long seek not working' 25634f9b3eeSRoland Mainzelse err_exit "$tmp/seek: cannot open for reading" 257da2e3ebdSchinfi 2587c2fbfb3SApril Chincommand exec 3<&- || 'cannot close 3' 2597c2fbfb3SApril Chinfor ((i=0; i < 62; i++)) 2607c2fbfb3SApril Chindo printf "%.39c\n" ${x:i:1} 26134f9b3eeSRoland Mainzdone > $tmp/seek 26234f9b3eeSRoland Mainzif command exec {n}<> $tmp/seek 2637c2fbfb3SApril Chinthen { command exec {n}<#((EOF)) ;} 2> /dev/null || err_exit '{n}<# not working' 2647c2fbfb3SApril Chin if $SHELL -c '{n}</dev/null' 2> /dev/null 2657c2fbfb3SApril Chin then (( $({n}<#) == 40*62)) || err_exit '$({n}<#) not working' 2667c2fbfb3SApril Chin else err_exit 'not able to parse {n}</dev/null' 2677c2fbfb3SApril Chin fi 2687c2fbfb3SApril Chinfi 269da2e3ebdSchin$SHELL -ic ' 270da2e3ebdSchin{ 271da2e3ebdSchin print -u2 || exit 2 272da2e3ebdSchin print -u3 || exit 3 273da2e3ebdSchin print -u4 || exit 4 274da2e3ebdSchin print -u5 || exit 5 275da2e3ebdSchin print -u6 || exit 6 276da2e3ebdSchin print -u7 || exit 7 277da2e3ebdSchin print -u8 || exit 8 278da2e3ebdSchin print -u9 || exit 9 279da2e3ebdSchin} 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 280da2e3ebdSchinexitval=$? 281da2e3ebdSchin(( exitval )) && err_exit "print to unit $exitval failed" 28234f9b3eeSRoland Mainz$SHELL -c "{ > $tmp/1 ; date;} >&- 2> /dev/null" > $tmp/2 28334f9b3eeSRoland Mainz[[ -s $tmp/1 || -s $tmp/2 ]] && err_exit 'commands with standard output closed produce output' 284da2e3ebdSchin$SHELL -c "$SHELL -c ': 3>&1' 1>&- 2>/dev/null" && err_exit 'closed standard output not passed to subshell' 2857c2fbfb3SApril Chin[[ $(cat <<- \EOF | $SHELL 2867c2fbfb3SApril Chin do_it_all() 2877c2fbfb3SApril Chin { 2887c2fbfb3SApril Chin dd 2>/dev/null # not a ksh93 buildin 2897c2fbfb3SApril Chin return $? 2907c2fbfb3SApril Chin } 2917c2fbfb3SApril Chin do_it_all ; exit $? 2927c2fbfb3SApril Chin hello world 2937c2fbfb3SApril ChinEOF) == 'hello world' ]] || err_exit 'invalid readahead on stdin' 2947c2fbfb3SApril Chin$SHELL -c 'exec 3>; /dev/null' 2> /dev/null && err_exit '>; with exec should be an error' 2957c2fbfb3SApril Chin$SHELL -c ': 3>; /dev/null' 2> /dev/null || err_exit '>; not working with at all' 29634f9b3eeSRoland Mainzprint hello > $tmp/1 29734f9b3eeSRoland Mainzif ! $SHELL -c "false >; $tmp/1" 2> /dev/null 29834f9b3eeSRoland Mainzthen [[ $(<$tmp/1) == hello ]] || err_exit '>; not preserving file on failure' 2997c2fbfb3SApril Chinfi 30034f9b3eeSRoland Mainzif ! $SHELL -c "sed -e 's/hello/hello world/' $tmp/1" >; $tmp/1 2> /dev/null 30134f9b3eeSRoland Mainzthen [[ $(<$tmp/1) == 'hello world' ]] || err_exit '>; not updating file on success' 30234f9b3eeSRoland Mainzfi 30334f9b3eeSRoland Mainz 30434f9b3eeSRoland Mainz$SHELL -c 'exec 3<>; /dev/null' 2> /dev/null && err_exit '<>; with exec should be an error' 30534f9b3eeSRoland Mainz$SHELL -c ': 3<>; /dev/null' 2> /dev/null || err_exit '<>; not working with at all' 30634f9b3eeSRoland Mainzprint $'hello\nworld' > $tmp/1 30734f9b3eeSRoland Mainzif ! $SHELL -c "false <>; $tmp/1" 2> /dev/null 30834f9b3eeSRoland Mainzthen [[ $(<$tmp/1) == $'hello\nworld' ]] || err_exit '<>; not preserving file on failure' 30934f9b3eeSRoland Mainzfi 31034f9b3eeSRoland Mainzif ! $SHELL -c "head -1 $tmp/1" <>; $tmp/1 2> /dev/null 31134f9b3eeSRoland Mainzthen [[ $(<$tmp/1) == hello ]] || err_exit '<>; not truncating file on success of head' 31234f9b3eeSRoland Mainzfi 31334f9b3eeSRoland Mainzprint $'hello\nworld' > $tmp/1 31434f9b3eeSRoland Mainzif ! $SHELL -c head < $tmp/1 <#((6)) <>; $tmp/1 2> /dev/null 31534f9b3eeSRoland Mainzthen [[ $(<$tmp/1) == world ]] || err_exit '<>; not truncating file on success of behead' 3167c2fbfb3SApril Chinfi 3177c2fbfb3SApril Chin 3187c2fbfb3SApril Chinunset y 3197c2fbfb3SApril Chinread -n1 y <<! 3207c2fbfb3SApril Chinabc 3217c2fbfb3SApril Chin! 3227c2fbfb3SApril Chinif [[ $y != a ]] 3237c2fbfb3SApril Chinthen err_exit 'read -n1 not working' 3247c2fbfb3SApril Chinfi 3257c2fbfb3SApril Chinunset a 3267c2fbfb3SApril Chin{ read -N3 a; read -N1 b;} <<! 3277c2fbfb3SApril Chinabcdefg 3287c2fbfb3SApril Chin! 3297c2fbfb3SApril Chin[[ $a == abc ]] || err_exit 'read -N3 here-document not working' 3307c2fbfb3SApril Chin[[ $b == d ]] || err_exit 'read -N1 here-document not working' 3317c2fbfb3SApril Chinread -n3 a <<! 3327c2fbfb3SApril Chinabcdefg 3337c2fbfb3SApril Chin! 3347c2fbfb3SApril Chin[[ $a == abc ]] || err_exit 'read -n3 here-document not working' 3357c2fbfb3SApril Chin(print -n a;sleep 1; print -n bcde) | { read -N3 a; read -N1 b;} 3367c2fbfb3SApril Chin[[ $a == abc ]] || err_exit 'read -N3 from pipe not working' 3377c2fbfb3SApril Chin[[ $b == d ]] || err_exit 'read -N1 from pipe not working' 3387c2fbfb3SApril Chin(print -n a;sleep 1; print -n bcde) |read -n3 a 3397c2fbfb3SApril Chin[[ $a == a ]] || err_exit 'read -n3 from pipe not working' 34034f9b3eeSRoland Mainzif mkfifo $tmp/fifo 2> /dev/null 34134f9b3eeSRoland Mainzthen (print -n a; sleep 1;print -n bcde) > $tmp/fifo & 3427c2fbfb3SApril Chin { 3437c2fbfb3SApril Chin read -u5 -n3 -t2 a || err_exit 'read -n3 from fifo timedout' 3447c2fbfb3SApril Chin read -u5 -n1 -t2 b || err_exit 'read -n1 from fifo timedout' 34534f9b3eeSRoland Mainz } 5< $tmp/fifo 3467c2fbfb3SApril Chin [[ $a == a ]] || err_exit 'read -n3 from fifo not working' 34734f9b3eeSRoland Mainz rm -f $tmp/fifo 34834f9b3eeSRoland Mainz mkfifo $tmp/fifo 2> /dev/null 34934f9b3eeSRoland Mainz (print -n a; sleep 1;print -n bcde) > $tmp/fifo & 3507c2fbfb3SApril Chin { 3517c2fbfb3SApril Chin read -u5 -N3 -t2 a || err_exit 'read -N3 from fifo timed out' 3527c2fbfb3SApril Chin read -u5 -N1 -t2 b || err_exit 'read -N1 from fifo timedout' 35334f9b3eeSRoland Mainz } 5< $tmp/fifo 3547c2fbfb3SApril Chin [[ $a == abc ]] || err_exit 'read -N3 from fifo not working' 3557c2fbfb3SApril Chin [[ $b == d ]] || err_exit 'read -N1 from fifo not working' 3567c2fbfb3SApril Chinfi 35734f9b3eeSRoland Mainz( 35834f9b3eeSRoland Mainz print -n 'prompt1: ' 35934f9b3eeSRoland Mainz sleep .1 36034f9b3eeSRoland Mainz print line2 36134f9b3eeSRoland Mainz sleep .1 36234f9b3eeSRoland Mainz print -n 'prompt2: ' 36334f9b3eeSRoland Mainz sleep .1 36434f9b3eeSRoland Mainz) | { 36534f9b3eeSRoland Mainz read -t2 -n 1000 line1 36634f9b3eeSRoland Mainz read -t2 -n 1000 line2 36734f9b3eeSRoland Mainz read -t2 -n 1000 line3 36834f9b3eeSRoland Mainz read -t2 -n 1000 line4 36934f9b3eeSRoland Mainz} 370*3e14f97fSRoger A. Faulkner[[ $? == 0 ]] && err_exit 'should have timed out' 37134f9b3eeSRoland Mainz[[ $line1 == 'prompt1: ' ]] || err_exit "line1 should be 'prompt1: '" 37234f9b3eeSRoland Mainz[[ $line2 == line2 ]] || err_exit "line2 should be line2" 37334f9b3eeSRoland Mainz[[ $line3 == 'prompt2: ' ]] || err_exit "line3 should be 'prompt2: '" 37434f9b3eeSRoland Mainz[[ ! $line4 ]] || err_exit "line4 should be empty" 3757c2fbfb3SApril Chin 3767c2fbfb3SApril Chinif $SHELL -c "export LC_ALL=en_US.UTF-8; c=$'\342\202\254'; [[ \${#c} == 1 ]]" 2>/dev/null 3777c2fbfb3SApril Chinthen lc_utf8=en_US.UTF-8 3787c2fbfb3SApril Chinelse lc_utf8='' 3797c2fbfb3SApril Chinfi 3807c2fbfb3SApril Chin 3817c2fbfb3SApril Chintypeset -a e o=(-n2 -N2) 3827c2fbfb3SApril Chininteger i 3837c2fbfb3SApril Chinset -- \ 3847c2fbfb3SApril Chin 'a' 'bcd' 'a bcd' 'ab cd' \ 3857c2fbfb3SApril Chin 'ab' 'cd' 'ab cd' 'ab cd' \ 3867c2fbfb3SApril Chin 'abc' 'd' 'ab cd' 'ab cd' \ 3877c2fbfb3SApril Chin 'abcd' '' 'ab cd' 'ab cd' 3887c2fbfb3SApril Chinwhile (( $# >= 3 )) 3897c2fbfb3SApril Chindo a=$1 3907c2fbfb3SApril Chin b=$2 3917c2fbfb3SApril Chin e[0]=$3 3927c2fbfb3SApril Chin e[1]=$4 3937c2fbfb3SApril Chin shift 4 3947c2fbfb3SApril Chin for ((i = 0; i < 2; i++)) 3957c2fbfb3SApril Chin do for lc_all in C $lc_utf8 3967c2fbfb3SApril Chin 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; }") 3977c2fbfb3SApril Chin [[ $g == "${e[i]}" ]] || err_exit "LC_ALL=$lc_all read ${o[i]} from pipe '$a $b' failed -- expected '${e[i]}', got '$g'" 3987c2fbfb3SApril Chin done 3997c2fbfb3SApril Chin done 4007c2fbfb3SApril Chindone 4017c2fbfb3SApril Chin 4027c2fbfb3SApril Chinif [[ $lc_utf8 ]] 4037c2fbfb3SApril Chinthen export LC_ALL=en_US.UTF-8 4047c2fbfb3SApril Chin typeset -a c=( '' 'A' $'\303\274' $'\342\202\254' ) 4057c2fbfb3SApril Chin integer i w 4067c2fbfb3SApril Chin typeset o 4077c2fbfb3SApril Chin if (( ${#c[2]} == 1 && ${#c[3]} == 1 )) 4087c2fbfb3SApril Chin then for i in 1 2 3 4097c2fbfb3SApril Chin do for o in n N 4107c2fbfb3SApril Chin do for w in 1 2 3 4117c2fbfb3SApril Chin do print -nr "${c[w]}" | read -${o}${i} g 4127c2fbfb3SApril Chin if [[ $o == N ]] && (( i > 1 )) 4137c2fbfb3SApril Chin then e='' 4147c2fbfb3SApril Chin else e=${c[w]} 4157c2fbfb3SApril Chin fi 4167c2fbfb3SApril Chin [[ $g == "$e" ]] || err_exit "read -${o}${i} failed for '${c[w]}' -- expected '$e', got '$g'" 4177c2fbfb3SApril Chin done 4187c2fbfb3SApril Chin done 4197c2fbfb3SApril Chin done 4207c2fbfb3SApril Chin fi 4217c2fbfb3SApril Chinfi 4227c2fbfb3SApril Chin 42334f9b3eeSRoland Mainzexec 3<&2 42434f9b3eeSRoland Mainzfile=$tmp/file 42534f9b3eeSRoland Mainzredirect 5>$file 2>&5 42634f9b3eeSRoland Mainzprint -u5 -f 'This is a test\n' 42734f9b3eeSRoland Mainzprint -u2 OK 42834f9b3eeSRoland Mainzexec 2<&3 42934f9b3eeSRoland Mainzexp=$'This is a test\nOK' 43034f9b3eeSRoland Mainzgot=$(< $file) 43134f9b3eeSRoland Mainz[[ $got == $exp ]] || err_exit "output garbled when stderr is duped -- expected $(printf %q "$exp"), got $(printf %q "$got")" 43234f9b3eeSRoland Mainzprint 'hello world' > $file 43334f9b3eeSRoland Mainz1<>; $file 1># ((5)) 43434f9b3eeSRoland Mainz(( $(wc -c < $file) == 5 )) || err_exit "$file was not truncate to 5 bytes" 43534f9b3eeSRoland Mainz 43634f9b3eeSRoland Mainz$SHELL -c "PS4=':2:' 43734f9b3eeSRoland Mainz exec 1> $tmp/21.out 2> $tmp/22.out 43834f9b3eeSRoland Mainz set -x 43934f9b3eeSRoland Mainz printf ':1:A:' 44034f9b3eeSRoland Mainz print \$(:) 44134f9b3eeSRoland Mainz print :1:Z:" 1> $tmp/11.out 2> $tmp/12.out 44234f9b3eeSRoland Mainz[[ -s $tmp/11.out ]] && err_exit "standard output leaked past redirection" 44334f9b3eeSRoland Mainz[[ -s $tmp/12.out ]] && err_exit "standard error leaked past redirection" 44434f9b3eeSRoland Mainzexp=$':1:A:\n:1:Z:' 44534f9b3eeSRoland Mainzgot=$(<$tmp/21.out) 44634f9b3eeSRoland Mainz[[ $exp == "$got" ]] || err_exit "standard output garbled -- expected $(printf %q "$exp"), got $(printf %q "$got")" 44734f9b3eeSRoland Mainzexp=$':2:printf :1:A:\n:2::\n:2:print\n:2:print :1:Z:' 44834f9b3eeSRoland Mainzgot=$(<$tmp/22.out) 44934f9b3eeSRoland Mainz[[ $exp == "$got" ]] || err_exit "standard error garbled -- expected $(printf %q "$exp"), got $(printf %q "$got")" 45034f9b3eeSRoland Mainz 451da2e3ebdSchinexit $((Errors)) 452