mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix command substitutions in here-docs (rhbz#994241, rhbz#1036802)
When ksh was compiled with SHOPT_SPAWN (the default), any command substitution embedded in a here-document returned an empty string. The bug was also present in 93u+ 2012-08-01 (although not in every case as some systems compile it without SHOPT_SPAWN). This fixes it by applying a slightly edited combination of two Red Hat patches (the second containing a fix for the first), which backport a new command substitution mechanism from the abandoned ksh 93v- beta version. The originals are:642af4d6/f/ksh-20120801-macro.patch
642af4d6/f/ksh-20120801-fd2lost.patch
src/cmd/ksh93/include/io.h: - The iopipe() function from xec.c is now needed in sh_subshell() (subshell.c), so rename it to sh_iounpipe() and declare it as an extern here. The 93v- beta did it as well. (The Red Hat patch did this without renaming it.) src/cmd/ksh93/sh/xec.c: - Backport new versions of iousepipe() and sh_iounpipe() from ksh 93v-. New 'type' flaggery is introduced to distinguish between different command substitution conditions. What all that means remains to be determined. - sh_exec(): I made one change to the Red Hat patch myself: if in a subshell and the type flags FAMP (for "ampersand" as in '&' as in background job) and TFORK are set, continue to call sh_subfork() to fork the subshell unconditionally, instead of only if we're in a command substitution connected to an unseekable file. Maybe the latter works for the 93v- code, but on 93u+(m) it causes a couple of regressions, which are fixed by my change: signal.sh[273]: subshell ignoring signal does not send signal to parent signal.sh[276]: subshell catching signal does not send signal to parent Details: https://github.com/ksh93/ksh/issues/104#issuecomment-696341902 src/cmd/ksh93/sh/macro.c, src/cmd/ksh93/sh/subshell.c: - Updates that go with those new functions. Fixes: https://github.com/ksh93/ksh/issues/104 Affects: https://github.com/ksh93/ksh/issues/124
This commit is contained in:
parent
0d3bedd67d
commit
970069a6fe
6 changed files with 111 additions and 30 deletions
|
@ -272,10 +272,22 @@ done < tst.got
|
|||
|
||||
if [[ ${SIG[USR1]} ]]
|
||||
then float s=$SECONDS
|
||||
[[ $(LC_ALL=C $SHELL -c 'trap "print SIGUSR1 ; exit 0" USR1; (trap "" USR1 ; exec kill -USR1 $$ & sleep .5); print done') == SIGUSR1 ]] || err_exit 'subshell ignoring signal does not send signal to parent'
|
||||
exp=SIGUSR1
|
||||
got=$(LC_ALL=C $SHELL -c '
|
||||
trap "print SIGUSR1 ; exit 0" USR1
|
||||
(trap "" USR1 ; exec kill -USR1 $$ & sleep .5)
|
||||
print done')
|
||||
[[ $got == "$exp" ]] || err_exit 'subshell ignoring signal does not send signal to parent' \
|
||||
"(expected '$exp', got '$got')"
|
||||
(( (SECONDS-s) < .4 )) && err_exit 'parent does not wait for child to complete before handling signal'
|
||||
((s = SECONDS))
|
||||
[[ $(LC_ALL=C $SHELL -c 'trap "print SIGUSR1 ; exit 0" USR1; (trap "exit" USR1 ; exec kill -USR1 $$ & sleep .5); print done') == SIGUSR1 ]] || err_exit 'subshell catching signal does not send signal to parent'
|
||||
exp=SIGUSR1
|
||||
got=$(LC_ALL=C $SHELL -c '
|
||||
trap "print SIGUSR1 ; exit 0" USR1
|
||||
(trap "exit" USR1 ; exec kill -USR1 $$ & sleep .5)
|
||||
print done')
|
||||
[[ $got == "$exp" ]] || err_exit 'subshell catching signal does not send signal to parent' \
|
||||
"(expected '$exp', got '$got')"
|
||||
(( SECONDS-s < .4 )) && err_exit 'parent completes early'
|
||||
fi
|
||||
|
||||
|
|
|
@ -759,5 +759,40 @@ SHELL=$SHELL "$SHELL" -c '
|
|||
' | awk '/^DEBUG/ { pid[NR] = $2; } END { exit !(pid[1] == pid[2] && pid[2] == pid[3]); }' \
|
||||
|| err_exit "setting PATH to readonly in subshell triggers an erroneous fork"
|
||||
|
||||
# ======'
|
||||
# Test command substitution with external command in here-document
|
||||
# https://github.com/ksh93/ksh/issues/104
|
||||
expect=$'/dev/null\n/dev/null'
|
||||
actual=$(
|
||||
cat <<-EOF
|
||||
$(ls /dev/null)
|
||||
`ls /dev/null`
|
||||
EOF
|
||||
)
|
||||
[[ $actual == "$expect" ]] || err_exit 'Command substitution in here-document fails' \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# ...and in pipeline (rhbz#994251)
|
||||
expect=/dev/null
|
||||
actual=$(cat /dev/null | "$binecho" `ls /dev/null`)
|
||||
[[ $actual == "$expect" ]] || err_exit 'Command substitution in pipeline fails (1)' \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# ...and in pipeline again (rhbz#1036802: standard error was misdirected)
|
||||
expect=$'END2\naaa\nEND1\nEND3'
|
||||
actual=$(export bincat binecho; "$SHELL" 2>&1 -c \
|
||||
'function foo
|
||||
{
|
||||
"$binecho" hello >/dev/null 2>&1
|
||||
"$binecho" aaa | "$bincat"
|
||||
echo END1
|
||||
echo END2 >&2
|
||||
}
|
||||
echo "$(foo)" >&2
|
||||
echo END3 >&2
|
||||
exit')
|
||||
[[ $actual == "$expect" ]] || err_exit 'Command substitution in pipeline fails (2)' \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue