1*b30d1939SAndy Fiddaman#
2*b30d1939SAndy Fiddaman# CDDL HEADER START
3*b30d1939SAndy Fiddaman#
4*b30d1939SAndy Fiddaman# The contents of this file are subject to the terms of the
5*b30d1939SAndy Fiddaman# Common Development and Distribution License (the "License").
6*b30d1939SAndy Fiddaman# You may not use this file except in compliance with the License.
7*b30d1939SAndy Fiddaman#
8*b30d1939SAndy Fiddaman# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*b30d1939SAndy Fiddaman# or http://www.opensolaris.org/os/licensing.
10*b30d1939SAndy Fiddaman# See the License for the specific language governing permissions
11*b30d1939SAndy Fiddaman# and limitations under the License.
12*b30d1939SAndy Fiddaman#
13*b30d1939SAndy Fiddaman# When distributing Covered Code, include this CDDL HEADER in each
14*b30d1939SAndy Fiddaman# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*b30d1939SAndy Fiddaman# If applicable, add the following below this CDDL HEADER, with the
16*b30d1939SAndy Fiddaman# fields enclosed by brackets "[]" replaced with your own identifying
17*b30d1939SAndy Fiddaman# information: Portions Copyright [yyyy] [name of copyright owner]
18*b30d1939SAndy Fiddaman#
19*b30d1939SAndy Fiddaman# CDDL HEADER END
20*b30d1939SAndy Fiddaman#
21*b30d1939SAndy Fiddaman
22*b30d1939SAndy Fiddaman#
23*b30d1939SAndy Fiddaman# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24*b30d1939SAndy Fiddaman#
25*b30d1939SAndy Fiddaman
26*b30d1939SAndy Fiddaman#
27*b30d1939SAndy Fiddaman# This test checks whether the issue described in CR #6687139
28*b30d1939SAndy Fiddaman# ("command substitution, exec, and stdout redirection cause
29*b30d1939SAndy Fiddaman# allocation loop") has been fixed:
30*b30d1939SAndy Fiddaman# -- snip --
31*b30d1939SAndy Fiddaman# The following one-liner (including back ticks) causes ksh93 to spin
32*b30d1939SAndy Fiddaman# out of control consuming all memory at a *very* rapid pace:
33*b30d1939SAndy Fiddaman#
34*b30d1939SAndy Fiddaman#    `exec program > file`
35*b30d1939SAndy Fiddaman#
36*b30d1939SAndy Fiddaman#  If "file" is a real file (as opposed to /dev/null), the file will
37*b30d1939SAndy Fiddaman#  also grow without bound.  "program" need not exist, i.e.
38*b30d1939SAndy Fiddaman#
39*b30d1939SAndy Fiddaman#    `exec > file`
40*b30d1939SAndy Fiddaman#
41*b30d1939SAndy Fiddaman#  has the same result.  Using $() instead of `` also has the same
42*b30d1939SAndy Fiddaman#  effect.
43*b30d1939SAndy Fiddaman#
44*b30d1939SAndy Fiddaman#  This works fine under all other bourne-compatible shells.
45*b30d1939SAndy Fiddaman# -- snip --
46*b30d1939SAndy Fiddaman#
47*b30d1939SAndy Fiddaman
48*b30d1939SAndy Fiddaman# test setup
49*b30d1939SAndy Fiddamanfunction err_exit
50*b30d1939SAndy Fiddaman{
51*b30d1939SAndy Fiddaman	print -u2 -n "\t"
52*b30d1939SAndy Fiddaman	print -u2 -r ${Command}[$1]: "${@:2}"
53*b30d1939SAndy Fiddaman	(( Errors < 127 && Errors++ ))
54*b30d1939SAndy Fiddaman}
55*b30d1939SAndy Fiddamanalias err_exit='err_exit $LINENO'
56*b30d1939SAndy Fiddaman
57*b30d1939SAndy Fiddamanset -o nounset
58*b30d1939SAndy FiddamanCommand=${0##*/}
59*b30d1939SAndy Fiddamaninteger Errors=0
60*b30d1939SAndy Fiddaman
61*b30d1939SAndy Fiddamanfunction isvalidpid
62*b30d1939SAndy Fiddaman{
63*b30d1939SAndy Fiddaman	kill -0 ${1} 2>/dev/null && return 0
64*b30d1939SAndy Fiddaman	return 1
65*b30d1939SAndy Fiddaman}
66*b30d1939SAndy Fiddaman
67*b30d1939SAndy Fiddamaninteger childpid
68*b30d1939SAndy Fiddamantypeset testdir
69*b30d1939SAndy Fiddamaninteger childretval
70*b30d1939SAndy Fiddaman
71*b30d1939SAndy Fiddamantestdir="/tmp/sun_solaris_cr_6687139_pid$$_${PPID}"
72*b30d1939SAndy Fiddamanmkdir -p "${testdir}" || err_exit "Cannot create test dirctory"
73*b30d1939SAndy Fiddamancd "${testdir}" || { err_exit "Cannot cd to test dirctory" ; exit $Errors ; }
74*b30d1939SAndy Fiddaman
75*b30d1939SAndy Fiddaman##############################################################################
76*b30d1939SAndy Fiddaman##
77*b30d1939SAndy Fiddaman## test variant 1a: Use command substitution $( ... )
78*b30d1939SAndy Fiddaman##
79*b30d1939SAndy Fiddaman
80*b30d1939SAndy Fiddaman# Run testcase with "nice" to make sure a "runaway" process can
81*b30d1939SAndy Fiddaman# still be caught&&terminated by the current shell
82*b30d1939SAndy Fiddamannice -n 10 ${SHELL} -c 'touch z ; $(exec nosuchprogram_for_cr_6687139 > z) ; rm z' 2>/dev/null &
83*b30d1939SAndy Fiddamanchildpid=$!
84*b30d1939SAndy Fiddaman
85*b30d1939SAndy Fiddamansleep 5
86*b30d1939SAndy Fiddaman
87*b30d1939SAndy Fiddamanif isvalidpid ${childpid} ; then
88*b30d1939SAndy Fiddaman	# First _stop_, then log error since the child may eat up memory
89*b30d1939SAndy Fiddaman	# VERY VERY quickly
90*b30d1939SAndy Fiddaman	kill -STOP ${childpid}
91*b30d1939SAndy Fiddaman
92*b30d1939SAndy Fiddaman	err_exit "Child still active after 5 seconds (hang ?)"
93*b30d1939SAndy Fiddaman
94*b30d1939SAndy Fiddaman	# Get sample stack trace
95*b30d1939SAndy Fiddaman	pstack ${childpid}
96*b30d1939SAndy Fiddaman	kill -KILL ${childpid}
97*b30d1939SAndy Fiddamanfi
98*b30d1939SAndy Fiddaman
99*b30d1939SAndy Fiddaman# collect child's return status
100*b30d1939SAndy Fiddamanwait ${childpid}
101*b30d1939SAndy Fiddamanchildretval=$?
102*b30d1939SAndy Fiddaman
103*b30d1939SAndy Fiddaman(( childretval == 0 )) || err_exit "Child returned non-zero exit code ${childretval}."
104*b30d1939SAndy Fiddaman
105*b30d1939SAndy Fiddaman[[ ! -f "z" ]] || { rm "z" ; err_exit "Child did not remove test file" ; }
106*b30d1939SAndy Fiddaman
107*b30d1939SAndy Fiddaman
108*b30d1939SAndy Fiddaman##############################################################################
109*b30d1939SAndy Fiddaman##
110*b30d1939SAndy Fiddaman## test variant 1b: Same as test 1a but forces the shell to |fork()| for the
111*b30d1939SAndy Fiddaman## subshell
112*b30d1939SAndy Fiddaman##
113*b30d1939SAndy Fiddaman
114*b30d1939SAndy Fiddaman# Run testcase with "nice" to make sure a "runaway" process can
115*b30d1939SAndy Fiddaman# still be caught&&terminated by the current shell
116*b30d1939SAndy Fiddamannice -n 10 ${SHELL} -c 'touch z ; $(ulimit -c 0 ; exec nosuchprogram_for_cr_6687139 > z) ; rm z' 2>/dev/null &
117*b30d1939SAndy Fiddamanchildpid=$!
118*b30d1939SAndy Fiddaman
119*b30d1939SAndy Fiddamansleep 5
120*b30d1939SAndy Fiddaman
121*b30d1939SAndy Fiddamanif isvalidpid ${childpid} ; then
122*b30d1939SAndy Fiddaman	# First _stop_, then log error since the child may eat up memory
123*b30d1939SAndy Fiddaman	# VERY VERY quickly
124*b30d1939SAndy Fiddaman	kill -STOP ${childpid}
125*b30d1939SAndy Fiddaman
126*b30d1939SAndy Fiddaman	err_exit "Child still active after 5 seconds (hang ?)"
127*b30d1939SAndy Fiddaman
128*b30d1939SAndy Fiddaman	# Get sample stack trace
129*b30d1939SAndy Fiddaman	pstack ${childpid}
130*b30d1939SAndy Fiddaman	kill -KILL ${childpid}
131*b30d1939SAndy Fiddamanfi
132*b30d1939SAndy Fiddaman
133*b30d1939SAndy Fiddaman# collect child's return status
134*b30d1939SAndy Fiddamanwait ${childpid}
135*b30d1939SAndy Fiddamanchildretval=$?
136*b30d1939SAndy Fiddaman
137*b30d1939SAndy Fiddaman(( childretval == 0 )) || err_exit "Child returned non-zero exit code ${childretval}."
138*b30d1939SAndy Fiddaman
139*b30d1939SAndy Fiddaman[[ ! -f "z" ]] || { rm "z" ; err_exit "Child did not remove test file" ; }
140*b30d1939SAndy Fiddaman
141*b30d1939SAndy Fiddaman
142*b30d1939SAndy Fiddaman##############################################################################
143*b30d1939SAndy Fiddaman##
144*b30d1939SAndy Fiddaman## test variant 2a: Use plain subshell ( ... )
145*b30d1939SAndy Fiddaman##
146*b30d1939SAndy Fiddaman
147*b30d1939SAndy Fiddaman# Run testcase with "nice" to make sure a "runaway" process can
148*b30d1939SAndy Fiddaman# still be caught&&terminated by the current shell
149*b30d1939SAndy Fiddamannice -n 10 ${SHELL} -c 'touch z ; (exec nosuchprogram_for_cr_6687139 > z) ; rm z' 2>/dev/null &
150*b30d1939SAndy Fiddamanchildpid=$!
151*b30d1939SAndy Fiddaman
152*b30d1939SAndy Fiddamansleep 5
153*b30d1939SAndy Fiddaman
154*b30d1939SAndy Fiddamanif isvalidpid ${childpid} ; then
155*b30d1939SAndy Fiddaman	# First _stop_, then log error since the child may eat up memory
156*b30d1939SAndy Fiddaman	# VERY VERY quickly
157*b30d1939SAndy Fiddaman	kill -STOP ${childpid}
158*b30d1939SAndy Fiddaman
159*b30d1939SAndy Fiddaman	err_exit "Child still active after 5 seconds (hang ?)"
160*b30d1939SAndy Fiddaman
161*b30d1939SAndy Fiddaman	# Get sample stack trace
162*b30d1939SAndy Fiddaman	pstack ${childpid}
163*b30d1939SAndy Fiddaman	kill -KILL ${childpid}
164*b30d1939SAndy Fiddamanfi
165*b30d1939SAndy Fiddaman
166*b30d1939SAndy Fiddaman# collect child's return status
167*b30d1939SAndy Fiddamanwait ${childpid}
168*b30d1939SAndy Fiddamanchildretval=$?
169*b30d1939SAndy Fiddaman
170*b30d1939SAndy Fiddaman(( childretval == 0 )) || err_exit "Child returned non-zero exit code ${childretval}."
171*b30d1939SAndy Fiddaman
172*b30d1939SAndy Fiddaman[[ ! -f "z" ]] || { rm "z" ; err_exit "Child did not remove test file" ; }
173*b30d1939SAndy Fiddaman
174*b30d1939SAndy Fiddaman
175*b30d1939SAndy Fiddaman##############################################################################
176*b30d1939SAndy Fiddaman##
177*b30d1939SAndy Fiddaman## test variant 2b: Same as test 2a but forces the shell to |fork()| for the
178*b30d1939SAndy Fiddaman## subshell
179*b30d1939SAndy Fiddaman##
180*b30d1939SAndy Fiddaman
181*b30d1939SAndy Fiddaman# Run testcase with "nice" to make sure a "runaway" process can
182*b30d1939SAndy Fiddaman# still be caught&&terminated by the current shell
183*b30d1939SAndy Fiddamannice -n 10 ${SHELL} -c 'touch z ; (ulimit -c 0 ; exec nosuchprogram_for_cr_6687139 > z) ; rm z' 2>/dev/null &
184*b30d1939SAndy Fiddamanchildpid=$!
185*b30d1939SAndy Fiddaman
186*b30d1939SAndy Fiddamansleep 5
187*b30d1939SAndy Fiddaman
188*b30d1939SAndy Fiddamanif isvalidpid ${childpid} ; then
189*b30d1939SAndy Fiddaman	# First _stop_, then log error since the child may eat up memory
190*b30d1939SAndy Fiddaman	# VERY VERY quickly
191*b30d1939SAndy Fiddaman	kill -STOP ${childpid}
192*b30d1939SAndy Fiddaman
193*b30d1939SAndy Fiddaman	err_exit "Child still active after 5 seconds (hang ?)"
194*b30d1939SAndy Fiddaman
195*b30d1939SAndy Fiddaman	# Get sample stack trace
196*b30d1939SAndy Fiddaman	pstack ${childpid}
197*b30d1939SAndy Fiddaman	kill -KILL ${childpid}
198*b30d1939SAndy Fiddamanfi
199*b30d1939SAndy Fiddaman
200*b30d1939SAndy Fiddaman# collect child's return status
201*b30d1939SAndy Fiddamanwait ${childpid}
202*b30d1939SAndy Fiddamanchildretval=$?
203*b30d1939SAndy Fiddaman
204*b30d1939SAndy Fiddaman(( childretval == 0 )) || err_exit "Child returned non-zero exit code ${childretval}."
205*b30d1939SAndy Fiddaman
206*b30d1939SAndy Fiddaman[[ ! -f "z" ]] || { rm "z" ; err_exit "Child did not remove test file" ; }
207*b30d1939SAndy Fiddaman
208*b30d1939SAndy Fiddaman# tests done, remove temporary test subdir
209*b30d1939SAndy Fiddamancd /tmp
210*b30d1939SAndy Fiddamanrmdir "${testdir}" || err_exit "Could not remove temporary test directory ${testdir}"
211*b30d1939SAndy Fiddaman
212*b30d1939SAndy Fiddaman
213*b30d1939SAndy Fiddaman# tests done
214*b30d1939SAndy Fiddamanexit $((Errors))
215