1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Fix unsetting aliases in subshells

Aliases can now be correctly unset within subshell environments
(such as ( ... ), $(command substitutions), etc), as well as
non-subshell "shared" command substitutions (${ ...; }). Before,
attempts to unset aliases within these were silently ignored.

Prior discussion: https://github.com/att/ast/issues/108

Subshell alias trees are only referenced in a few places in the
code, *and* have always been broken, so this commit gets rid of the
whole notion of a subshell alias tree. Instead, there is now just
one flat alias tree, and subshells fork into a separate process
when aliases are set or unset within them. It is not really
conceivable that this could be a performance-sensitive operation,
or even a common one, so this is a clean fix with no downside.

src/cmd/ksh93/include/defs.h:
- Remove sh_subaliastree() definition.

src/cmd/ksh93/sh/subshell.c:
- Remove salias element (pointer to subshell alias tree) from
  subshell struct.
- Remove sh_subaliastree() function.
- sh_subshell(): Remove alias subshell tree cleanup.

src/cmd/ksh93/bltins/typeset.c:
- b_alias(): If in subshell, fork before setting alias.
- b_unalias(): If in subshell, fork before unsetting alias.
- unall(): Remove sh_subaliastree() call.

src/cmd/ksh93/sh/name.c:
- nv_open(): Remove sh_subaliastree() call.

src/cmd/ksh93/tests/subshell.sh:
- Add regression tests for unsetting or redefining aliases within
  subshells.

(cherry picked from commit 12a15605b9521a2564a6e657905705a060e89095)
This commit is contained in:
Martijn Dekker 2020-05-29 08:27:53 +01:00
parent 047cb3303c
commit ec888867fd
6 changed files with 36 additions and 32 deletions

View file

@ -652,5 +652,34 @@ v=$("$SHELL" -c "$(cat "$a")") && [[ $v == ok ]] || err_exit 'fail: more fun 2'
v=$("$SHELL" -c 'eval "$(cat "$1")"' x "$a") && [[ $v == ok ]] || err_exit "fail: more fun 3"
v=$("$SHELL" -c '. "$1"' x "$a") && [[ $v == ok ]] || err_exit "fail: more fun 4"
# ======
# Unsetting or redefining aliases within subshells
# ...alias can be unset in subshell
alias al="echo 'mainalias'"
(unalias al; alias al >/dev/null) && err_exit 'alias fails to be unset in subshell'
v=$(unalias al; alias al >/dev/null) && err_exit 'alias fails to be unset in comsub'
[[ $(eval 'al') == 'mainalias' ]] || err_exit 'main alias fails to survive unset in subshell(s)'
v=${ eval 'al'; unalias al 2>&1; } && [[ $v == 'mainalias' ]] && ! alias al >/dev/null \
|| err_exit 'main shell alias wrongly survives unset within ${ ...; }'
# ...alias can be redefined in subshell
alias al="echo 'mainalias'"
(alias al='echo sub'; [[ $(eval 'al') == sub ]]) || err_exit 'alias fails to be redefined in subshell'
v=$(alias al='echo sub'; eval 'al') && [[ $v == sub ]] || err_exit 'alias fails to be redefined in comsub'
[[ $(eval 'al') == 'mainalias' ]] || err_exit 'main alias fails to survive redefinition in subshell(s)'
v=${ eval 'al'; alias al='echo subshare'; } && [[ $v == 'mainalias' && $(eval 'al') == subshare ]] \
|| err_exit 'alias redefinition fails to survive ${ ...; }'
# ======
exit $((Errors<125?Errors:125))