17c2fbfb3SApril Chin########################################################################
27c2fbfb3SApril Chin#                                                                      #
37c2fbfb3SApril Chin#               This software is part of the ast package               #
4*b30d1939SAndy Fiddaman#          Copyright (c) 1982-2012 AT&T Intellectual Property          #
57c2fbfb3SApril Chin#                      and is licensed under the                       #
6*b30d1939SAndy Fiddaman#                 Eclipse Public License, Version 1.0                  #
77c2fbfb3SApril Chin#                    by AT&T Intellectual Property                     #
87c2fbfb3SApril Chin#                                                                      #
97c2fbfb3SApril Chin#                A copy of the License is available at                 #
10*b30d1939SAndy Fiddaman#          http://www.eclipse.org/org/documents/epl-v10.html           #
11*b30d1939SAndy Fiddaman#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
127c2fbfb3SApril Chin#                                                                      #
137c2fbfb3SApril Chin#              Information and Software Systems Research               #
147c2fbfb3SApril Chin#                            AT&T Research                             #
157c2fbfb3SApril Chin#                           Florham Park NJ                            #
167c2fbfb3SApril Chin#                                                                      #
177c2fbfb3SApril Chin#                  David Korn <dgk@research.att.com>                   #
187c2fbfb3SApril Chin#                                                                      #
197c2fbfb3SApril Chin########################################################################
207c2fbfb3SApril Chinfunction err_exit
217c2fbfb3SApril Chin{
227c2fbfb3SApril Chin	print -u2 -n "\t"
237c2fbfb3SApril Chin	print -u2 -r ${Command}[$1]: "${@:2}"
247c2fbfb3SApril Chin	(( Errors+=1 ))
257c2fbfb3SApril Chin}
267c2fbfb3SApril Chin
277c2fbfb3SApril Chinalias err_exit='err_exit $LINENO'
287c2fbfb3SApril Chin
293e14f97fSRoger A. Faulknerfloat DELAY=${1:-0.2}
307c2fbfb3SApril Chininteger FOREGROUND=10 BACKGROUND=2 Errors=0
317c2fbfb3SApril Chin
327c2fbfb3SApril Chins=$($SHELL -c '
337c2fbfb3SApril Chininteger i foreground=0 background=0
347c2fbfb3SApril Chinfloat delay='$DELAY' d=0 s=0
357c2fbfb3SApril Chin
367c2fbfb3SApril Chinset --errexit
377c2fbfb3SApril Chin
387c2fbfb3SApril Chintrap "(( background++ ))" CHLD
397c2fbfb3SApril Chin
407c2fbfb3SApril Chin(( d = delay ))
417c2fbfb3SApril Chinfor ((i = 0; i < '$BACKGROUND'; i++))
427c2fbfb3SApril Chindo	sleep $d &
437c2fbfb3SApril Chin	(( d *= 4 ))
447c2fbfb3SApril Chin	(( s += d ))
457c2fbfb3SApril Chindone
467c2fbfb3SApril Chinfor ((i = 0; i < '$FOREGROUND'; i++))
477c2fbfb3SApril Chindo	(( foreground++ ))
487c2fbfb3SApril Chin	sleep $delay
497c2fbfb3SApril Chin	(( s -= delay ))
507c2fbfb3SApril Chin	$SHELL -c : > /dev/null # foreground does not generate SIGCHLD
517c2fbfb3SApril Chindone
527c2fbfb3SApril Chinif	(( (s += delay) < 1 ))
537c2fbfb3SApril Chinthen	(( s = 1 ))
547c2fbfb3SApril Chinfi
557c2fbfb3SApril Chinsleep $s
567c2fbfb3SApril Chinwait
577c2fbfb3SApril Chinprint foreground=$foreground background=$background
587c2fbfb3SApril Chin') || err_exit "test loop failed"
597c2fbfb3SApril Chin
607c2fbfb3SApril Chineval $s
617c2fbfb3SApril Chin
6234f9b3eeSRoland Mainz(( foreground == FOREGROUND )) || err_exit "expected '$FOREGROUND foreground' -- got '$foreground' (DELAY=$DELAY)"
6334f9b3eeSRoland Mainz(( background == BACKGROUND )) || err_exit "expected '$BACKGROUND background' -- got '$background' (DELAY=$DELAY)"
6434f9b3eeSRoland Mainz
6534f9b3eeSRoland Mainzset --noerrexit
6634f9b3eeSRoland Mainz
6734f9b3eeSRoland Mainzif	[[ ${.sh.version} == Version?*([[:upper:]])J* ]]
6834f9b3eeSRoland Mainzthen
6934f9b3eeSRoland Mainz
7034f9b3eeSRoland Mainz	jobmax=4
7134f9b3eeSRoland Mainz	got=$($SHELL -c '
7234f9b3eeSRoland Mainz		JOBMAX='$jobmax' JOBCOUNT=$(('$jobmax'*2))
7334f9b3eeSRoland Mainz		integer running=0 maxrunning=0
7434f9b3eeSRoland Mainz		trap "((running--))" CHLD
7534f9b3eeSRoland Mainz		for ((i=0; i<JOBCOUNT; i++))
7634f9b3eeSRoland Mainz		do	sleep 1 &
7734f9b3eeSRoland Mainz			if	((++running > maxrunning))
7834f9b3eeSRoland Mainz			then	((maxrunning=running))
7934f9b3eeSRoland Mainz			fi
8034f9b3eeSRoland Mainz		done
8134f9b3eeSRoland Mainz		wait
8234f9b3eeSRoland Mainz		print running=$running maxrunning=$maxrunning
8334f9b3eeSRoland Mainz	')
8434f9b3eeSRoland Mainz	exp='running=0 maxrunning='$jobmax
8534f9b3eeSRoland Mainz	[[ $got == $exp ]] || err_exit "SIGCHLD trap queueing failed -- expected '$exp', got '$got'"
8634f9b3eeSRoland Mainz
8734f9b3eeSRoland Mainz	got=$($SHELL -c '
8834f9b3eeSRoland Mainz		typeset -A proc
8934f9b3eeSRoland Mainz
9034f9b3eeSRoland Mainz		trap "
9134f9b3eeSRoland Mainz			print \${proc[\$!].name} \${proc[\$!].status} \$?
9234f9b3eeSRoland Mainz			unset proc[\$!]
9334f9b3eeSRoland Mainz		" CHLD
9434f9b3eeSRoland Mainz
9534f9b3eeSRoland Mainz		{ sleep 3; print a; exit 1; } &
9634f9b3eeSRoland Mainz		proc[$!]=( name=a status=1 )
9734f9b3eeSRoland Mainz
9834f9b3eeSRoland Mainz		{ sleep 2; print b; exit 2; } &
9934f9b3eeSRoland Mainz		proc[$!]=( name=b status=2 )
10034f9b3eeSRoland Mainz
10134f9b3eeSRoland Mainz		{ sleep 1; print c; exit 3; } &
10234f9b3eeSRoland Mainz		proc[$!]=( name=c status=3 )
10334f9b3eeSRoland Mainz
10434f9b3eeSRoland Mainz		while	(( ${#proc[@]} ))
10534f9b3eeSRoland Mainz		do	sleep -s
10634f9b3eeSRoland Mainz		done
10734f9b3eeSRoland Mainz	')
10834f9b3eeSRoland Mainz	exp='c\nc 3 3\nb\nb 2 2\na\na 1 1'
10934f9b3eeSRoland Mainz	[[ $got == $exp ]] || err_exit "SIGCHLD trap queueing failed -- expected $(printf %q "$exp"), got $(printf %q "$got")"
11034f9b3eeSRoland Mainz
11134f9b3eeSRoland Mainzfi
1127c2fbfb3SApril Chin
1133e14f97fSRoger A. Faulkner{
1143e14f97fSRoger A. Faulknergot=$( ( sleep 1;print $'\n') | $SHELL -c 'function handler { : ;}
1153e14f97fSRoger A. Faulkner	trap handler CHLD; sleep .3 & IFS= read; print good')
1163e14f97fSRoger A. Faulkner} 2> /dev/null
1173e14f97fSRoger A. Faulkner[[ $got == good ]] || err_exit 'SIGCLD handler effects read behavior'
1183e14f97fSRoger A. Faulkner
1193e14f97fSRoger A. Faulknerset -- $(
1203e14f97fSRoger A. Faulkner	(
1213e14f97fSRoger A. Faulkner	$SHELL -xc $'
1223e14f97fSRoger A. Faulkner		trap \'wait $!; print $! $?\' CHLD
1233e14f97fSRoger A. Faulkner		{ sleep 0.1; exit 9; } &
1243e14f97fSRoger A. Faulkner		print $!
1253e14f97fSRoger A. Faulkner		sleep 0.5
1263e14f97fSRoger A. Faulkner	'
1273e14f97fSRoger A. Faulkner	) 2>/dev/null; print $?
1283e14f97fSRoger A. Faulkner)
1293e14f97fSRoger A. Faulknerif	(( $# != 4 ))
1303e14f97fSRoger A. Faulknerthen	err_exit "CHLD trap failed -- expected 4 args, got $#"
1313e14f97fSRoger A. Faulknerelif	(( $4 != 0 ))
1323e14f97fSRoger A. Faulknerthen	err_exit "CHLD trap failed -- exit code $4"
1333e14f97fSRoger A. Faulknerelif	(( $1 != $2 ))
1343e14f97fSRoger A. Faulknerthen	err_exit "child pid mismatch -- got '$1' != '$2'"
1353e14f97fSRoger A. Faulknerelif	(( $3 != 9 ))
1363e14f97fSRoger A. Faulknerthen	err_exit "child status mismatch -- expected '9', got '$3'"
1373e14f97fSRoger A. Faulknerfi
1383e14f97fSRoger A. Faulkner
139*b30d1939SAndy Fiddamantrap '' CHLD
140*b30d1939SAndy Fiddamaninteger d
141*b30d1939SAndy Fiddamanfor ((d=0; d < 2000; d++))
142*b30d1939SAndy Fiddamando      if      print foo | grep bar
143*b30d1939SAndy Fiddaman        then    break
144*b30d1939SAndy Fiddaman        fi
145*b30d1939SAndy Fiddamandone
146*b30d1939SAndy Fiddaman(( d==2000 )) ||  err_exit "trap '' CHLD  causes side effects d=$d"
147*b30d1939SAndy Fiddamantrap - CHLD
148*b30d1939SAndy Fiddaman
149*b30d1939SAndy Fiddamantmp=$(mktemp -dt)
150*b30d1939SAndy Fiddamantrap 'rm -rf $tmp' EXIT
151*b30d1939SAndy Fiddamanx=$($SHELL 2> /dev/null -ic '/bin/notfound; sleep .5 & sleep 1;jobs')
152*b30d1939SAndy Fiddaman[[ $x == *Done* ]] || err_exit 'SIGCHLD blocked after notfound'
153*b30d1939SAndy Fiddamanx=$($SHELL 2> /dev/null  -ic 'kill -0 12345678901234567876; sleep .5 & sleep 1;jobs')
154*b30d1939SAndy Fiddaman[[ $x == *Done* ]] || err_exit 'SIGCHLD blocked after error message'
155*b30d1939SAndy Fiddamanprint 'set -o monitor;sleep .5 & sleep 1;jobs' > $tmp/foobar
156*b30d1939SAndy Fiddamanchmod +x $tmp/foobar
157*b30d1939SAndy Fiddamanx=$($SHELL  -c "echo | $tmp/foobar")
158*b30d1939SAndy Fiddaman[[ $x == *Done* ]] || err_exit 'SIGCHLD blocked for script at end of pipeline'
159*b30d1939SAndy Fiddaman
160*b30d1939SAndy Fiddamanexit $((Errors<125?Errors:125))
161