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