diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2010-08-31 19:32:56 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2010-08-31 19:32:56 +0000 |
commit | 8bc64084a46c79be5659ef42c746a3b806816c7f (patch) | |
tree | 6276b954f096a73655ba746dfc3367b6534dca6f /Src/exec.c | |
parent | afc3a7c41201ee5c6ffddb17ebe9db616f2919a1 (diff) | |
download | zsh-8bc64084a46c79be5659ef42c746a3b806816c7f.tar.gz zsh-8bc64084a46c79be5659ef42c746a3b806816c7f.tar.xz zsh-8bc64084a46c79be5659ef42c746a3b806816c7f.zip |
28220 plus some comments: fix "HELLO=$HELLO shellfunc"
Diffstat (limited to 'Src/exec.c')
-rw-r--r-- | Src/exec.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/Src/exec.c b/Src/exec.c index 3ab4aa90b..e866639b9 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -3313,13 +3313,32 @@ save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p) while (wc_code(ac = *pc) == WC_ASSIGN) { s = ecrawstr(state->prog, pc + 1, NULL); if ((pm = (Param) paramtab->getnode(paramtab, s))) { + Param tpm; if (pm->env) delenv(pm); if (!(pm->node.flags & PM_SPECIAL)) { - paramtab->removenode(paramtab, s); + /* + * We used to remove ordinary parameters from the + * table, but that meant "HELLO=$HELLO shellfunc" + * failed because the expansion of $HELLO hasn't + * been done at this point. Instead, copy the + * parameter: in this case, we'll insert the + * copied parameter straight back into the parameter + * table so we wan't to be sure everything is + * properly set up and in permanent memory. + */ + tpm = (Param) zshcalloc(sizeof *tpm); + tpm->node.nam = ztrdup(pm->node.nam); + copyparam(tpm, pm, 0); + pm = tpm; } else if (!(pm->node.flags & PM_READONLY) && (unset(RESTRICTED) || !(pm->node.flags & PM_RESTRICTED))) { - Param tpm = (Param) hcalloc(sizeof *tpm); + /* + * In this case we're just saving parts of + * the parameter in a tempory, so use heap allocation + * and don't bother copying every detail. + */ + tpm = (Param) hcalloc(sizeof *tpm); tpm->node.nam = pm->node.nam; copyparam(tpm, pm, 1); pm = tpm; @@ -3383,8 +3402,9 @@ restore_params(LinkList restorelist, LinkList removelist) break; } pm = tpm; - } else + } else { paramtab->addnode(paramtab, pm->node.nam, pm); + } if ((pm->node.flags & PM_EXPORTED) && ((s = getsparam(pm->node.nam)))) addenv(pm, s); } |