18462SApril.Chin@Sun.COM######################################################################## 28462SApril.Chin@Sun.COM# # 38462SApril.Chin@Sun.COM# This software is part of the ast package # 4*12068SRoger.Faulkner@Oracle.COM# Copyright (c) 1982-2010 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 3110898Sroland.mainz@nrubsig.orgtmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 3210898Sroland.mainz@nrubsig.orgtrap "cd /; rm -rf $tmp" EXIT 3310898Sroland.mainz@nrubsig.org 3410898Sroland.mainz@nrubsig.orgcd $tmp || err_exit "cd $tmp failed" 3510898Sroland.mainz@nrubsig.org 3610898Sroland.mainz@nrubsig.org( 3710898Sroland.mainz@nrubsig.org set --pipefail 3810898Sroland.mainz@nrubsig.org { 3910898Sroland.mainz@nrubsig.org $SHELL 2> out2 <<- \EOF 4010898Sroland.mainz@nrubsig.org g=false 4110898Sroland.mainz@nrubsig.org trap 'print -u2 PIPED; $g && exit 0;g=true' PIPE 4210898Sroland.mainz@nrubsig.org while : 4310898Sroland.mainz@nrubsig.org do print hello 4410898Sroland.mainz@nrubsig.org done 4510898Sroland.mainz@nrubsig.org EOF 4610898Sroland.mainz@nrubsig.org } | head > /dev/null 4710898Sroland.mainz@nrubsig.org (( $? == 0)) || err_exit "SIGPIPE with wrong error code $?" 4810898Sroland.mainz@nrubsig.org [[ $(<out2) == $'PIPED\nPIPED' ]] || err_exit 'SIGPIPE output on standard error is not correct' 4910898Sroland.mainz@nrubsig.org) & 5010898Sroland.mainz@nrubsig.orgcop=$! 5110898Sroland.mainz@nrubsig.org{ sleep 4; kill $cop; } 2>/dev/null & 5210898Sroland.mainz@nrubsig.orgspy=$! 5310898Sroland.mainz@nrubsig.orgif wait $cop 2>/dev/null 5410898Sroland.mainz@nrubsig.orgthen kill $spy 2>/dev/null 5510898Sroland.mainz@nrubsig.orgelse err_exit "pipe with --pipefail PIPE trap hangs" 5610898Sroland.mainz@nrubsig.orgfi 5710898Sroland.mainz@nrubsig.orgwait 5810898Sroland.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++)) 6310898Sroland.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 8310898Sroland.mainz@nrubsig.org# x trap, echo on SIGINT, and tst-3 exit 0, tst-2 exit, otherwise SIGINT default 8410898Sroland.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 10010898Sroland.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 18210898Sroland.mainz@nrubsig.org*z*) trap ' 18310898Sroland.mainz@nrubsig.org echo 2-intr 18410898Sroland.mainz@nrubsig.org exit 0 18510898Sroland.mainz@nrubsig.org ' INT 18610898Sroland.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 21010898Sroland.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" 24010898Sroland.mainz@nrubsig.orgexpected[x--]="3-intr 2-intr" 24110898Sroland.mainz@nrubsig.orgexpected[x-d]="3-intr 2-intr" 24210898Sroland.mainz@nrubsig.orgexpected[xt-]="3-intr 2-intr 1-intr 1-0258" 24310898Sroland.mainz@nrubsig.orgexpected[xtd]="3-intr 2-intr 1-intr 1-0258" 24410898Sroland.mainz@nrubsig.orgexpected[z--]="3-intr 2-intr 1-0000" 24510898Sroland.mainz@nrubsig.orgexpected[z-d]="3-intr 2-intr 1-0000" 24610898Sroland.mainz@nrubsig.orgexpected[zt-]="3-intr 2-intr 1-intr 1-0000" 24710898Sroland.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 25610898Sroland.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)) 25910898Sroland.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' 26110898Sroland.mainz@nrubsig.org 26210898Sroland.mainz@nrubsig.orgunset n s t 26310898Sroland.mainz@nrubsig.orgfor s in $(kill -l) 26410898Sroland.mainz@nrubsig.orgdo if ! n=$(kill -l $s 2>/dev/null) 26510898Sroland.mainz@nrubsig.org then err_exit "'kill -l $s' failed" 26610898Sroland.mainz@nrubsig.org continue 26710898Sroland.mainz@nrubsig.org fi 26810898Sroland.mainz@nrubsig.org if ! t=$(kill -l $n 2>/dev/null) 26910898Sroland.mainz@nrubsig.org then err_exit "'kill -l $n' failed" 27010898Sroland.mainz@nrubsig.org continue 27110898Sroland.mainz@nrubsig.org fi 27210898Sroland.mainz@nrubsig.org if [[ $s == ?(SIG)$t ]] 27310898Sroland.mainz@nrubsig.org then continue 27410898Sroland.mainz@nrubsig.org fi 27510898Sroland.mainz@nrubsig.org if ! m=$(kill -l $t 2>/dev/null) 27610898Sroland.mainz@nrubsig.org then err_exit "'kill -l $t' failed" 27710898Sroland.mainz@nrubsig.org continue 27810898Sroland.mainz@nrubsig.org fi 27910898Sroland.mainz@nrubsig.org if [[ $m == $n ]] 28010898Sroland.mainz@nrubsig.org then continue 28110898Sroland.mainz@nrubsig.org fi 28210898Sroland.mainz@nrubsig.org err_exit "'kill -l $s' => $n, 'kill -l $n' => $t, kill -l $t => $m -- expected $n" 28310898Sroland.mainz@nrubsig.orgdone 28410898Sroland.mainz@nrubsig.orgyes=$(whence -p yes) 28510898Sroland.mainz@nrubsig.org[[ $yes ]] && for exp in TERM VTALRM PIPE 28610898Sroland.mainz@nrubsig.orgdo { $SHELL <<- EOF 28710898Sroland.mainz@nrubsig.org foo() { return 0; } 28810898Sroland.mainz@nrubsig.org trap foo EXIT 28910898Sroland.mainz@nrubsig.org { sleep 2; kill -$exp \$\$; sleep 3; kill -0 \$\$ && kill -KILL \$\$; } & 29010898Sroland.mainz@nrubsig.org $yes | while read yes; do 29110898Sroland.mainz@nrubsig.org (/bin/date; sleep .1) 29210898Sroland.mainz@nrubsig.org done > /dev/null 29310898Sroland.mainz@nrubsig.org EOF 29410898Sroland.mainz@nrubsig.org } 2>> /dev/null 29510898Sroland.mainz@nrubsig.org got=$(kill -l $?) 29610898Sroland.mainz@nrubsig.org [[ $exp == $got ]] || err_exit "kill -$exp \$\$ failed, required termination by signal '$got'" 29710898Sroland.mainz@nrubsig.orgdone 29810898Sroland.mainz@nrubsig.org 29910898Sroland.mainz@nrubsig.orgSECONDS=0 30010898Sroland.mainz@nrubsig.org$SHELL 2> /dev/null -c 'sleep 2 && kill $$ & trap "print done;exit 3" EXIT; (sleep 5);print finished' > $tmp/sig 30110898Sroland.mainz@nrubsig.org(( $?==3)) || err_exit "wrong exit status expecting 3 got $?" 30210898Sroland.mainz@nrubsig.orgx=$(<$tmp/sig) 30310898Sroland.mainz@nrubsig.org[[ $x == done ]] || err_exit "wrong result - execting done got $x" 30410898Sroland.mainz@nrubsig.org(( SECONDS > 3.5 )) && err_exit "took $SECONDS seconds, expecting around 2" 30510898Sroland.mainz@nrubsig.org 30610898Sroland.mainz@nrubsig.orgSECONDS=0 30710898Sroland.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 30810898Sroland.mainz@nrubsig.org[[ $(kill -l $?) == TERM ]] || err_exit "wrong exit status expecting TERM got $(kill -l $?)" 30910898Sroland.mainz@nrubsig.orgx=$(<$tmp/sig) 31010898Sroland.mainz@nrubsig.org[[ $x == done ]] || err_exit "wrong result - execting done got $x" 31110898Sroland.mainz@nrubsig.org(( SECONDS > 3.5 )) && err_exit "took $SECONDS seconds, expecting around 2" 31210898Sroland.mainz@nrubsig.org 31310898Sroland.mainz@nrubsig.orgSECONDS=0 31410898Sroland.mainz@nrubsig.orgx=$($SHELL 2> /dev/null -c 'sleep 2 && kill $$ & trap "print done;exit 3" EXIT; (sleep 5);print finished') 31510898Sroland.mainz@nrubsig.org(( $?==3)) || err_exit "wrong exit status expecting 3 got $?" 31610898Sroland.mainz@nrubsig.org[[ $x == done ]] || err_exit "wrong result - execting done got $x" 31710898Sroland.mainz@nrubsig.org(( SECONDS < 4 )) && err_exit "took $SECONDS seconds, expecting around 5" 31810898Sroland.mainz@nrubsig.org 31910898Sroland.mainz@nrubsig.orgtrap '' SIGBUS 32010898Sroland.mainz@nrubsig.org[[ $($SHELL -c 'trap date SIGBUS;trap -p SIGBUS') ]] && err_exit 'SIGBUS should not have a trap' 32110898Sroland.mainz@nrubsig.orgtrap -- - SIGBUS 32210898Sroland.mainz@nrubsig.org 3238462SApril.Chin@Sun.COMexit $((Errors)) 324