1*8462SApril.Chin@Sun.COM######################################################################## 2*8462SApril.Chin@Sun.COM# # 3*8462SApril.Chin@Sun.COM# This software is part of the ast package # 4*8462SApril.Chin@Sun.COM# Copyright (c) 1982-2008 AT&T Intellectual Property # 5*8462SApril.Chin@Sun.COM# and is licensed under the # 6*8462SApril.Chin@Sun.COM# Common Public License, Version 1.0 # 7*8462SApril.Chin@Sun.COM# by AT&T Intellectual Property # 8*8462SApril.Chin@Sun.COM# # 9*8462SApril.Chin@Sun.COM# A copy of the License is available at # 10*8462SApril.Chin@Sun.COM# http://www.opensource.org/licenses/cpl1.0.txt # 11*8462SApril.Chin@Sun.COM# (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) # 12*8462SApril.Chin@Sun.COM# # 13*8462SApril.Chin@Sun.COM# Information and Software Systems Research # 14*8462SApril.Chin@Sun.COM# AT&T Research # 15*8462SApril.Chin@Sun.COM# Florham Park NJ # 16*8462SApril.Chin@Sun.COM# # 17*8462SApril.Chin@Sun.COM# David Korn <dgk@research.att.com> # 18*8462SApril.Chin@Sun.COM# # 19*8462SApril.Chin@Sun.COM######################################################################## 20*8462SApril.Chin@Sun.COMfunction err_exit 21*8462SApril.Chin@Sun.COM{ 22*8462SApril.Chin@Sun.COM print -u2 -n "\t" 23*8462SApril.Chin@Sun.COM print -u2 -r ${Command}[$1]: "${@:2}" 24*8462SApril.Chin@Sun.COM (( Errors++ )) 25*8462SApril.Chin@Sun.COM} 26*8462SApril.Chin@Sun.COMalias err_exit='err_exit $LINENO' 27*8462SApril.Chin@Sun.COM 28*8462SApril.Chin@Sun.COMCommand=${0##*/} 29*8462SApril.Chin@Sun.COMinteger Errors=0 30*8462SApril.Chin@Sun.COM 31*8462SApril.Chin@Sun.COMmkdir /tmp/ksh$$ || err_exit "mkdir /tmp/ksh$$ failed" 32*8462SApril.Chin@Sun.COMtrap 'cd /; rm -rf /tmp/ksh$$' EXIT 33*8462SApril.Chin@Sun.COMcd /tmp/ksh$$ || err_exit "cd /tmp/ksh$$ failed" 34*8462SApril.Chin@Sun.COM 35*8462SApril.Chin@Sun.COM[[ $( trap 'print -n got_child' SIGCHLD 36*8462SApril.Chin@Sun.COM sleep 2 & 37*8462SApril.Chin@Sun.COM for ((i=0; i < 4; i++)) 38*8462SApril.Chin@Sun.COM do sleep .9 39*8462SApril.Chin@Sun.COM print -n $i 40*8462SApril.Chin@Sun.COM done) == 01got_child23 ]] || err_exit 'SIGCHLD not working' 41*8462SApril.Chin@Sun.COM 42*8462SApril.Chin@Sun.COM# begin standalone SIGINT test generation 43*8462SApril.Chin@Sun.COM 44*8462SApril.Chin@Sun.COMcat > tst <<'!' 45*8462SApril.Chin@Sun.COM# shell trap tests 46*8462SApril.Chin@Sun.COM# 47*8462SApril.Chin@Sun.COM# tst control script that calls tst-1, must be run by ksh 48*8462SApril.Chin@Sun.COM# tst-1 calls tst-2 49*8462SApril.Chin@Sun.COM# tst-2 calls tst-3 50*8462SApril.Chin@Sun.COM# tst-3 defaults or handles and discards/propagates SIGINT 51*8462SApril.Chin@Sun.COM# 52*8462SApril.Chin@Sun.COM# initial -v option lists script entry and SIGINT delivery 53*8462SApril.Chin@Sun.COM# 54*8462SApril.Chin@Sun.COM# three test options 55*8462SApril.Chin@Sun.COM# 56*8462SApril.Chin@Sun.COM# d call next script directly, otherwise via $SHELL -c 57*8462SApril.Chin@Sun.COM# t trap, echo, and kill self on SIGINT, otherwise x or SIGINT default if no x 58*8462SApril.Chin@Sun.COM# x trap, echo on SIGINT, and exit 0, otherwise SIGINT default 59*8462SApril.Chin@Sun.COM# 60*8462SApril.Chin@Sun.COM# Usage: tst [-v] [-options] shell-to-test ... 61*8462SApril.Chin@Sun.COM 62*8462SApril.Chin@Sun.COM# "trap + sig" is an unadvertized extension for this test 63*8462SApril.Chin@Sun.COM# if run from nmake SIGINT is set to SIG_IGN 64*8462SApril.Chin@Sun.COM# this call sets it back to SIG_DFL 65*8462SApril.Chin@Sun.COM# semantics w.r.t. function scope must be worked out before 66*8462SApril.Chin@Sun.COM# making it public 67*8462SApril.Chin@Sun.COMtrap + INT 68*8462SApril.Chin@Sun.COM 69*8462SApril.Chin@Sun.COMset -o monitor 70*8462SApril.Chin@Sun.COM 71*8462SApril.Chin@Sun.COMfunction gen 72*8462SApril.Chin@Sun.COM{ 73*8462SApril.Chin@Sun.COM typeset o t x d 74*8462SApril.Chin@Sun.COM for x in - x 75*8462SApril.Chin@Sun.COM do case $x in 76*8462SApril.Chin@Sun.COM [$1]) for t in - t 77*8462SApril.Chin@Sun.COM do case $t in 78*8462SApril.Chin@Sun.COM [$1]) for d in - d 79*8462SApril.Chin@Sun.COM do case $d in 80*8462SApril.Chin@Sun.COM [$1]) o="$o $x$t$d" 81*8462SApril.Chin@Sun.COM esac 82*8462SApril.Chin@Sun.COM done 83*8462SApril.Chin@Sun.COM esac 84*8462SApril.Chin@Sun.COM done 85*8462SApril.Chin@Sun.COM esac 86*8462SApril.Chin@Sun.COM done 87*8462SApril.Chin@Sun.COM echo '' $o 88*8462SApril.Chin@Sun.COM} 89*8462SApril.Chin@Sun.COM 90*8462SApril.Chin@Sun.COMcase $1 in 91*8462SApril.Chin@Sun.COM-v) v=v; shift ;; 92*8462SApril.Chin@Sun.COM-*v*) v=v ;; 93*8462SApril.Chin@Sun.COM*) v= ;; 94*8462SApril.Chin@Sun.COMesac 95*8462SApril.Chin@Sun.COMcase $1 in 96*8462SApril.Chin@Sun.COM*' '*) o=$1; shift ;; 97*8462SApril.Chin@Sun.COM-*) o=$(gen $1); shift ;; 98*8462SApril.Chin@Sun.COM*) o=$(gen -txd) ;; 99*8462SApril.Chin@Sun.COMesac 100*8462SApril.Chin@Sun.COMcase $# in 101*8462SApril.Chin@Sun.COM0) set ksh bash ksh88 pdksh ash zsh ;; 102*8462SApril.Chin@Sun.COMesac 103*8462SApril.Chin@Sun.COMfor f in $o 104*8462SApril.Chin@Sun.COMdo case $# in 105*8462SApril.Chin@Sun.COM 1) ;; 106*8462SApril.Chin@Sun.COM *) echo ;; 107*8462SApril.Chin@Sun.COM esac 108*8462SApril.Chin@Sun.COM for sh 109*8462SApril.Chin@Sun.COM do if $sh -c 'exit 0' > /dev/null 2>&1 110*8462SApril.Chin@Sun.COM then case $# in 111*8462SApril.Chin@Sun.COM 1) printf '%3s ' "$f" ;; 112*8462SApril.Chin@Sun.COM *) printf '%16s %3s ' "$sh" "$f" ;; 113*8462SApril.Chin@Sun.COM esac 114*8462SApril.Chin@Sun.COM $sh tst-1 $v$f $sh > tst.out & 115*8462SApril.Chin@Sun.COM wait 116*8462SApril.Chin@Sun.COM echo $(cat tst.out) 117*8462SApril.Chin@Sun.COM fi 118*8462SApril.Chin@Sun.COM done 119*8462SApril.Chin@Sun.COMdone 120*8462SApril.Chin@Sun.COMcase $# in 121*8462SApril.Chin@Sun.COM1) ;; 122*8462SApril.Chin@Sun.COM*) echo ;; 123*8462SApril.Chin@Sun.COMesac 124*8462SApril.Chin@Sun.COM! 125*8462SApril.Chin@Sun.COMcat > tst-1 <<'!' 126*8462SApril.Chin@Sun.COMexec 2>/dev/null 127*8462SApril.Chin@Sun.COMcase $1 in 128*8462SApril.Chin@Sun.COM*v*) echo 1-main ;; 129*8462SApril.Chin@Sun.COMesac 130*8462SApril.Chin@Sun.COM{ 131*8462SApril.Chin@Sun.COM sleep 2 132*8462SApril.Chin@Sun.COM case $1 in 133*8462SApril.Chin@Sun.COM *v*) echo "SIGINT" ;; 134*8462SApril.Chin@Sun.COM esac 135*8462SApril.Chin@Sun.COM kill -s INT 0 136*8462SApril.Chin@Sun.COM} & 137*8462SApril.Chin@Sun.COMcase $1 in 138*8462SApril.Chin@Sun.COM*t*) trap ' 139*8462SApril.Chin@Sun.COM echo 1-intr 140*8462SApril.Chin@Sun.COM trap - INT 141*8462SApril.Chin@Sun.COM # omitting the self kill exposes shells that deliver 142*8462SApril.Chin@Sun.COM # the SIGINT trap but exit 0 for -xt 143*8462SApril.Chin@Sun.COM # kill -s INT $$ 144*8462SApril.Chin@Sun.COM ' INT 145*8462SApril.Chin@Sun.COM ;; 146*8462SApril.Chin@Sun.COMesac 147*8462SApril.Chin@Sun.COMcase $1 in 148*8462SApril.Chin@Sun.COM*d*) tst-2 $1 $2; status=$? ;; 149*8462SApril.Chin@Sun.COM*) $2 -c "tst-2 $1 $2"; status=$? ;; 150*8462SApril.Chin@Sun.COMesac 151*8462SApril.Chin@Sun.COMprintf '1-%04d\n' $status 152*8462SApril.Chin@Sun.COMsleep 2 153*8462SApril.Chin@Sun.COM! 154*8462SApril.Chin@Sun.COMcat > tst-2 <<'!' 155*8462SApril.Chin@Sun.COMcase $1 in 156*8462SApril.Chin@Sun.COM*x*) trap ' 157*8462SApril.Chin@Sun.COM echo 2-intr 158*8462SApril.Chin@Sun.COM exit 159*8462SApril.Chin@Sun.COM ' INT 160*8462SApril.Chin@Sun.COM ;; 161*8462SApril.Chin@Sun.COM*t*) trap ' 162*8462SApril.Chin@Sun.COM echo 2-intr 163*8462SApril.Chin@Sun.COM trap - INT 164*8462SApril.Chin@Sun.COM kill -s INT $$ 165*8462SApril.Chin@Sun.COM ' INT 166*8462SApril.Chin@Sun.COM ;; 167*8462SApril.Chin@Sun.COMesac 168*8462SApril.Chin@Sun.COMcase $1 in 169*8462SApril.Chin@Sun.COM*v*) echo 2-main ;; 170*8462SApril.Chin@Sun.COMesac 171*8462SApril.Chin@Sun.COMcase $1 in 172*8462SApril.Chin@Sun.COM*d*) tst-3 $1 $2; status=$? ;; 173*8462SApril.Chin@Sun.COM*) $2 -c "tst-3 $1 $2"; status=$? ;; 174*8462SApril.Chin@Sun.COMesac 175*8462SApril.Chin@Sun.COMprintf '2-%04d\n' $status 176*8462SApril.Chin@Sun.COM! 177*8462SApril.Chin@Sun.COMcat > tst-3 <<'!' 178*8462SApril.Chin@Sun.COMcase $1 in 179*8462SApril.Chin@Sun.COM*x*) trap ' 180*8462SApril.Chin@Sun.COM sleep 2 181*8462SApril.Chin@Sun.COM echo 3-intr 182*8462SApril.Chin@Sun.COM exit 0 183*8462SApril.Chin@Sun.COM ' INT 184*8462SApril.Chin@Sun.COM ;; 185*8462SApril.Chin@Sun.COM*) trap ' 186*8462SApril.Chin@Sun.COM sleep 2 187*8462SApril.Chin@Sun.COM echo 3-intr 188*8462SApril.Chin@Sun.COM trap - INT 189*8462SApril.Chin@Sun.COM kill -s INT $$ 190*8462SApril.Chin@Sun.COM ' INT 191*8462SApril.Chin@Sun.COM ;; 192*8462SApril.Chin@Sun.COMesac 193*8462SApril.Chin@Sun.COMcase $1 in 194*8462SApril.Chin@Sun.COM*v*) echo 3-main ;; 195*8462SApril.Chin@Sun.COMesac 196*8462SApril.Chin@Sun.COMsleep 5 197*8462SApril.Chin@Sun.COMprintf '3-%04d\n' $? 198*8462SApril.Chin@Sun.COM! 199*8462SApril.Chin@Sun.COMchmod +x tst tst-? 200*8462SApril.Chin@Sun.COM 201*8462SApril.Chin@Sun.COM# end standalone test generation 202*8462SApril.Chin@Sun.COM 203*8462SApril.Chin@Sun.COMexport PATH=$PATH: 204*8462SApril.Chin@Sun.COMtypeset -A expected 205*8462SApril.Chin@Sun.COMexpected[---]="3-intr" 206*8462SApril.Chin@Sun.COMexpected[--d]="3-intr" 207*8462SApril.Chin@Sun.COMexpected[-t-]="3-intr 2-intr 1-intr 1-0258" 208*8462SApril.Chin@Sun.COMexpected[-td]="3-intr 2-intr 1-intr 1-0258" 209*8462SApril.Chin@Sun.COMexpected[x--]="3-intr 2-intr 1-0000" 210*8462SApril.Chin@Sun.COMexpected[x-d]="3-intr 2-intr 1-0000" 211*8462SApril.Chin@Sun.COMexpected[xt-]="3-intr 2-intr 1-intr 1-0000" 212*8462SApril.Chin@Sun.COMexpected[xtd]="3-intr 2-intr 1-intr 1-0000" 213*8462SApril.Chin@Sun.COM 214*8462SApril.Chin@Sun.COMtst $SHELL > tst.got 215*8462SApril.Chin@Sun.COM 216*8462SApril.Chin@Sun.COMwhile read ops out 217*8462SApril.Chin@Sun.COMdo [[ $out == ${expected[$ops]} ]] || err_exit "interrupt $ops test failed -- expected '${expected[$ops]}', got '$out'" 218*8462SApril.Chin@Sun.COMdone < tst.got 219*8462SApril.Chin@Sun.COM 220*8462SApril.Chin@Sun.COMfloat s=$SECONDS 221*8462SApril.Chin@Sun.COM[[ $($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' 222*8462SApril.Chin@Sun.COM(( (SECONDS-s) < 4 )) && err_exit 'parent does not wait for child to complete before handling signal' 223*8462SApril.Chin@Sun.COM((s = SECONDS)) 224*8462SApril.Chin@Sun.COM[[ $($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' 225*8462SApril.Chin@Sun.COM(( SECONDS-s < 4 )) && err_exit 'parent completes early' 226*8462SApril.Chin@Sun.COMexit $((Errors)) 227