diff --git a/NEWS b/NEWS index bda9d6be7..b658dd7ca 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,9 @@ Any uppercase BUG_* names are modernish shell bug IDs. This now correctly lists your directory and then prints "ls executed", instead of printing "ls executed" twice. +- Fix a similar bug with aliases. These can now be correctly unset + in subshell environments. + 2020-05-21: - Fix truncating of files with the combined redirections '<>;file' and diff --git a/src/cmd/ksh93/bltins/typeset.c b/src/cmd/ksh93/bltins/typeset.c index aaaf0e7c5..7aa1e06fe 100644 --- a/src/cmd/ksh93/bltins/typeset.c +++ b/src/cmd/ksh93/bltins/typeset.c @@ -197,6 +197,8 @@ int b_alias(int argc,register char *argv[],Shbltin_t *context) troot = tdata.sh->track_tree; } } + if(context->shp->subshell && !context->shp->subshare) + sh_subfork(); return(setall(argv,flag,troot,&tdata)); } @@ -1142,6 +1144,8 @@ int b_set(int argc,register char *argv[],Shbltin_t *context) int b_unalias(int argc,register char *argv[],Shbltin_t *context) { Shell_t *shp = context->shp; + if(shp->subshell && !shp->subshare) + sh_subfork(); return(unall(argc,argv,shp->alias_tree,shp)); } @@ -1161,11 +1165,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp) struct checkpt buff; NOT_USED(argc); if(troot==shp->alias_tree) - { name = sh_optunalias; - if(shp->subshell) - troot = sh_subaliastree(0); - } else name = sh_optunset; while(r = optget(argv,name)) switch(r) diff --git a/src/cmd/ksh93/include/defs.h b/src/cmd/ksh93/include/defs.h index 4d50de459..049ddc593 100644 --- a/src/cmd/ksh93/include/defs.h +++ b/src/cmd/ksh93/include/defs.h @@ -423,7 +423,6 @@ extern void sh_printopts(Shopt_t,int,Shopt_t*); extern int sh_readline(Shell_t*,char**,volatile int,int,ssize_t,long); extern Sfio_t *sh_sfeval(char*[]); extern void sh_setmatch(Shell_t*,const char*,int,int,int[],int); -extern Dt_t *sh_subaliastree(int); extern void sh_scope(Shell_t*, struct argnod*, int); extern Namval_t *sh_scoped(Shell_t*, Namval_t*); extern Dt_t *sh_subfuntree(int); diff --git a/src/cmd/ksh93/sh/name.c b/src/cmd/ksh93/sh/name.c index b008dbdad..5a70c2503 100644 --- a/src/cmd/ksh93/sh/name.c +++ b/src/cmd/ksh93/sh/name.c @@ -1390,8 +1390,6 @@ Namval_t *nv_open(const char *name, Dt_t *root, int flags) msg = e_aliname; while((c= *(unsigned char*)cp++) && (c!='=') && (c!='/') && (c>=0x200 || !(c=sh_lexstates[ST_NORM][c]) || c==S_EPAT || c==S_COLON)); - if(shp->subshell && c=='=') - root = sh_subaliastree(1); if(c= *--cp) *cp = 0; np = nv_search(name, root, (flags&NV_NOADD)?0:NV_ADD); diff --git a/src/cmd/ksh93/sh/subshell.c b/src/cmd/ksh93/sh/subshell.c index 04840235a..1b7aea70c 100644 --- a/src/cmd/ksh93/sh/subshell.c +++ b/src/cmd/ksh93/sh/subshell.c @@ -71,7 +71,6 @@ static struct subshell Dt_t *var; /* variable table at time of subshell */ struct Link *svar; /* save shell variable table */ Dt_t *sfun; /* function scope for subshell */ - Dt_t *salias;/* alias scope for subshell */ Pathcomp_t *pathlist; /* for PATH variable */ #if (ERROR_VERSION >= 20030214L) struct Error_context_s *errcontext; @@ -375,24 +374,6 @@ static void nv_restore(struct subshell *sp) sp->shpwd=save; } -/* - * return pointer to alias tree - * create new one if in a subshell and one doesn't exist and create is non-zero - */ -Dt_t *sh_subaliastree(int create) -{ - register struct subshell *sp = subshell_data; - if(!sp || sp->shp->curenv==0) - return(sh.alias_tree); - if(!sp->salias && create) - { - sp->salias = dtopen(&_Nvdisc,Dtoset); - dtview(sp->salias,sp->shp->alias_tree); - sp->shp->alias_tree = sp->salias; - } - return(sp->salias); -} - /* * return pointer to function tree * create new one if in a subshell and one doesn't exist and create is non-zero @@ -710,12 +691,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) { int n; shp->options = sp->options; - if(sp->salias) - { - shp->alias_tree = dtview(sp->salias,0); - table_unset(sp->salias,0); - dtclose(sp->salias); - } if(sp->sfun) { shp->fun_tree = dtview(sp->sfun,0); diff --git a/src/cmd/ksh93/tests/subshell.sh b/src/cmd/ksh93/tests/subshell.sh index 9bcede4de..2b6881064 100755 --- a/src/cmd/ksh93/tests/subshell.sh +++ b/src/cmd/ksh93/tests/subshell.sh @@ -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))