18462SApril.Chin@Sun.COM######################################################################## 28462SApril.Chin@Sun.COM# # 38462SApril.Chin@Sun.COM# This software is part of the ast package # 4*10898Sroland.mainz@nrubsig.org# Copyright (c) 1982-2009 AT&T Intellectual Property # 58462SApril.Chin@Sun.COM# and is licensed under the # 68462SApril.Chin@Sun.COM# Common Public License, Version 1.0 # 78462SApril.Chin@Sun.COM# by AT&T Intellectual Property # 88462SApril.Chin@Sun.COM# # 98462SApril.Chin@Sun.COM# A copy of the License is available at # 108462SApril.Chin@Sun.COM# http://www.opensource.org/licenses/cpl1.0.txt # 118462SApril.Chin@Sun.COM# (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) # 128462SApril.Chin@Sun.COM# # 138462SApril.Chin@Sun.COM# Information and Software Systems Research # 148462SApril.Chin@Sun.COM# AT&T Research # 158462SApril.Chin@Sun.COM# Florham Park NJ # 168462SApril.Chin@Sun.COM# # 178462SApril.Chin@Sun.COM# David Korn <dgk@research.att.com> # 188462SApril.Chin@Sun.COM# # 198462SApril.Chin@Sun.COM######################################################################## 208462SApril.Chin@Sun.COMfunction err_exit 218462SApril.Chin@Sun.COM{ 228462SApril.Chin@Sun.COM print -u2 -n "\t" 238462SApril.Chin@Sun.COM print -u2 -r ${Command}[$1]: "${@:2}" 248462SApril.Chin@Sun.COM (( Errors++ )) 258462SApril.Chin@Sun.COM} 268462SApril.Chin@Sun.COMalias err_exit='err_exit $LINENO' 278462SApril.Chin@Sun.COM 288462SApril.Chin@Sun.COMCommand=${0##*/} 298462SApril.Chin@Sun.COMinteger Errors=0 308462SApril.Chin@Sun.COM 31*10898Sroland.mainz@nrubsig.orgtmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 32*10898Sroland.mainz@nrubsig.orgtrap "cd /; rm -rf $tmp" EXIT 33*10898Sroland.mainz@nrubsig.org 34*10898Sroland.mainz@nrubsig.orgcd $tmp || err_exit "cd $tmp failed" 35*10898Sroland.mainz@nrubsig.org 36*10898Sroland.mainz@nrubsig.org( 37*10898Sroland.mainz@nrubsig.org set --pipefail 38*10898Sroland.mainz@nrubsig.org { 39*10898Sroland.mainz@nrubsig.org $SHELL 2> out2 <<- \EOF 40*10898Sroland.mainz@nrubsig.org g=false 41*10898Sroland.mainz@nrubsig.org trap 'print -u2 PIPED; $g && exit 0;g=true' PIPE 42*10898Sroland.mainz@nrubsig.org while : 43*10898Sroland.mainz@nrubsig.org do print hello 44*10898Sroland.mainz@nrubsig.org done 45*10898Sroland.mainz@nrubsig.org EOF 46*10898Sroland.mainz@nrubsig.org } | head > /dev/null 47*10898Sroland.mainz@nrubsig.org (( $? == 0)) || err_exit "SIGPIPE with wrong error code $?" 48*10898Sroland.mainz@nrubsig.org [[ $(<out2) == $'PIPED\nPIPED' ]] || err_exit 'SIGPIPE output on standard error is not correct' 49*10898Sroland.mainz@nrubsig.org) & 50*10898Sroland.mainz@nrubsig.orgcop=$! 51*10898Sroland.mainz@nrubsig.org{ sleep 4; kill $cop; } 2>/dev/null & 52*10898Sroland.mainz@nrubsig.orgspy=$! 53*10898Sroland.mainz@nrubsig.orgif wait $cop 2>/dev/null 54*10898Sroland.mainz@nrubsig.orgthen kill $spy 2>/dev/null 55*10898Sroland.mainz@nrubsig.orgelse err_exit "pipe with --pipefail PIPE trap hangs" 56*10898Sroland.mainz@nrubsig.orgfi 57*10898Sroland.mainz@nrubsig.orgwait 58*10898Sroland.mainz@nrubsig.orgrm -f out2 598462SApril.Chin@Sun.COM 608462SApril.Chin@Sun.COM[[ $( trap 'print -n got_child' SIGCHLD 618462SApril.Chin@Sun.COM sleep 2 & 628462SApril.Chin@Sun.COM for ((i=0; i < 4; i++)) 63*10898Sroland.mainz@nrubsig.org do sleep .75 648462SApril.Chin@Sun.COM print -n $i 658462SApril.Chin@Sun.COM done) == 01got_child23 ]] || err_exit 'SIGCHLD not working' 668462SApril.Chin@Sun.COM 678462SApril.Chin@Sun.COM# begin standalone SIGINT test generation 688462SApril.Chin@Sun.COM 698462SApril.Chin@Sun.COMcat > tst <<'!' 708462SApril.Chin@Sun.COM# shell trap tests 718462SApril.Chin@Sun.COM# 728462SApril.Chin@Sun.COM# tst control script that calls tst-1, must be run by ksh 738462SApril.Chin@Sun.COM# tst-1 calls tst-2 748462SApril.Chin@Sun.COM# tst-2 calls tst-3 758462SApril.Chin@Sun.COM# tst-3 defaults or handles and discards/propagates SIGINT 768462SApril.Chin@Sun.COM# 778462SApril.Chin@Sun.COM# initial -v option lists script entry and SIGINT delivery 788462SApril.Chin@Sun.COM# 798462SApril.Chin@Sun.COM# three test options 808462SApril.Chin@Sun.COM# 818462SApril.Chin@Sun.COM# d call next script directly, otherwise via $SHELL -c 828462SApril.Chin@Sun.COM# t trap, echo, and kill self on SIGINT, otherwise x or SIGINT default if no x 83*10898Sroland.mainz@nrubsig.org# x trap, echo on SIGINT, and tst-3 exit 0, tst-2 exit, otherwise SIGINT default 84*10898Sroland.mainz@nrubsig.org# z trap, echo on SIGINT, and tst-3 exit 0, tst-2 exit 0, otherwise SIGINT default 858462SApril.Chin@Sun.COM# 868462SApril.Chin@Sun.COM# Usage: tst [-v] [-options] shell-to-test ... 878462SApril.Chin@Sun.COM 888462SApril.Chin@Sun.COM# "trap + sig" is an unadvertized extension for this test 898462SApril.Chin@Sun.COM# if run from nmake SIGINT is set to SIG_IGN 908462SApril.Chin@Sun.COM# this call sets it back to SIG_DFL 918462SApril.Chin@Sun.COM# semantics w.r.t. function scope must be worked out before 928462SApril.Chin@Sun.COM# making it public 938462SApril.Chin@Sun.COMtrap + INT 948462SApril.Chin@Sun.COM 958462SApril.Chin@Sun.COMset -o monitor 968462SApril.Chin@Sun.COM 978462SApril.Chin@Sun.COMfunction gen 988462SApril.Chin@Sun.COM{ 998462SApril.Chin@Sun.COM typeset o t x d 100*10898Sroland.mainz@nrubsig.org for x in - x z 1018462SApril.Chin@Sun.COM do case $x in 1028462SApril.Chin@Sun.COM [$1]) for t in - t 1038462SApril.Chin@Sun.COM do case $t in 1048462SApril.Chin@Sun.COM [$1]) for d in - d 1058462SApril.Chin@Sun.COM do case $d in 1068462SApril.Chin@Sun.COM [$1]) o="$o $x$t$d" 1078462SApril.Chin@Sun.COM esac 1088462SApril.Chin@Sun.COM done 1098462SApril.Chin@Sun.COM esac 1108462SApril.Chin@Sun.COM done 1118462SApril.Chin@Sun.COM esac 1128462SApril.Chin@Sun.COM done 1138462SApril.Chin@Sun.COM echo '' $o 1148462SApril.Chin@Sun.COM} 1158462SApril.Chin@Sun.COM 1168462SApril.Chin@Sun.COMcase $1 in 1178462SApril.Chin@Sun.COM-v) v=v; shift ;; 1188462SApril.Chin@Sun.COM-*v*) v=v ;; 1198462SApril.Chin@Sun.COM*) v= ;; 1208462SApril.Chin@Sun.COMesac 1218462SApril.Chin@Sun.COMcase $1 in 1228462SApril.Chin@Sun.COM*' '*) o=$1; shift ;; 1238462SApril.Chin@Sun.COM-*) o=$(gen $1); shift ;; 1248462SApril.Chin@Sun.COM*) o=$(gen -txd) ;; 1258462SApril.Chin@Sun.COMesac 1268462SApril.Chin@Sun.COMcase $# in 1278462SApril.Chin@Sun.COM0) set ksh bash ksh88 pdksh ash zsh ;; 1288462SApril.Chin@Sun.COMesac 1298462SApril.Chin@Sun.COMfor f in $o 1308462SApril.Chin@Sun.COMdo case $# in 1318462SApril.Chin@Sun.COM 1) ;; 1328462SApril.Chin@Sun.COM *) echo ;; 1338462SApril.Chin@Sun.COM esac 1348462SApril.Chin@Sun.COM for sh 1358462SApril.Chin@Sun.COM do if $sh -c 'exit 0' > /dev/null 2>&1 1368462SApril.Chin@Sun.COM then case $# in 1378462SApril.Chin@Sun.COM 1) printf '%3s ' "$f" ;; 1388462SApril.Chin@Sun.COM *) printf '%16s %3s ' "$sh" "$f" ;; 1398462SApril.Chin@Sun.COM esac 1408462SApril.Chin@Sun.COM $sh tst-1 $v$f $sh > tst.out & 1418462SApril.Chin@Sun.COM wait 1428462SApril.Chin@Sun.COM echo $(cat tst.out) 1438462SApril.Chin@Sun.COM fi 1448462SApril.Chin@Sun.COM done 1458462SApril.Chin@Sun.COMdone 1468462SApril.Chin@Sun.COMcase $# in 1478462SApril.Chin@Sun.COM1) ;; 1488462SApril.Chin@Sun.COM*) echo ;; 1498462SApril.Chin@Sun.COMesac 1508462SApril.Chin@Sun.COM! 1518462SApril.Chin@Sun.COMcat > tst-1 <<'!' 1528462SApril.Chin@Sun.COMexec 2>/dev/null 1538462SApril.Chin@Sun.COMcase $1 in 1548462SApril.Chin@Sun.COM*v*) echo 1-main ;; 1558462SApril.Chin@Sun.COMesac 1568462SApril.Chin@Sun.COM{ 1578462SApril.Chin@Sun.COM sleep 2 1588462SApril.Chin@Sun.COM case $1 in 1598462SApril.Chin@Sun.COM *v*) echo "SIGINT" ;; 1608462SApril.Chin@Sun.COM esac 1618462SApril.Chin@Sun.COM kill -s INT 0 1628462SApril.Chin@Sun.COM} & 1638462SApril.Chin@Sun.COMcase $1 in 1648462SApril.Chin@Sun.COM*t*) trap ' 1658462SApril.Chin@Sun.COM echo 1-intr 1668462SApril.Chin@Sun.COM trap - INT 1678462SApril.Chin@Sun.COM # omitting the self kill exposes shells that deliver 1688462SApril.Chin@Sun.COM # the SIGINT trap but exit 0 for -xt 1698462SApril.Chin@Sun.COM # kill -s INT $$ 1708462SApril.Chin@Sun.COM ' INT 1718462SApril.Chin@Sun.COM ;; 1728462SApril.Chin@Sun.COMesac 1738462SApril.Chin@Sun.COMcase $1 in 1748462SApril.Chin@Sun.COM*d*) tst-2 $1 $2; status=$? ;; 1758462SApril.Chin@Sun.COM*) $2 -c "tst-2 $1 $2"; status=$? ;; 1768462SApril.Chin@Sun.COMesac 1778462SApril.Chin@Sun.COMprintf '1-%04d\n' $status 1788462SApril.Chin@Sun.COMsleep 2 1798462SApril.Chin@Sun.COM! 1808462SApril.Chin@Sun.COMcat > tst-2 <<'!' 1818462SApril.Chin@Sun.COMcase $1 in 182*10898Sroland.mainz@nrubsig.org*z*) trap ' 183*10898Sroland.mainz@nrubsig.org echo 2-intr 184*10898Sroland.mainz@nrubsig.org exit 0 185*10898Sroland.mainz@nrubsig.org ' INT 186*10898Sroland.mainz@nrubsig.org ;; 1878462SApril.Chin@Sun.COM*x*) trap ' 1888462SApril.Chin@Sun.COM echo 2-intr 1898462SApril.Chin@Sun.COM exit 1908462SApril.Chin@Sun.COM ' INT 1918462SApril.Chin@Sun.COM ;; 1928462SApril.Chin@Sun.COM*t*) trap ' 1938462SApril.Chin@Sun.COM echo 2-intr 1948462SApril.Chin@Sun.COM trap - INT 1958462SApril.Chin@Sun.COM kill -s INT $$ 1968462SApril.Chin@Sun.COM ' INT 1978462SApril.Chin@Sun.COM ;; 1988462SApril.Chin@Sun.COMesac 1998462SApril.Chin@Sun.COMcase $1 in 2008462SApril.Chin@Sun.COM*v*) echo 2-main ;; 2018462SApril.Chin@Sun.COMesac 2028462SApril.Chin@Sun.COMcase $1 in 2038462SApril.Chin@Sun.COM*d*) tst-3 $1 $2; status=$? ;; 2048462SApril.Chin@Sun.COM*) $2 -c "tst-3 $1 $2"; status=$? ;; 2058462SApril.Chin@Sun.COMesac 2068462SApril.Chin@Sun.COMprintf '2-%04d\n' $status 2078462SApril.Chin@Sun.COM! 2088462SApril.Chin@Sun.COMcat > tst-3 <<'!' 2098462SApril.Chin@Sun.COMcase $1 in 210*10898Sroland.mainz@nrubsig.org*[xz]*) trap ' 2118462SApril.Chin@Sun.COM sleep 2 2128462SApril.Chin@Sun.COM echo 3-intr 2138462SApril.Chin@Sun.COM exit 0 2148462SApril.Chin@Sun.COM ' INT 2158462SApril.Chin@Sun.COM ;; 2168462SApril.Chin@Sun.COM*) trap ' 2178462SApril.Chin@Sun.COM sleep 2 2188462SApril.Chin@Sun.COM echo 3-intr 2198462SApril.Chin@Sun.COM trap - INT 2208462SApril.Chin@Sun.COM kill -s INT $$ 2218462SApril.Chin@Sun.COM ' INT 2228462SApril.Chin@Sun.COM ;; 2238462SApril.Chin@Sun.COMesac 2248462SApril.Chin@Sun.COMcase $1 in 2258462SApril.Chin@Sun.COM*v*) echo 3-main ;; 2268462SApril.Chin@Sun.COMesac 2278462SApril.Chin@Sun.COMsleep 5 2288462SApril.Chin@Sun.COMprintf '3-%04d\n' $? 2298462SApril.Chin@Sun.COM! 2308462SApril.Chin@Sun.COMchmod +x tst tst-? 2318462SApril.Chin@Sun.COM 2328462SApril.Chin@Sun.COM# end standalone test generation 2338462SApril.Chin@Sun.COM 2348462SApril.Chin@Sun.COMexport PATH=$PATH: 2358462SApril.Chin@Sun.COMtypeset -A expected 2368462SApril.Chin@Sun.COMexpected[---]="3-intr" 2378462SApril.Chin@Sun.COMexpected[--d]="3-intr" 2388462SApril.Chin@Sun.COMexpected[-t-]="3-intr 2-intr 1-intr 1-0258" 2398462SApril.Chin@Sun.COMexpected[-td]="3-intr 2-intr 1-intr 1-0258" 240*10898Sroland.mainz@nrubsig.orgexpected[x--]="3-intr 2-intr" 241*10898Sroland.mainz@nrubsig.orgexpected[x-d]="3-intr 2-intr" 242*10898Sroland.mainz@nrubsig.orgexpected[xt-]="3-intr 2-intr 1-intr 1-0258" 243*10898Sroland.mainz@nrubsig.orgexpected[xtd]="3-intr 2-intr 1-intr 1-0258" 244*10898Sroland.mainz@nrubsig.orgexpected[z--]="3-intr 2-intr 1-0000" 245*10898Sroland.mainz@nrubsig.orgexpected[z-d]="3-intr 2-intr 1-0000" 246*10898Sroland.mainz@nrubsig.orgexpected[zt-]="3-intr 2-intr 1-intr 1-0000" 247*10898Sroland.mainz@nrubsig.orgexpected[ztd]="3-intr 2-intr 1-intr 1-0000" 2488462SApril.Chin@Sun.COM 2498462SApril.Chin@Sun.COMtst $SHELL > tst.got 2508462SApril.Chin@Sun.COM 2518462SApril.Chin@Sun.COMwhile read ops out 2528462SApril.Chin@Sun.COMdo [[ $out == ${expected[$ops]} ]] || err_exit "interrupt $ops test failed -- expected '${expected[$ops]}', got '$out'" 2538462SApril.Chin@Sun.COMdone < tst.got 2548462SApril.Chin@Sun.COM 2558462SApril.Chin@Sun.COMfloat s=$SECONDS 256*10898Sroland.mainz@nrubsig.org[[ $($SHELL -c 'trap "print SIGUSR1 ; exit 0" USR1; (trap "" USR1 ; exec kill -USR1 $$ & sleep 5); print done') == SIGUSR1 ]] || err_exit 'subshell ignoring signal does not send signal to parent' 2578462SApril.Chin@Sun.COM(( (SECONDS-s) < 4 )) && err_exit 'parent does not wait for child to complete before handling signal' 2588462SApril.Chin@Sun.COM((s = SECONDS)) 259*10898Sroland.mainz@nrubsig.org[[ $($SHELL -c 'trap "print SIGUSR1 ; exit 0" USR1; (trap "exit" USR1 ; exec kill -USR1 $$ & sleep 5); print done') == SIGUSR1 ]] || err_exit 'subshell catching signal does not send signal to parent' 2608462SApril.Chin@Sun.COM(( SECONDS-s < 4 )) && err_exit 'parent completes early' 261*10898Sroland.mainz@nrubsig.org 262*10898Sroland.mainz@nrubsig.orgunset n s t 263*10898Sroland.mainz@nrubsig.orgfor s in $(kill -l) 264*10898Sroland.mainz@nrubsig.orgdo if ! n=$(kill -l $s 2>/dev/null) 265*10898Sroland.mainz@nrubsig.org then err_exit "'kill -l $s' failed" 266*10898Sroland.mainz@nrubsig.org continue 267*10898Sroland.mainz@nrubsig.org fi 268*10898Sroland.mainz@nrubsig.org if ! t=$(kill -l $n 2>/dev/null) 269*10898Sroland.mainz@nrubsig.org then err_exit "'kill -l $n' failed" 270*10898Sroland.mainz@nrubsig.org continue 271*10898Sroland.mainz@nrubsig.org fi 272*10898Sroland.mainz@nrubsig.org if [[ $s == ?(SIG)$t ]] 273*10898Sroland.mainz@nrubsig.org then continue 274*10898Sroland.mainz@nrubsig.org fi 275*10898Sroland.mainz@nrubsig.org if ! m=$(kill -l $t 2>/dev/null) 276*10898Sroland.mainz@nrubsig.org then err_exit "'kill -l $t' failed" 277*10898Sroland.mainz@nrubsig.org continue 278*10898Sroland.mainz@nrubsig.org fi 279*10898Sroland.mainz@nrubsig.org if [[ $m == $n ]] 280*10898Sroland.mainz@nrubsig.org then continue 281*10898Sroland.mainz@nrubsig.org fi 282*10898Sroland.mainz@nrubsig.org err_exit "'kill -l $s' => $n, 'kill -l $n' => $t, kill -l $t => $m -- expected $n" 283*10898Sroland.mainz@nrubsig.orgdone 284*10898Sroland.mainz@nrubsig.orgyes=$(whence -p yes) 285*10898Sroland.mainz@nrubsig.org[[ $yes ]] && for exp in TERM VTALRM PIPE 286*10898Sroland.mainz@nrubsig.orgdo { $SHELL <<- EOF 287*10898Sroland.mainz@nrubsig.org foo() { return 0; } 288*10898Sroland.mainz@nrubsig.org trap foo EXIT 289*10898Sroland.mainz@nrubsig.org { sleep 2; kill -$exp \$\$; sleep 3; kill -0 \$\$ && kill -KILL \$\$; } & 290*10898Sroland.mainz@nrubsig.org $yes | while read yes; do 291*10898Sroland.mainz@nrubsig.org (/bin/date; sleep .1) 292*10898Sroland.mainz@nrubsig.org done > /dev/null 293*10898Sroland.mainz@nrubsig.org EOF 294*10898Sroland.mainz@nrubsig.org } 2>> /dev/null 295*10898Sroland.mainz@nrubsig.org got=$(kill -l $?) 296*10898Sroland.mainz@nrubsig.org [[ $exp == $got ]] || err_exit "kill -$exp \$\$ failed, required termination by signal '$got'" 297*10898Sroland.mainz@nrubsig.orgdone 298*10898Sroland.mainz@nrubsig.org 299*10898Sroland.mainz@nrubsig.orgSECONDS=0 300*10898Sroland.mainz@nrubsig.org$SHELL 2> /dev/null -c 'sleep 2 && kill $$ & trap "print done;exit 3" EXIT; (sleep 5);print finished' > $tmp/sig 301*10898Sroland.mainz@nrubsig.org(( $?==3)) || err_exit "wrong exit status expecting 3 got $?" 302*10898Sroland.mainz@nrubsig.orgx=$(<$tmp/sig) 303*10898Sroland.mainz@nrubsig.org[[ $x == done ]] || err_exit "wrong result - execting done got $x" 304*10898Sroland.mainz@nrubsig.org(( SECONDS > 3.5 )) && err_exit "took $SECONDS seconds, expecting around 2" 305*10898Sroland.mainz@nrubsig.org 306*10898Sroland.mainz@nrubsig.orgSECONDS=0 307*10898Sroland.mainz@nrubsig.org{ $SHELL 2> /dev/null -c 'sleep 2 && kill $$ & trap "print done;exit" EXIT; (sleep 5);print finished' > $tmp/sig ;} 2> /dev/null 308*10898Sroland.mainz@nrubsig.org[[ $(kill -l $?) == TERM ]] || err_exit "wrong exit status expecting TERM got $(kill -l $?)" 309*10898Sroland.mainz@nrubsig.orgx=$(<$tmp/sig) 310*10898Sroland.mainz@nrubsig.org[[ $x == done ]] || err_exit "wrong result - execting done got $x" 311*10898Sroland.mainz@nrubsig.org(( SECONDS > 3.5 )) && err_exit "took $SECONDS seconds, expecting around 2" 312*10898Sroland.mainz@nrubsig.org 313*10898Sroland.mainz@nrubsig.orgSECONDS=0 314*10898Sroland.mainz@nrubsig.orgx=$($SHELL 2> /dev/null -c 'sleep 2 && kill $$ & trap "print done;exit 3" EXIT; (sleep 5);print finished') 315*10898Sroland.mainz@nrubsig.org(( $?==3)) || err_exit "wrong exit status expecting 3 got $?" 316*10898Sroland.mainz@nrubsig.org[[ $x == done ]] || err_exit "wrong result - execting done got $x" 317*10898Sroland.mainz@nrubsig.org(( SECONDS < 4 )) && err_exit "took $SECONDS seconds, expecting around 5" 318*10898Sroland.mainz@nrubsig.org 319*10898Sroland.mainz@nrubsig.orgtrap '' SIGBUS 320*10898Sroland.mainz@nrubsig.org[[ $($SHELL -c 'trap date SIGBUS;trap -p SIGBUS') ]] && err_exit 'SIGBUS should not have a trap' 321*10898Sroland.mainz@nrubsig.orgtrap -- - SIGBUS 322*10898Sroland.mainz@nrubsig.org 3238462SApril.Chin@Sun.COMexit $((Errors)) 324