xref: /onnv-gate/usr/src/lib/libshell/common/tests/signal.sh (revision 12068:08a39a083754)
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