mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix hang in comsubs
(rhbz#1062296) (re: 970069a6
)
The new command substitution mechanism imported in970069a6
from Red Hat patches introduced this bug: backtick-style command substitutions hang when processing about 117KiB of data or more. It is fixed by another Red Hat patch:642af4d6/f/ksh-20140415-hokaido.patch
It saves the value of the shp->comsub flag so that it is set to 2 (usually meaning new-style $(comsubs)) in two specific cases even when processing backtick comsubs. This stops the sh_subtmpfile() function in subshell.c from creating a /tmp file. However, I think that approach is quite ugly, so I'm taking a slightly different one that has the same effect. src/cmd/ksh93/include/defs.h, src/cmd/ksh93/sh/subshell.c: - Redefine sh_subtmpfile() to pass the comsub flag as an argument. (Remove the shp pointer argument, which is redundant; a pointer to the shell state can easily be obtained in the function.) src/cmd/ksh93/sh/xec.c: sh_exec(): - Apply the Red Hat fix by passing flag 2 to sh_subtmpfile(). src/cmd/ksh93/tests/subshell.sh: - Move regress test fromce68e1be
from basic.sh to here; this is the place for command substitution tests as they are subshells. - Add regress test for this bug. All other changed files: - Update sh_subtmpfile() calls to pass on the shp->comsub flag.
This commit is contained in:
parent
3654ee73c0
commit
4ce486a7a4
7 changed files with 42 additions and 30 deletions
|
@ -692,23 +692,5 @@ actual=$(exptest foo)
|
|||
[[ $actual == "$expect" ]] || err_exit 'Corruption of multibyte char following expansion of single-char name' \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# ======
|
||||
# Crash in job handling code when running backtick-style command substitutions (rhbz#825520)
|
||||
# The regression sometimes doesn't just crash, but freezes hard, so requires special handling.
|
||||
cat >$tmp/backtick_crash.ksh <<'EOF'
|
||||
binfalse=$(whence -p false) || exit
|
||||
for ((i=0; i<250; i++))
|
||||
do test -z `"$binfalse" | "$binfalse" | /dev/null/nothing`
|
||||
done
|
||||
EOF
|
||||
"$SHELL" -i "$tmp/backtick_crash.ksh" 2>/dev/null & # run test as bg job
|
||||
test_pid=$!
|
||||
(sleep 10; kill -s KILL "$test_pid" 2>/dev/null) & # another bg job to kill frozen test job
|
||||
sleep_pid=$!
|
||||
{ wait "$test_pid"; } 2>/dev/null # suppress any crash messages, which 'wait' would print
|
||||
e=$? # get job's exit status from 'wait'
|
||||
((!e)) || err_exit "backtick comsub crash/freeze (got status $e$( ((e>128)) && print -n / && kill -l "$e"))"
|
||||
kill "$sleep_pid" 2>/dev/null
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
|
@ -794,5 +794,32 @@ actual=$(export bincat binecho; "$SHELL" 2>&1 -c \
|
|||
[[ $actual == "$expect" ]] || err_exit 'Command substitution in pipeline fails (2)' \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# ======
|
||||
# Crash in job handling code when running backtick-style command substitutions (rhbz#825520)
|
||||
# The regression sometimes doesn't just crash, but freezes hard, so requires special handling.
|
||||
cat >$tmp/backtick_crash.ksh <<'EOF'
|
||||
binfalse=$(whence -p false) || exit
|
||||
for ((i=0; i<250; i++))
|
||||
do test -z `"$binfalse" | "$binfalse" | /dev/null/nothing`
|
||||
done
|
||||
EOF
|
||||
"$SHELL" -i "$tmp/backtick_crash.ksh" 2>/dev/null & # run test as bg job
|
||||
test_pid=$!
|
||||
(sleep 10; kill -s KILL "$test_pid" 2>/dev/null) & # another bg job to kill frozen test job
|
||||
sleep_pid=$!
|
||||
{ wait "$test_pid"; } 2>/dev/null # get job's exit status, suppressing signal messages
|
||||
((!(e = $?))) || err_exit "backtick comsub crash/freeze (got status $e$( ((e>128)) && print -n / && kill -l "$e"))"
|
||||
kill "$sleep_pid" 2>/dev/null
|
||||
|
||||
# ======
|
||||
# Backtick command substitution hangs when filling out pipe buffer (rhbz#1062296)
|
||||
"$SHELL" -c 'HANG=`dd if=/dev/zero bs=1k count=117 2>/dev/null`' &
|
||||
test_pid=$!
|
||||
(sleep 2; kill -s KILL "$test_pid" 2>/dev/null) &
|
||||
sleep_pid=$!
|
||||
{ wait "$test_pid"; } 2>/dev/null
|
||||
((!(e = $?))) || err_exit "backtick comsub hang (got status $e$( ((e>128)) && print -n / && kill -l "$e"))"
|
||||
kill "$sleep_pid" 2>/dev/null
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue