xref: /titanic_44/usr/src/lib/libshell/common/tests/coprocess.sh (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
1da2e3ebdSchin########################################################################
2da2e3ebdSchin#                                                                      #
3da2e3ebdSchin#               This software is part of the ast package               #
4*3e14f97fSRoger A. Faulkner#          Copyright (c) 1982-2010 AT&T Intellectual Property          #
5da2e3ebdSchin#                      and is licensed under the                       #
6da2e3ebdSchin#                  Common Public License, Version 1.0                  #
77c2fbfb3SApril Chin#                    by AT&T Intellectual Property                     #
8da2e3ebdSchin#                                                                      #
9da2e3ebdSchin#                A copy of the License is available at                 #
10da2e3ebdSchin#            http://www.opensource.org/licenses/cpl1.0.txt             #
11da2e3ebdSchin#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
12da2e3ebdSchin#                                                                      #
13da2e3ebdSchin#              Information and Software Systems Research               #
14da2e3ebdSchin#                            AT&T Research                             #
15da2e3ebdSchin#                           Florham Park NJ                            #
16da2e3ebdSchin#                                                                      #
17da2e3ebdSchin#                  David Korn <dgk@research.att.com>                   #
18da2e3ebdSchin#                                                                      #
19da2e3ebdSchin########################################################################
20da2e3ebdSchin# test the behavior of co-processes
21da2e3ebdSchinfunction err_exit
22da2e3ebdSchin{
23da2e3ebdSchin	print -u2 -n "\t"
24da2e3ebdSchin	print -u2 -r ${Command}[$1]: "${@:2}"
25da2e3ebdSchin	let Errors+=1
26da2e3ebdSchin}
27da2e3ebdSchinalias err_exit='err_exit $LINENO'
28da2e3ebdSchin
29da2e3ebdSchinCommand=${0##*/}
30da2e3ebdSchininteger Errors=0
31da2e3ebdSchin
3234f9b3eeSRoland Mainztmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
3334f9b3eeSRoland Mainztrap "cd /; rm -rf $tmp" EXIT
3434f9b3eeSRoland Mainz
35da2e3ebdSchinif	[[ -d /cygdrive ]]
36da2e3ebdSchinthen	err_exit cygwin detected - coprocess tests disabled - enable at the risk of wedging your system
37da2e3ebdSchin	exit $((Errors))
38da2e3ebdSchinfi
39da2e3ebdSchin
40da2e3ebdSchinfunction ping # id
41da2e3ebdSchin{
42da2e3ebdSchin	integer x=0
437c2fbfb3SApril Chin	while ((x++ < 5))
44da2e3ebdSchin	do	read -r
45da2e3ebdSchin		print -r "$1 $REPLY"
46da2e3ebdSchin	done
47da2e3ebdSchin}
48da2e3ebdSchin
49da2e3ebdSchincat |&
50da2e3ebdSchinprint -p "hello"
51da2e3ebdSchinread -p line
52da2e3ebdSchin[[ $line == hello ]] || err_exit 'coprocessing fails'
53da2e3ebdSchinexec 5>&p 6<&p
54da2e3ebdSchinprint -u5 'hello again' || err_exit 'write on u5 fails'
55da2e3ebdSchinread -u6 line
56da2e3ebdSchin[[ $line == 'hello again' ]] || err_exit 'coprocess after moving fds fails'
57da2e3ebdSchinexec 5<&- 6<&-
587c2fbfb3SApril Chinwait $!
59da2e3ebdSchin
60da2e3ebdSchinping three |&
61da2e3ebdSchinexec 3>&p
62da2e3ebdSchinping four |&
63da2e3ebdSchinexec 4>&p
64da2e3ebdSchinping pipe |&
65da2e3ebdSchin
66da2e3ebdSchininteger count
67da2e3ebdSchinfor i in three four pipe four pipe four three pipe pipe three pipe
68da2e3ebdSchindo	case $i in
69da2e3ebdSchin	three)	to=-u3;;
70da2e3ebdSchin	four)	to=-u4;;
71da2e3ebdSchin	pipe)	to=-p;;
72da2e3ebdSchin	esac
737c2fbfb3SApril Chin	(( count++ ))
74da2e3ebdSchin	print $to $i $count
75da2e3ebdSchindone
76da2e3ebdSchin
77da2e3ebdSchinwhile	((count > 0))
787c2fbfb3SApril Chindo	(( count-- ))
79da2e3ebdSchin	read -p
80da2e3ebdSchin	set -- $REPLY
81da2e3ebdSchin	if	[[ $1 != $2 ]]
827c2fbfb3SApril Chin	then	err_exit "$1 does not match $2"
83da2e3ebdSchin	fi
84da2e3ebdSchin	case $1 in
85da2e3ebdSchin	three)	;;
86da2e3ebdSchin	four)	;;
87da2e3ebdSchin	pipe)	;;
887c2fbfb3SApril Chin	*)	err_exit "unknown message +|$REPLY|+" ;;
89da2e3ebdSchin	esac
90da2e3ebdSchindone
917c2fbfb3SApril Chinkill $(jobs -p) 2>/dev/null
92da2e3ebdSchin
9334f9b3eeSRoland Mainzfile=$tmp/regress
94da2e3ebdSchincat > $file  <<\!
95da2e3ebdSchin/bin/cat |&
96da2e3ebdSchin!
97da2e3ebdSchinchmod +x $file
987c2fbfb3SApril Chinsleep 10 |&
99da2e3ebdSchin$file 2> /dev/null || err_exit "parent coprocess prevents script coprocess"
100da2e3ebdSchinexec 5<&p 6>&p
101da2e3ebdSchinexec 5<&- 6>&-
1027c2fbfb3SApril Chinkill $(jobs -p) 2>/dev/null
1037c2fbfb3SApril Chin
104da2e3ebdSchin${SHELL-ksh} |&
10534f9b3eeSRoland Mainzcop=$!
10634f9b3eeSRoland Mainzexp=Done
10734f9b3eeSRoland Mainzprint -p $'print hello | cat\nprint '$exp
108da2e3ebdSchinread -t 5 -p
109da2e3ebdSchinread -t 5 -p
11034f9b3eeSRoland Mainzgot=$REPLY
11134f9b3eeSRoland Mainzif	[[ $got != $exp ]]
11234f9b3eeSRoland Mainzthen	err_exit "${SHELL-ksh} coprocess io failed -- got '$got', expected '$exp'"
113da2e3ebdSchinfi
114da2e3ebdSchinexec 5<&p 6>&p
115da2e3ebdSchinexec 5<&- 6>&-
11634f9b3eeSRoland Mainz{ sleep 4; kill $cop; } 2>/dev/null &
11734f9b3eeSRoland Mainzspy=$!
11834f9b3eeSRoland Mainzif	wait $cop 2>/dev/null
11934f9b3eeSRoland Mainzthen	kill $spy 2>/dev/null
12034f9b3eeSRoland Mainzelse	err_exit "coprocess hung after 'exec 5<&p 6>&p; exec 5<&- 6>&-'"
12134f9b3eeSRoland Mainzfi
12234f9b3eeSRoland Mainzwait
1237c2fbfb3SApril Chin
124da2e3ebdSchin{
125da2e3ebdSchinecho line1 | grep 'line2'
126da2e3ebdSchinecho line2 | grep 'line1'
127da2e3ebdSchin} |&
1287c2fbfb3SApril ChinSECONDS=0 count=0
1297c2fbfb3SApril Chinwhile	read -p -t 10 line
1307c2fbfb3SApril Chindo	((count++))
131da2e3ebdSchindone
132da2e3ebdSchinif	(( SECONDS > 8 ))
1337c2fbfb3SApril Chinthen	err_exit "read -p hanging (SECONDS=$SECONDS count=$count)"
134da2e3ebdSchinfi
1357c2fbfb3SApril Chinwait $!
1367c2fbfb3SApril Chin
137da2e3ebdSchin( sleep 3 |& sleep 1 && kill $!; sleep 1; sleep 3 |& sleep 1 && kill $! ) ||
138da2e3ebdSchin	err_exit "coprocess cleanup not working correctly"
1397c2fbfb3SApril Chin{ : |& } 2>/dev/null ||
1407c2fbfb3SApril Chin	err_exit "subshell coprocess lingers in parent"
141da2e3ebdSchinwait $!
1427c2fbfb3SApril Chin
1437c2fbfb3SApril Chinunset N r e
1447c2fbfb3SApril Chininteger N=5
1457c2fbfb3SApril Chine=12345
1467c2fbfb3SApril Chin(
1477c2fbfb3SApril Chin	integer i
1487c2fbfb3SApril Chin	for ((i = 1; i <= N; i++))
1497c2fbfb3SApril Chin	do	print $i |&
1507c2fbfb3SApril Chin		read -p r
1517c2fbfb3SApril Chin		print -n $r
1527c2fbfb3SApril Chin		wait $!
1537c2fbfb3SApril Chin	done
1547c2fbfb3SApril Chin	print
1557c2fbfb3SApril Chin) 2>/dev/null | read -t 10 r
1567c2fbfb3SApril Chin[[ $r == $e ]] || err_exit "coprocess timing bug -- expected $e, got '$r'"
1577c2fbfb3SApril Chinr=
1587c2fbfb3SApril Chin(
1597c2fbfb3SApril Chin	integer i
1607c2fbfb3SApril Chin	for ((i = 1; i <= N; i++))
1617c2fbfb3SApril Chin	do	print $i |&
1627c2fbfb3SApril Chin		sleep 0.01
1637c2fbfb3SApril Chin		r=$r$(cat <&p)
1647c2fbfb3SApril Chin		wait $!
1657c2fbfb3SApril Chin	done
1667c2fbfb3SApril Chin	print $r
1677c2fbfb3SApril Chin) 2>/dev/null | read -t 10 r
1687c2fbfb3SApril Chin[[ $r == $e ]] || err_exit "coprocess command substitution bug -- expected $e, got '$r'"
1697c2fbfb3SApril Chin
170da2e3ebdSchin(
171da2e3ebdSchin	/bin/cat |&
1727c2fbfb3SApril Chin	sleep 0.01
173da2e3ebdSchin	exec 6>&p
174da2e3ebdSchin	print -u6 ok
175da2e3ebdSchin	exec 6>&-
176da2e3ebdSchin	sleep 1
177da2e3ebdSchin	kill $! 2> /dev/null
178da2e3ebdSchin) && err_exit 'coprocess with subshell would hang'
179da2e3ebdSchinfor sig in IOT ABRT
180da2e3ebdSchindo	if	( trap - $sig ) 2> /dev/null
1817c2fbfb3SApril Chin	then	if	[[ $( { sig=$sig $SHELL  2> /dev/null <<- '++EOF++'
182da2e3ebdSchin				cat |&
183da2e3ebdSchin				pid=$!
184da2e3ebdSchin				trap "print TRAP" $sig
185da2e3ebdSchin				(
186da2e3ebdSchin					sleep 2
187da2e3ebdSchin					kill -$sig $$
188da2e3ebdSchin					sleep 2
189da2e3ebdSchin					kill -$sig $$
190da2e3ebdSchin					kill $pid
1917c2fbfb3SApril Chin					sleep 2
1927c2fbfb3SApril Chin					kill $$
1937c2fbfb3SApril Chin				) &
194da2e3ebdSchin				read -p
1957c2fbfb3SApril Chin			++EOF++
1967c2fbfb3SApril Chin			} ) != $'TRAP\nTRAP' ]] 2> /dev/null
197da2e3ebdSchin		then	err_exit 'traps when reading from coprocess not working'
198da2e3ebdSchin		fi
199da2e3ebdSchin		break
200da2e3ebdSchin	fi
201da2e3ebdSchindone
202da2e3ebdSchin
203da2e3ebdSchintrap 'sleep_pid=; kill $pid; err_exit "coprocess 1 hung"' TERM
204da2e3ebdSchin{ sleep 5; kill $$; } &
205da2e3ebdSchinsleep_pid=$!
206da2e3ebdSchinbuiltin cat
207da2e3ebdSchincat |&
208da2e3ebdSchinpid=$!
209da2e3ebdSchinexec 5<&p 6>&p
210da2e3ebdSchinprint -u6 hi; read -u5
211da2e3ebdSchin[[ $REPLY == hi ]] || err_exit 'REPLY is $REPLY not hi'
212da2e3ebdSchinexec 6>&-
213da2e3ebdSchinwait $pid
214da2e3ebdSchintrap - TERM
215da2e3ebdSchin[[ $sleep_pid ]] && kill $sleep_pid
216da2e3ebdSchin
217da2e3ebdSchintrap 'sleep_pid=; kill $pid; err_exit "coprocess 2 hung"' TERM
218da2e3ebdSchin{ sleep 5; kill $$; } &
219da2e3ebdSchinsleep_pid=$!
220da2e3ebdSchincat |&
221da2e3ebdSchinpid=$!
222da2e3ebdSchinprint foo >&p 2> /dev/null || err_exit 'first write of foo to coprocess failed'
223da2e3ebdSchinprint foo >&p 2> /dev/null || err_exit 'second write of foo to coprocess failed'
224da2e3ebdSchinkill $pid
225da2e3ebdSchinwait $pid 2> /dev/null
226da2e3ebdSchintrap - TERM
227da2e3ebdSchin[[ $sleep_pid ]] && kill $sleep_pid
228da2e3ebdSchin
229da2e3ebdSchintrap 'sleep_pid=; kill $pid; err_exit "coprocess 3 hung"' TERM
230da2e3ebdSchin{ sleep 5; kill $$; } &
231da2e3ebdSchinsleep_pid=$!
232da2e3ebdSchincat |&
233da2e3ebdSchinpid=$!
234da2e3ebdSchinprint -p foo
235da2e3ebdSchinprint -p bar
236da2e3ebdSchinread <&p || err_exit 'first read from coprocess failed'
237da2e3ebdSchin[[ $REPLY == foo ]] || err_exit "first REPLY is $REPLY not foo"
238da2e3ebdSchinread <&p || err_exit 'second read from coprocess failed'
239da2e3ebdSchin[[ $REPLY == bar ]] || err_exit "second REPLY is $REPLY not bar"
240da2e3ebdSchinkill $pid
241da2e3ebdSchinwait $pid 2> /dev/null
242da2e3ebdSchintrap - TERM
243da2e3ebdSchin[[ $sleep_pid ]] && kill $sleep_pid
244da2e3ebdSchin
24534f9b3eeSRoland Mainzexp=ksh
24634f9b3eeSRoland Mainzgot=$(print -r $'#00315
24734f9b3eeSRoland MainzCOATTRIBUTES=\'label=make \'
24834f9b3eeSRoland Mainz# @(#)$Id: libcoshell (AT&T Research) 2008-04-28 $
24934f9b3eeSRoland Mainz_COSHELL_msgfd=5
25034f9b3eeSRoland Mainz{ { (eval \'function fun { trap \":\" 0; return 1; }; trap \"exit 0\" 0; fun; exit 1\') && PATH= print -u$_COSHELL_msgfd ksh; } || { times && echo bsh >&$_COSHELL_msgfd; } || { echo osh >&$_COSHELL_msgfd; }; } >/dev/null 2>&1' | $SHELL 5>&1)
25134f9b3eeSRoland Mainz[[ $got == $exp ]] || err_exit "coshell(3) identification sequence failed -- expected '$exp', got '$got'"
25234f9b3eeSRoland Mainz
25334f9b3eeSRoland Mainzfunction cop
25434f9b3eeSRoland Mainz{
25534f9b3eeSRoland Mainz	read
25634f9b3eeSRoland Mainz	print ok
25734f9b3eeSRoland Mainz}
25834f9b3eeSRoland Mainz
25934f9b3eeSRoland Mainzexp=ok
26034f9b3eeSRoland Mainz
26134f9b3eeSRoland Mainzcop |&
26234f9b3eeSRoland Mainzpid=$!
26334f9b3eeSRoland Mainzif	print -p yo 2>/dev/null
26434f9b3eeSRoland Mainzthen	read -p got
26534f9b3eeSRoland Mainzelse	got='no coprocess'
26634f9b3eeSRoland Mainzfi
26734f9b3eeSRoland Mainz[[ $got == $exp ]] || err_exit "main coprocess main query failed -- expected $exp, got '$got'"
26834f9b3eeSRoland Mainzkill $pid 2>/dev/null
26934f9b3eeSRoland Mainzwait
27034f9b3eeSRoland Mainz
27134f9b3eeSRoland Mainzcop |&
27234f9b3eeSRoland Mainzpid=$!
27334f9b3eeSRoland Mainz(
27434f9b3eeSRoland Mainzif	print -p yo 2>/dev/null
27534f9b3eeSRoland Mainzthen	read -p got
27634f9b3eeSRoland Mainzelse	got='no coprocess'
27734f9b3eeSRoland Mainzfi
27834f9b3eeSRoland Mainz[[ $got == $exp ]] || err_exit "main coprocess subshell query failed -- expected $exp, got '$got'"
27934f9b3eeSRoland Mainz)
28034f9b3eeSRoland Mainzkill $pid 2>/dev/null
28134f9b3eeSRoland Mainzwait
28234f9b3eeSRoland Mainz
28334f9b3eeSRoland Mainzexp='no coprocess'
28434f9b3eeSRoland Mainz
28534f9b3eeSRoland Mainz(
28634f9b3eeSRoland Mainzcop |&
28734f9b3eeSRoland Mainzprint $! > $tmp/pid
28834f9b3eeSRoland Mainz)
28934f9b3eeSRoland Mainzpid=$(<$tmp/pid)
29034f9b3eeSRoland Mainzif	print -p yo 2>/dev/null
29134f9b3eeSRoland Mainzthen	read -p got
29234f9b3eeSRoland Mainzelse	got=$exp
29334f9b3eeSRoland Mainzfi
29434f9b3eeSRoland Mainz[[ $got == $exp ]] || err_exit "subshell coprocess main query failed -- expected $exp, got '$got'"
29534f9b3eeSRoland Mainzkill $pid 2>/dev/null
29634f9b3eeSRoland Mainzwait
29734f9b3eeSRoland Mainz
29834f9b3eeSRoland Mainz(
29934f9b3eeSRoland Mainzcop |&
30034f9b3eeSRoland Mainzprint $! > $tmp/pid
30134f9b3eeSRoland Mainz)
30234f9b3eeSRoland Mainzpid=$(<$tmp/pid)
30334f9b3eeSRoland Mainz(
30434f9b3eeSRoland Mainzif	print -p yo 2>/dev/null
30534f9b3eeSRoland Mainzthen	read -p got
30634f9b3eeSRoland Mainzelse	got=$exp
30734f9b3eeSRoland Mainzfi
30834f9b3eeSRoland Mainz[[ $got == $exp ]] || err_exit "subshell coprocess subshell query failed -- expected $exp, got '$got'"
30934f9b3eeSRoland Mainzkill $pid 2>/dev/null
31034f9b3eeSRoland Mainzwait
31134f9b3eeSRoland Mainz)
31234f9b3eeSRoland Mainz
313da2e3ebdSchinexit $((Errors))
314