1######################################################################## 2# # 3# This software is part of the ast package # 4# Copyright (c) 1982-2010 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######################################################################## 20# test the behavior of co-processes 21function err_exit 22{ 23 print -u2 -n "\t" 24 print -u2 -r ${Command}[$1]: "${@:2}" 25 let Errors+=1 26} 27alias err_exit='err_exit $LINENO' 28 29Command=${0##*/} 30integer Errors=0 31 32tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 33trap "cd /; rm -rf $tmp" EXIT 34 35if [[ -d /cygdrive ]] 36then err_exit cygwin detected - coprocess tests disabled - enable at the risk of wedging your system 37 exit $((Errors)) 38fi 39 40function ping # id 41{ 42 integer x=0 43 while ((x++ < 5)) 44 do read -r 45 print -r "$1 $REPLY" 46 done 47} 48 49cat |& 50print -p "hello" 51read -p line 52[[ $line == hello ]] || err_exit 'coprocessing fails' 53exec 5>&p 6<&p 54print -u5 'hello again' || err_exit 'write on u5 fails' 55read -u6 line 56[[ $line == 'hello again' ]] || err_exit 'coprocess after moving fds fails' 57exec 5<&- 6<&- 58wait $! 59 60ping three |& 61exec 3>&p 62ping four |& 63exec 4>&p 64ping pipe |& 65 66integer count 67for i in three four pipe four pipe four three pipe pipe three pipe 68do case $i in 69 three) to=-u3;; 70 four) to=-u4;; 71 pipe) to=-p;; 72 esac 73 (( count++ )) 74 print $to $i $count 75done 76 77while ((count > 0)) 78do (( count-- )) 79 read -p 80 set -- $REPLY 81 if [[ $1 != $2 ]] 82 then err_exit "$1 does not match $2" 83 fi 84 case $1 in 85 three) ;; 86 four) ;; 87 pipe) ;; 88 *) err_exit "unknown message +|$REPLY|+" ;; 89 esac 90done 91kill $(jobs -p) 2>/dev/null 92 93file=$tmp/regress 94cat > $file <<\! 95/bin/cat |& 96! 97chmod +x $file 98sleep 10 |& 99$file 2> /dev/null || err_exit "parent coprocess prevents script coprocess" 100exec 5<&p 6>&p 101exec 5<&- 6>&- 102kill $(jobs -p) 2>/dev/null 103 104${SHELL-ksh} |& 105cop=$! 106exp=Done 107print -p $'print hello | cat\nprint '$exp 108read -t 5 -p 109read -t 5 -p 110got=$REPLY 111if [[ $got != $exp ]] 112then err_exit "${SHELL-ksh} coprocess io failed -- got '$got', expected '$exp'" 113fi 114exec 5<&p 6>&p 115exec 5<&- 6>&- 116{ sleep 4; kill $cop; } 2>/dev/null & 117spy=$! 118if wait $cop 2>/dev/null 119then kill $spy 2>/dev/null 120else err_exit "coprocess hung after 'exec 5<&p 6>&p; exec 5<&- 6>&-'" 121fi 122wait 123 124{ 125echo line1 | grep 'line2' 126echo line2 | grep 'line1' 127} |& 128SECONDS=0 count=0 129while read -p -t 10 line 130do ((count++)) 131done 132if (( SECONDS > 8 )) 133then err_exit "read -p hanging (SECONDS=$SECONDS count=$count)" 134fi 135wait $! 136 137( sleep 3 |& sleep 1 && kill $!; sleep 1; sleep 3 |& sleep 1 && kill $! ) || 138 err_exit "coprocess cleanup not working correctly" 139{ : |& } 2>/dev/null || 140 err_exit "subshell coprocess lingers in parent" 141wait $! 142 143unset N r e 144integer N=5 145e=12345 146( 147 integer i 148 for ((i = 1; i <= N; i++)) 149 do print $i |& 150 read -p r 151 print -n $r 152 wait $! 153 done 154 print 155) 2>/dev/null | read -t 10 r 156[[ $r == $e ]] || err_exit "coprocess timing bug -- expected $e, got '$r'" 157r= 158( 159 integer i 160 for ((i = 1; i <= N; i++)) 161 do print $i |& 162 sleep 0.01 163 r=$r$(cat <&p) 164 wait $! 165 done 166 print $r 167) 2>/dev/null | read -t 10 r 168[[ $r == $e ]] || err_exit "coprocess command substitution bug -- expected $e, got '$r'" 169 170( 171 /bin/cat |& 172 sleep 0.01 173 exec 6>&p 174 print -u6 ok 175 exec 6>&- 176 sleep 1 177 kill $! 2> /dev/null 178) && err_exit 'coprocess with subshell would hang' 179for sig in IOT ABRT 180do if ( trap - $sig ) 2> /dev/null 181 then if [[ $( { sig=$sig $SHELL 2> /dev/null <<- '++EOF++' 182 cat |& 183 pid=$! 184 trap "print TRAP" $sig 185 ( 186 sleep 2 187 kill -$sig $$ 188 sleep 2 189 kill -$sig $$ 190 kill $pid 191 sleep 2 192 kill $$ 193 ) & 194 read -p 195 ++EOF++ 196 } ) != $'TRAP\nTRAP' ]] 2> /dev/null 197 then err_exit 'traps when reading from coprocess not working' 198 fi 199 break 200 fi 201done 202 203trap 'sleep_pid=; kill $pid; err_exit "coprocess 1 hung"' TERM 204{ sleep 5; kill $$; } & 205sleep_pid=$! 206builtin cat 207cat |& 208pid=$! 209exec 5<&p 6>&p 210print -u6 hi; read -u5 211[[ $REPLY == hi ]] || err_exit 'REPLY is $REPLY not hi' 212exec 6>&- 213wait $pid 214trap - TERM 215[[ $sleep_pid ]] && kill $sleep_pid 216 217trap 'sleep_pid=; kill $pid; err_exit "coprocess 2 hung"' TERM 218{ sleep 5; kill $$; } & 219sleep_pid=$! 220cat |& 221pid=$! 222print foo >&p 2> /dev/null || err_exit 'first write of foo to coprocess failed' 223print foo >&p 2> /dev/null || err_exit 'second write of foo to coprocess failed' 224kill $pid 225wait $pid 2> /dev/null 226trap - TERM 227[[ $sleep_pid ]] && kill $sleep_pid 228 229trap 'sleep_pid=; kill $pid; err_exit "coprocess 3 hung"' TERM 230{ sleep 5; kill $$; } & 231sleep_pid=$! 232cat |& 233pid=$! 234print -p foo 235print -p bar 236read <&p || err_exit 'first read from coprocess failed' 237[[ $REPLY == foo ]] || err_exit "first REPLY is $REPLY not foo" 238read <&p || err_exit 'second read from coprocess failed' 239[[ $REPLY == bar ]] || err_exit "second REPLY is $REPLY not bar" 240kill $pid 241wait $pid 2> /dev/null 242trap - TERM 243[[ $sleep_pid ]] && kill $sleep_pid 244 245exp=ksh 246got=$(print -r $'#00315 247COATTRIBUTES=\'label=make \' 248# @(#)$Id: libcoshell (AT&T Research) 2008-04-28 $ 249_COSHELL_msgfd=5 250{ { (eval \'function fun { trap \":\" 0; return 1; }; trap \"exit 0\" 0; fun; exit 1\') && PATH= print -u$_COSHELL_msgfd ksh; } || { times && echo bsh >&$_COSHELL_msgfd; } || { echo osh >&$_COSHELL_msgfd; }; } >/dev/null 2>&1' | $SHELL 5>&1) 251[[ $got == $exp ]] || err_exit "coshell(3) identification sequence failed -- expected '$exp', got '$got'" 252 253function cop 254{ 255 read 256 print ok 257} 258 259exp=ok 260 261cop |& 262pid=$! 263if print -p yo 2>/dev/null 264then read -p got 265else got='no coprocess' 266fi 267[[ $got == $exp ]] || err_exit "main coprocess main query failed -- expected $exp, got '$got'" 268kill $pid 2>/dev/null 269wait 270 271cop |& 272pid=$! 273( 274if print -p yo 2>/dev/null 275then read -p got 276else got='no coprocess' 277fi 278[[ $got == $exp ]] || err_exit "main coprocess subshell query failed -- expected $exp, got '$got'" 279) 280kill $pid 2>/dev/null 281wait 282 283exp='no coprocess' 284 285( 286cop |& 287print $! > $tmp/pid 288) 289pid=$(<$tmp/pid) 290if print -p yo 2>/dev/null 291then read -p got 292else got=$exp 293fi 294[[ $got == $exp ]] || err_exit "subshell coprocess main query failed -- expected $exp, got '$got'" 295kill $pid 2>/dev/null 296wait 297 298( 299cop |& 300print $! > $tmp/pid 301) 302pid=$(<$tmp/pid) 303( 304if print -p yo 2>/dev/null 305then read -p got 306else got=$exp 307fi 308[[ $got == $exp ]] || err_exit "subshell coprocess subshell query failed -- expected $exp, got '$got'" 309kill $pid 2>/dev/null 310wait 311) 312 313exit $((Errors)) 314