181af778eSCasper H.S. Dik# 281af778eSCasper H.S. Dik# CDDL HEADER START 381af778eSCasper H.S. Dik# 481af778eSCasper H.S. Dik# The contents of this file are subject to the terms of the 581af778eSCasper H.S. Dik# Common Development and Distribution License (the "License"). 681af778eSCasper H.S. Dik# You may not use this file except in compliance with the License. 781af778eSCasper H.S. Dik# 881af778eSCasper H.S. Dik# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 981af778eSCasper H.S. Dik# or http://www.opensolaris.org/os/licensing. 1081af778eSCasper H.S. Dik# See the License for the specific language governing permissions 1181af778eSCasper H.S. Dik# and limitations under the License. 1281af778eSCasper H.S. Dik# 1381af778eSCasper H.S. Dik# When distributing Covered Code, include this CDDL HEADER in each 1481af778eSCasper H.S. Dik# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1581af778eSCasper H.S. Dik# If applicable, add the following below this CDDL HEADER, with the 1681af778eSCasper H.S. Dik# fields enclosed by brackets "[]" replaced with your own identifying 1781af778eSCasper H.S. Dik# information: Portions Copyright [yyyy] [name of copyright owner] 1881af778eSCasper H.S. Dik# 1981af778eSCasper H.S. Dik# CDDL HEADER END 2081af778eSCasper H.S. Dik# 2181af778eSCasper H.S. Dik 2281af778eSCasper H.S. Dik# 233e14f97fSRoger A. Faulkner# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 2481af778eSCasper H.S. Dik# 2581af778eSCasper H.S. Dik 2681af778eSCasper H.S. Dik# 2781af778eSCasper H.S. Dik# Test whether CR #6800929 ("snv_106 ksh93 update breaks Install(1M)") has been fixed. 28*b30d1939SAndy Fiddaman# 29*b30d1939SAndy Fiddaman# Quote from CR #6800929: 3081af778eSCasper H.S. Dik# ---- snip ---- 3181af778eSCasper H.S. Dik# so i just upgraded this morning from snv_105 to snv_106. now 3281af778eSCasper H.S. Dik# Install(1M) is hanging whenever i run it. i'm running it as follows: 3381af778eSCasper H.S. Dik# Install -o debug -k i86xpv -T domu-219:/tmp 34*b30d1939SAndy Fiddaman# 3581af778eSCasper H.S. Dik# and here's where it's hung: 3681af778eSCasper H.S. Dik# ---8<--- 37*b30d1939SAndy Fiddaman# Edward Pilatowicz <edward.pilatowicz@sun.com> 3834f9b3eeSRoland Mainz# $ pstack 204600 3981af778eSCasper H.S. Dik# 204600: /bin/ksh /opt/onbld/bin/Install -o debug -k i86xpv -T domu-219:/tmp 4081af778eSCasper H.S. Dik# fffffd7fff2e3d1a write (1, 4154c0, 64) 4181af778eSCasper H.S. Dik# fffffd7ffefdafc8 sfwr () + 2d0 4281af778eSCasper H.S. Dik# fffffd7ffefc0f6f _sfflsbuf () + 217 4381af778eSCasper H.S. Dik# fffffd7ffefcb9f7 sfsync () + 17f 4481af778eSCasper H.S. Dik# fffffd7ffefc5c58 _sfphead () + 188 4581af778eSCasper H.S. Dik# fffffd7ffefc5ef5 _sfpmove () + 55 4681af778eSCasper H.S. Dik# fffffd7ffefc2595 _sfmode () + 22d 4781af778eSCasper H.S. Dik# fffffd7ffefc5fb1 sfpool () + 99 4881af778eSCasper H.S. Dik# fffffd7fff15eb8e sh_exec () + 2f56 4981af778eSCasper H.S. Dik# fffffd7fff15f78c sh_exec () + 3b54 5081af778eSCasper H.S. Dik# fffffd7fff15d9c8 sh_exec () + 1d90 5181af778eSCasper H.S. Dik# fffffd7fff15788e sh_subshell () + 646 5281af778eSCasper H.S. Dik# fffffd7fff134562 comsubst () + 8a2 5381af778eSCasper H.S. Dik# fffffd7fff12f61f copyto () + bcf 5481af778eSCasper H.S. Dik# fffffd7fff12df79 sh_macexpand () + 1f1 5581af778eSCasper H.S. Dik# fffffd7fff1129f5 arg_expand () + a5 5681af778eSCasper H.S. Dik# fffffd7fff112812 sh_argbuild () + 9a 5781af778eSCasper H.S. Dik# fffffd7fff15dbe2 sh_exec () + 1faa 5881af778eSCasper H.S. Dik# fffffd7fff15d854 sh_exec () + 1c1c 5981af778eSCasper H.S. Dik# fffffd7fff0f22ef b_dot_cmd () + 507 6081af778eSCasper H.S. Dik# fffffd7fff161559 sh_funct () + 199 6181af778eSCasper H.S. Dik# fffffd7fff15ef35 sh_exec () + 32fd 6281af778eSCasper H.S. Dik# fffffd7fff136e86 exfile () + 786 6381af778eSCasper H.S. Dik# fffffd7fff136676 sh_main () + 7fe 6481af778eSCasper H.S. Dik# 0000000000400e72 main () + 52 6581af778eSCasper H.S. Dik# 0000000000400ccc ???? 6681af778eSCasper H.S. Dik# ---8<--- 67*b30d1939SAndy Fiddaman# 6881af778eSCasper H.S. Dik# there is only one place where Install(1M) invokes "uniq": 6981af778eSCasper H.S. Dik# set -- `grep "^CONF" $modlist | sort | uniq`; 70*b30d1939SAndy Fiddaman# 7181af778eSCasper H.S. Dik# as it turns out, i can easily reproduce this problem as follows: 7281af778eSCasper H.S. Dik# ---8<--- 7334f9b3eeSRoland Mainz# $ ksh93 7434f9b3eeSRoland Mainz# $ set -- `cat /etc/termcap | sort | uniq` 7581af778eSCasper H.S. Dik# <hang> 7681af778eSCasper H.S. Dik# ---8<--- 7781af778eSCasper H.S. Dik# ---- snip ---- 7881af778eSCasper H.S. Dik 7981af778eSCasper H.S. Dik 8034f9b3eeSRoland Mainz# test setup 8181af778eSCasper H.S. Dikfunction err_exit 8281af778eSCasper H.S. Dik{ 8381af778eSCasper H.S. Dik print -u2 -n "\t" 8481af778eSCasper H.S. Dik print -u2 -r ${Command}[$1]: "${@:2}" 853e14f97fSRoger A. Faulkner (( Errors < 127 && Errors++ )) 8681af778eSCasper H.S. Dik} 8781af778eSCasper H.S. Dikalias err_exit='err_exit $LINENO' 8881af778eSCasper H.S. Dik 8934f9b3eeSRoland Mainzset -o nounset 9034f9b3eeSRoland MainzCommand=${0##*/} 9181af778eSCasper H.S. Dikinteger Errors=0 9281af778eSCasper H.S. Dik 9334f9b3eeSRoland Mainz# common functions/variables 9434f9b3eeSRoland Mainzfunction isvalidpid 9534f9b3eeSRoland Mainz{ 9634f9b3eeSRoland Mainz kill -0 ${1} 2>/dev/null && return 0 9734f9b3eeSRoland Mainz return 1 9834f9b3eeSRoland Mainz} 9934f9b3eeSRoland Mainzinteger testfilesize i maxwait 10081af778eSCasper H.S. Diktypeset tmpfile 10134f9b3eeSRoland Mainzinteger testid 10234f9b3eeSRoland Mainz 10381af778eSCasper H.S. Dik 10481af778eSCasper H.S. Dik# test 1: run loop and check various temp filesizes 1053e14f97fSRoger A. Faulknertmpfile="$(mktemp -t "sun_solaris_cr_6800929_large_command_substitution_hang.${PPID}.$$.XXXXXX")" || err_exit "Cannot create temporary file." 10681af778eSCasper H.S. Dik 10734f9b3eeSRoland Mainzcompound -a testcases=( 10834f9b3eeSRoland Mainz # test 1a: Run test child for $(...) 10934f9b3eeSRoland Mainz # (note the pipe chain has to end in a builtin command, an external command may not trigger the bug) 11034f9b3eeSRoland Mainz ( name="test1a" cmd="builtin cat ; print -- \"\$(cat \"${tmpfile}\" | cat)\" ; true" ) 11134f9b3eeSRoland Mainz # test 1b: Same as test1a but uses ${... ; } instead if $(...) 11234f9b3eeSRoland Mainz ( name="test1b" cmd="builtin cat ; print -- \"\${ cat \"${tmpfile}\" | cat ; }\" ; true" ) 11334f9b3eeSRoland Mainz # test 1c: Same as test1a but does not use a pipe 11434f9b3eeSRoland Mainz ( name="test1c" cmd="builtin cat ; print -- \"\$(cat \"${tmpfile}\" ; true)\" ; true" ) 11534f9b3eeSRoland Mainz # test 1d: Same as test1a but does not use a pipe 11634f9b3eeSRoland Mainz ( name="test1d" cmd="builtin cat ; print -- \"\${ cat \"${tmpfile}\" ; true ; }\" ; true" ) 11734f9b3eeSRoland Mainz 11834f9b3eeSRoland Mainz # test 1e: Same as test1a but uses an external "cat" command 11934f9b3eeSRoland Mainz ( name="test1e" cmd="builtin -d cat /bin/cat ; print -- \"\$(cat \"${tmpfile}\" | cat)\" ; true" ) 12034f9b3eeSRoland Mainz # test 1f: Same as test1a but uses an external "cat" command 12134f9b3eeSRoland Mainz ( name="test1f" cmd="builtin -d cat /bin/cat ; print -- \"\${ cat \"${tmpfile}\" | cat ; }\" ; true" ) 12234f9b3eeSRoland Mainz # test 1g: Same as test1a but uses an external "cat" command 12334f9b3eeSRoland Mainz ( name="test1g" cmd="builtin -d cat /bin/cat ; print -- \"\$(cat \"${tmpfile}\" ; true)\" ; true" ) 12434f9b3eeSRoland Mainz # test 1h: Same as test1a but uses an external "cat" command 12534f9b3eeSRoland Mainz ( name="test1h" cmd="builtin -d cat /bin/cat ; print -- \"\${ cat \"${tmpfile}\" ; true ; }\" ; true" ) 12634f9b3eeSRoland Mainz) 12734f9b3eeSRoland Mainz 12834f9b3eeSRoland Mainzfor (( testfilesize=1*1024 ; testfilesize <= 1024*1024 ; testfilesize*=2 )) ; do 12981af778eSCasper H.S. Dik # Create temp file 13081af778eSCasper H.S. Dik { 13134f9b3eeSRoland Mainz for (( i=0 ; i < testfilesize ; i+=64 )) ; do 13234f9b3eeSRoland Mainz print "0123456789abcdef01234567890ABCDEF0123456789abcdef01234567890ABCDE" 13381af778eSCasper H.S. Dik done 13481af778eSCasper H.S. Dik } >"${tmpfile}" 13581af778eSCasper H.S. Dik 13681af778eSCasper H.S. Dik # wait up to log2(i) seconds for the child to terminate 13781af778eSCasper H.S. Dik # (this is 10 seconds for 1KB and 19 seconds for 512KB) 13834f9b3eeSRoland Mainz (( maxwait=log2(testfilesize) )) 139*b30d1939SAndy Fiddaman 14034f9b3eeSRoland Mainz for testid in "${!testcases[@]}" ; do 14134f9b3eeSRoland Mainz nameref currtst=testcases[testid] 14234f9b3eeSRoland Mainz ${SHELL} -o errexit -c "${currtst.cmd}" >"${tmpfile}.out" & 14334f9b3eeSRoland Mainz (( childpid=$! )) 14434f9b3eeSRoland Mainz 14534f9b3eeSRoland Mainz for (( i=0 ; i < maxwait ; i++ )) ; do 14634f9b3eeSRoland Mainz isvalidpid ${childpid} || break 14734f9b3eeSRoland Mainz sleep 0.25 14834f9b3eeSRoland Mainz done 14934f9b3eeSRoland Mainz 15034f9b3eeSRoland Mainz if isvalidpid ${childpid} ; then 15134f9b3eeSRoland Mainz err_exit "${currtst.name}: child (pid=${childpid}) still busy, filesize=${testfilesize}." 15234f9b3eeSRoland Mainz kill -KILL ${childpid} 2>/dev/null 15334f9b3eeSRoland Mainz fi 15434f9b3eeSRoland Mainz wait || err_exit "${currtst.name}: Child returned non-zero exit code." # wait for child (and/or avoid zombies/slime) 15534f9b3eeSRoland Mainz 15634f9b3eeSRoland Mainz # compare input/output 15734f9b3eeSRoland Mainz cmp -s "${tmpfile}" "${tmpfile}.out" || err_exit "${currtst.name}: ${tmpfile} and ${tmpfile}.out differ, filesize=${testfilesize}." 15834f9b3eeSRoland Mainz rm "${tmpfile}.out" 15981af778eSCasper H.S. Dik done 16081af778eSCasper H.S. Dik 16134f9b3eeSRoland Mainz # Cleanup 16281af778eSCasper H.S. Dik rm "${tmpfile}" 16381af778eSCasper H.S. Dikdone 16481af778eSCasper H.S. Dik 16581af778eSCasper H.S. Dik 16634f9b3eeSRoland Mainz# test 2a: Edward Pilatowicz <edward.pilatowicz@sun.com>'s Solaris-specific testcase 16734f9b3eeSRoland Mainz${SHELL} -o errexit -c 'builtin uniq ; set -- `cat /etc/termcap | sort | uniq` ; true' >/dev/null & 16881af778eSCasper H.S. Dik(( childpid=$! )) 16981af778eSCasper H.S. Diksleep 5 17034f9b3eeSRoland Mainzif isvalidpid ${childpid} ; then 17134f9b3eeSRoland Mainz err_exit "test2a: child (pid=${childpid}) still busy." 17281af778eSCasper H.S. Dik kill -KILL ${childpid} 2>/dev/null 17381af778eSCasper H.S. Dikfi 17434f9b3eeSRoland Mainzwait || err_exit "test2a: Child returned non-zero exit code." # wait for child (and/or avoid zombies/slime) 17534f9b3eeSRoland Mainz 17634f9b3eeSRoland Mainz 17734f9b3eeSRoland Mainz# test 2b: Same as test 2a but uses ${... ; } instead of $(...) 17834f9b3eeSRoland Mainz${SHELL} -o errexit -c 'builtin uniq ; set -- ${ cat /etc/termcap | sort | uniq ; } ; true' >/dev/null & 17934f9b3eeSRoland Mainz(( childpid=$! )) 18034f9b3eeSRoland Mainzsleep 5 18134f9b3eeSRoland Mainzif isvalidpid ${childpid} ; then 18234f9b3eeSRoland Mainz err_exit "test2b: child (pid=${childpid}) still busy." 18334f9b3eeSRoland Mainz kill -KILL ${childpid} 2>/dev/null 18434f9b3eeSRoland Mainzfi 18534f9b3eeSRoland Mainzwait || err_exit "test2b: Child returned non-zero exit code." # wait for child (and/or avoid zombies/slime) 18634f9b3eeSRoland Mainz 18734f9b3eeSRoland Mainz 18834f9b3eeSRoland Mainz# test 2c: Same as test 2a but makes sure that "uniq" is not a builtin 18934f9b3eeSRoland Mainz${SHELL} -o errexit -c 'builtin -d uniq /bin/uniq ; set -- `cat /etc/termcap | sort | uniq` ; true' >/dev/null & 19034f9b3eeSRoland Mainz(( childpid=$! )) 19134f9b3eeSRoland Mainzsleep 5 19234f9b3eeSRoland Mainzif isvalidpid ${childpid} ; then 19334f9b3eeSRoland Mainz err_exit "test2c: child (pid=${childpid}) still busy." 19434f9b3eeSRoland Mainz kill -KILL ${childpid} 2>/dev/null 19534f9b3eeSRoland Mainzfi 19634f9b3eeSRoland Mainzwait || err_exit "test2c: Child returned non-zero exit code." # wait for child (and/or avoid zombies/slime) 19734f9b3eeSRoland Mainz 19834f9b3eeSRoland Mainz 19934f9b3eeSRoland Mainz# test 2d: Same as test 2c but uses ${... ; } instead of $(...) 20034f9b3eeSRoland Mainz${SHELL} -o errexit -c 'builtin -d uniq /bin/uniq ; set -- ${ cat /etc/termcap | sort | uniq ; } ; true' >/dev/null & 20134f9b3eeSRoland Mainz(( childpid=$! )) 20234f9b3eeSRoland Mainzsleep 5 20334f9b3eeSRoland Mainzif isvalidpid ${childpid} ; then 20434f9b3eeSRoland Mainz err_exit "test2d: child (pid=${childpid}) still busy." 20534f9b3eeSRoland Mainz kill -KILL ${childpid} 2>/dev/null 20634f9b3eeSRoland Mainzfi 20734f9b3eeSRoland Mainzwait || err_exit "test2d: Child returned non-zero exit code." # wait for child (and/or avoid zombies/slime) 20834f9b3eeSRoland Mainz 20981af778eSCasper H.S. Dik 21081af778eSCasper H.S. Dik# tests done 21181af778eSCasper H.S. Dikexit $((Errors)) 212