xref: /titanic_41/usr/src/lib/libshell/common/tests/coprocess.sh (revision 9a0e82381c494d655823a54fc713a8c2a571131c)
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########################################################################
20# test the behavior of co-processes
21function err_exit
22{
23	print -u2 -n "\t"
24	print -u2 -r ${Command}[$1]: "${@:2}"
25	let Errors+=1
26}
27alias err_exit='err_exit $LINENO'
28
29Command=${0##*/}
30integer Errors=0
31
32if	[[ -d /cygdrive ]]
33then	err_exit cygwin detected - coprocess tests disabled - enable at the risk of wedging your system
34	exit $((Errors))
35fi
36
37function ping # id
38{
39	integer x=0
40	while ((x++ < 5))
41	do	read -r
42		print -r "$1 $REPLY"
43	done
44}
45
46cat |&
47print -p "hello"
48read -p line
49[[ $line == hello ]] || err_exit 'coprocessing fails'
50exec 5>&p 6<&p
51print -u5 'hello again' || err_exit 'write on u5 fails'
52read -u6 line
53[[ $line == 'hello again' ]] || err_exit 'coprocess after moving fds fails'
54exec 5<&- 6<&-
55wait $!
56
57ping three |&
58exec 3>&p
59ping four |&
60exec 4>&p
61ping pipe |&
62
63integer count
64for i in three four pipe four pipe four three pipe pipe three pipe
65do	case $i in
66	three)	to=-u3;;
67	four)	to=-u4;;
68	pipe)	to=-p;;
69	esac
70	(( count++ ))
71	print $to $i $count
72done
73
74while	((count > 0))
75do	(( count-- ))
76	read -p
77	set -- $REPLY
78	if	[[ $1 != $2 ]]
79	then	err_exit "$1 does not match $2"
80	fi
81	case $1 in
82	three)	;;
83	four)	;;
84	pipe)	;;
85	*)	err_exit "unknown message +|$REPLY|+" ;;
86	esac
87done
88kill $(jobs -p) 2>/dev/null
89
90file=/tmp/regress$$
91trap "rm -f $file" EXIT
92cat > $file  <<\!
93/bin/cat |&
94!
95chmod +x $file
96sleep 10 |&
97$file 2> /dev/null || err_exit "parent coprocess prevents script coprocess"
98exec 5<&p 6>&p
99exec 5<&- 6>&-
100kill $(jobs -p) 2>/dev/null
101
102${SHELL-ksh} |&
103print -p  $'print hello | cat\nprint Done'
104read -t 5 -p
105read -t 5 -p
106if	[[ $REPLY != Done ]]
107then	err_exit "${SHELL-ksh} coprocess not working"
108fi
109exec 5<&p 6>&p
110exec 5<&- 6>&-
111wait $!
112
113{
114echo line1 | grep 'line2'
115echo line2 | grep 'line1'
116} |&
117SECONDS=0 count=0
118while	read -p -t 10 line
119do	((count++))
120done
121if	(( SECONDS > 8 ))
122then	err_exit "read -p hanging (SECONDS=$SECONDS count=$count)"
123fi
124wait $!
125
126( sleep 3 |& sleep 1 && kill $!; sleep 1; sleep 3 |& sleep 1 && kill $! ) ||
127	err_exit "coprocess cleanup not working correctly"
128{ : |& } 2>/dev/null ||
129	err_exit "subshell coprocess lingers in parent"
130wait $!
131
132unset N r e
133integer N=5
134e=12345
135(
136	integer i
137	for ((i = 1; i <= N; i++))
138	do	print $i |&
139		read -p r
140		print -n $r
141		wait $!
142	done
143	print
144) 2>/dev/null | read -t 10 r
145[[ $r == $e ]] || err_exit "coprocess timing bug -- expected $e, got '$r'"
146r=
147(
148	integer i
149	for ((i = 1; i <= N; i++))
150	do	print $i |&
151		sleep 0.01
152		r=$r$(cat <&p)
153		wait $!
154	done
155	print $r
156) 2>/dev/null | read -t 10 r
157[[ $r == $e ]] || err_exit "coprocess command substitution bug -- expected $e, got '$r'"
158
159(
160	/bin/cat |&
161	sleep 0.01
162	exec 6>&p
163	print -u6 ok
164	exec 6>&-
165	sleep 1
166	kill $! 2> /dev/null
167) && err_exit 'coprocess with subshell would hang'
168for sig in IOT ABRT
169do	if	( trap - $sig ) 2> /dev/null
170	then	if	[[ $( { sig=$sig $SHELL  2> /dev/null <<- '++EOF++'
171				cat |&
172				pid=$!
173				trap "print TRAP" $sig
174				(
175					sleep 2
176					kill -$sig $$
177					sleep 2
178					kill -$sig $$
179					kill $pid
180					sleep 2
181					kill  $$
182				) &
183				read -p
184			++EOF++
185			} ) != $'TRAP\nTRAP' ]] 2> /dev/null
186		then	err_exit 'traps when reading from coprocess not working'
187		fi
188		break
189	fi
190done
191
192trap 'sleep_pid=; kill $pid; err_exit "coprocess 1 hung"' TERM
193{ sleep 5; kill $$; } &
194sleep_pid=$!
195builtin cat
196cat |&
197pid=$!
198exec 5<&p 6>&p
199print -u6 hi; read -u5
200[[ $REPLY == hi ]] || err_exit 'REPLY is $REPLY not hi'
201exec 6>&-
202wait $pid
203trap - TERM
204[[ $sleep_pid ]] && kill $sleep_pid
205
206trap 'sleep_pid=; kill $pid; err_exit "coprocess 2 hung"' TERM
207{ sleep 5; kill $$; } &
208sleep_pid=$!
209cat |&
210pid=$!
211print foo >&p 2> /dev/null || err_exit 'first write of foo to coprocess failed'
212print foo >&p 2> /dev/null || err_exit 'second write of foo to coprocess failed'
213kill $pid
214wait $pid 2> /dev/null
215trap - TERM
216[[ $sleep_pid ]] && kill $sleep_pid
217
218trap 'sleep_pid=; kill $pid; err_exit "coprocess 3 hung"' TERM
219{ sleep 5; kill $$; } &
220sleep_pid=$!
221cat |&
222pid=$!
223print -p foo
224print -p bar
225read <&p || err_exit 'first read from coprocess failed'
226[[ $REPLY == foo ]] || err_exit "first REPLY is $REPLY not foo"
227read <&p || err_exit 'second read from coprocess failed'
228[[ $REPLY == bar ]] || err_exit "second REPLY is $REPLY not bar"
229kill $pid
230wait $pid 2> /dev/null
231trap - TERM
232[[ $sleep_pid ]] && kill $sleep_pid
233
234exit $((Errors))
235