diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Src/Modules/db_gdbm.c | 17 | ||||
-rw-r--r-- | Src/params.c | 27 |
3 files changed, 42 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog index 1fe592b07..ee6860c0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,12 @@ +2015-01-29 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 34430: Src/Modules/db_gdbm.c, Src/params.c: various bug fixes + and safety additions for gdbm tied hashes. + 2015-01-28 Barton E. Schaefer <schaefer@zsh.org> * unposted: Doc/Zsh/builtins.yo: fix other typeset doc errors - + * 34421: Doc/Zsh/builtins.yo: clean up typeset documentation 2015-01-28 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp> diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index d75af980b..a6027deaf 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -105,7 +105,6 @@ static int bin_zuntie(char *nam, char **args, Options ops, UNUSED(int func)) { Param pm; - GDBM_FILE dbf; char *pmname; int ret = 0; @@ -116,12 +115,18 @@ bin_zuntie(char *nam, char **args, Options ops, UNUSED(int func)) ret = 1; continue; } + if (pm->gsu.h != &gdbm_hash_gsu) { + zwarnnam(nam, "not a tied gdbm hash: %s", pmname); + ret = 1; + continue; + } - dbf = (GDBM_FILE)(pm->u.hash->tmpdata); - gdbm_close(dbf); - /* free(pm->u.hash->tmpdata); */ - pm->u.hash->tmpdata = NULL; - paramtab->removenode(paramtab, pm->node.nam); + queue_signals(); + if (unsetparam_pm(pm, 0, 1)) { + /* assume already reported */ + ret = 1; + } + unqueue_signals(); } return ret; diff --git a/Src/params.c b/Src/params.c index 64c78bd63..e8a90104c 100644 --- a/Src/params.c +++ b/Src/params.c @@ -927,7 +927,15 @@ shempty(void) { } -/* Create a simple special hash parameter. */ +/* + * Create a simple special hash parameter. + * + * This is for hashes added internally --- it's not possible to add + * special hashes from shell commands. It's currently used + * - by addparamdef() for special parameters in the zsh/parameter + * module + * - by ztie for special parameters tied to databases. + */ /**/ mod_export Param @@ -939,7 +947,22 @@ createspecialhash(char *name, GetNodeFunc get, ScanTabFunc scan, int flags) if (!(pm = createparam(name, PM_SPECIAL|PM_HASHED|flags))) return NULL; - pm->level = pm->old ? locallevel : 0; + /* + * If there's an old parameter, we'll put the new one at + * the current locallevel, so that the old parameter is + * exposed again after leaving the function. Otherwise, + * we'll leave it alone. Usually this means the parameter + * will stay in place until explicitly unloaded, however + * if the parameter was previously unset within a function + * we'll inherit the level of that function and follow the + * standard convention that the parameter remains local + * even if unset. + * + * These semantics are similar to those of a normal parameter set + * within a function without a local definition. + */ + if (pm->old) + pm->level = locallevel; pm->gsu.h = (flags & PM_READONLY) ? &stdhash_gsu : &nullsethash_gsu; pm->u.hash = ht = newhashtable(0, name, NULL); |