diff --git a/NEWS b/NEWS index 14e58d54a..a97a53f0e 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,11 @@ For full details, see the git log at: Any uppercase BUG_* names are modernish shell bug IDs. +2020-06-09: + +- The 'unalias' builtin will now return a non-zero status if it tries + to remove a previously set alias that is not currently set. + 2020-06-08: - Fix an issue with the up arrow key in Emacs editing mode. diff --git a/src/cmd/ksh93/bltins/typeset.c b/src/cmd/ksh93/bltins/typeset.c index 99e7b0517..9b9c2fcbe 100644 --- a/src/cmd/ksh93/bltins/typeset.c +++ b/src/cmd/ksh93/bltins/typeset.c @@ -1161,11 +1161,13 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp) register const char *name; volatile int r; Dt_t *dp; - int nflag=0,all=0,isfun,jmpval; + int nflag=0,all=0,isalias=0,isfun,jmpval; struct checkpt buff; NOT_USED(argc); - if(troot==shp->alias_tree) + if(troot==shp->alias_tree) { + isalias = 1; name = sh_optunalias; + } else name = sh_optunset; while(r = optget(argv,name)) switch(r) @@ -1281,6 +1283,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp) if(shp->subshell) np=sh_assignok(np,0); } + if(!nv_isnull(np) || nv_size(np) || nv_isattr(np,~(NV_MINIMAL|NV_NOFREE))) _nv_unset(np,0); if(troot==shp->var_tree && shp->st.real_fun && (dp=shp->var_tree->walk) && dp==shp->st.real_fun->sdict) @@ -1298,6 +1301,13 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp) while((troottmp = troottmp->view) && (np = nv_search(name,troottmp,0)) && is_afunction(np)) nv_delete(np,troottmp,0); } + /* The alias has been unset by call to _nv_unset, remove it from the tree */ + else if(isalias) { + if(nv_isattr(np, NV_NOFREE)) + nv_delete(np,troot,NV_NOFREE); /* The alias is in read-only memory (shtab_aliases) */ + else + nv_delete(np,troot,0); + } #if 0 /* causes unsetting local variable to expose global */ else if(shp->var_tree==troot && shp->var_tree!=shp->var_base && nv_search((char*)np,shp->var_tree,HASH_BUCKET|HASH_NOSCOPE)) diff --git a/src/cmd/ksh93/tests/alias.sh b/src/cmd/ksh93/tests/alias.sh index 79dbe4ef2..642034eb9 100755 --- a/src/cmd/ksh93/tests/alias.sh +++ b/src/cmd/ksh93/tests/alias.sh @@ -103,6 +103,16 @@ fi ( alias :pr=print) 2> /dev/null || err_exit 'alias beginning with : fails' ( alias p:r=print) 2> /dev/null || err_exit 'alias with : in name fails' -unalias no_such_alias && err_exit 'unalias should return non-zero for unknown alias' +unalias no_such_alias && err_exit 'unalias should return non-zero for unknown alias' +# ====== +# Attempting to unalias a previously set alias twice should be an error +alias foo=bar +unalias foo +unalias foo && err_exit 'unalias should return non-zero when a previously set alias is unaliased twice' + +# Removing a predefined alias should work without an error from free(3) +$SHELL -c 'unalias history' 2> /dev/null || err_exit 'removing a predefined alias does not work' + +# ====== exit $((Errors<125?Errors:125))