xref: /titanic_50/usr/src/lib/libshell/common/tests/signal.sh (revision 3db3491215579980a91e230cf21b20608fbb8259)
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