1# 2# CDDL HEADER START 3# 4# The contents of this file are subject to the terms of the 5# Common Development and Distribution License (the "License"). 6# You may not use this file except in compliance with the License. 7# 8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9# or http://www.opensolaris.org/os/licensing. 10# See the License for the specific language governing permissions 11# and limitations under the License. 12# 13# When distributing Covered Code, include this CDDL HEADER in each 14# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15# If applicable, add the following below this CDDL HEADER, with the 16# fields enclosed by brackets "[]" replaced with your own identifying 17# information: Portions Copyright [yyyy] [name of copyright owner] 18# 19# CDDL HEADER END 20# 21 22# 23# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24# 25 26# 27# This test checks whether the return code of a child process 28# is reported properly. 29# 30# This was reported as CR #6887363 ("Korn shell 93 sometimes 31# mishandles return value of its child process"): 32# ------------ snip ------------ 33# Following construction sometimes ends with wrong return value. 34# 35# 56 echo $op | grep rand 2>&1 >/dev/null 36# 57 if [ $? = 0 ]; then 37# 58 randseq="rand${SEED}" 38# 59 else 39# 60 randseq="seq" 40# 61 fi 41# 42# Sometimes, the given result is "rand..." even when there is 43# no "rand" word in $op. This can be demonstrated with 44# TSufs/SnapShots/Func test case which excercises shown code 45# quite often. 46# 47# As it happens only sometimes, I suppose there is an 48# race-condition in handling return value from a child process. 49# ------------ snip ------------ 50# 51 52# test setup 53function err_exit 54{ 55 print -u2 -n "\t" 56 print -u2 -r ${Command}[$1]: "${@:2}" 57 (( Errors < 127 && Errors++ )) 58} 59alias err_exit='err_exit $LINENO' 60 61set -o nounset 62Command=${0##*/} 63integer Errors=0 64 65typeset ocwd 66typeset tmpdir 67typeset out 68 69# create temporary test directory 70ocwd="$PWD" 71tmpdir="$(mktemp -t -d "test_sun_solaris_cr_6887363_shell_sometimes_mishandles_return_value_of_its_child_process.XXXXXXXX")" || err_exit "Cannot create temporary directory" 72 73cd "${tmpdir}" || { err_exit "cd ${tmpdir} failed." ; exit $((Errors)) ; } 74 75 76# run tests 77 78# print test case from bug that ksh93 can read this script via stdin 79function cat_test 80{ 81cat <<EOF 82#!/bin/sh 83# 84# Test derived from Sun's SnapShots Functional Suite 85# 86 87export PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin 88 89# WARNING: make sure "expr" and "grep" are _external_ commands in this test 90 91# start test 92_pcnt=0 93 94PASS(){ 95 _pcnt=\`/usr/bin/expr \$_pcnt + 1\` 96 true 97} 98 99doblockstamper() { 100 output=\`/usr/bin/sleep .01\` 101 _status=\$? 102 103 PASS "Here I am" 104} 105 106lotsaFiles() { 107 OPS="read-seq read-rand syncread-seq syncread-seq" 108 echo \$OPS 109 for op in \$OPS; do 110 echo \$op 111 echo \$op | /usr/bin/grep rand 2>&1 >/dev/null 112 status=\$? 113 if [ \$status = 0 ]; then 114 randseq="rand" 115 phrase="read-rand" 116 else 117 randseq="seq" 118 phrase="read-seq" 119 fi 120 retcode=\$status 121 122 echo \$op | /usr/bin/grep sync 2>&1 >/dev/null 123 status=\$? 124 if [ \$status = 0 ]; then 125 syncasync="sync" 126 phrase="sync\$phrase" 127 else 128 syncasync="async" 129 fi 130 retcode=\${status}-\${retcode} 131 132 if [ "\$op" != "\$phrase" ]; then 133 echo "Bad mode: \$op != \$phrase (\$retcode)" 134 exit 2 135 fi 136 137 for sz in 1 2 3 4; do 138 for type in 1 2 3 4; do 139 PASS "Something" 140 doblockstamper & 141 done 142 wait # Let a few finish 143 done 144 done 145 146 wait # Make sure everyone got done 147 148 PASS "lotsafiles \$1 \$fill" 149} 150 151cycle=0 152while [ cycle -lt 24 ]; do 153 cycle=\`/usr/bin/expr \$cycle + 1\` 154 155 lotsaFiles write 156 lotsaFiles write 157 lotsaFiles write 158 159 lotsaFiles read 160 lotsaFiles read 161 lotsaFiles read 162 163 PASS "Cycle" 164done 165exit 0 166EOF 167} 168 169# FIXME: we reset the VMALLOC_OPTIONS (and the depreciated VMDEBUG (for now)) variable for the run to avoid 170# that the test may run for hours. This may require re-investigation why this happens. 171out="$(unset VMALLOC_OPTIONS VMDEBUG ; cat_test | ${SHELL} 2>&1)" || err_exit "Unexpected exit code $?" 172[[ "${out}" != "" ]] || err_exit "No output from test" 173 174# filter output and check it 175out2="$(/usr/bin/egrep -v '^((read-seq|read-rand|syncread-seq|syncread-seq)[[:space:][:blank:]]*)*$' <<<"${out}")" 176[[ "${out2}" == "" ]] || err_exit "Unexpected output '${out2}'" 177 178 179cd "${ocwd}" 180rmdir "${tmpdir}" || err_exit "Cannot remove temporary directory ${tmpdir}". 181 182# tests done 183exit $((Errors)) 184