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