diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Src/Modules/db_gdbm.c | 26 |
2 files changed, 31 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog index 191d6a9e2..fc6264497 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2015-01-26 Peter Stephenson <p.stephenson@samsung.com> + + * 34402: Src/Modules/db_gdbm.c: make unsetting a tied gdbm + variable work and hence allow tied variables in nested scope. + Untying still doesn't uncover scope properly. + 2015-01-25 Barton E. Schaefer <schaefer@zsh.org> * 34399: Src/utils.c: fix polltty thinko from 34365 diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index f079094c0..d75af980b 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -43,6 +43,9 @@ static char *backtype = "db/gdbm"; static const struct gsu_scalar gdbm_gsu = { gdbmgetfn, gdbmsetfn, gdbmunsetfn }; +/**/ +static const struct gsu_hash gdbm_hash_gsu = +{ hashgetfn, hashsetfn, gdbmhashunsetfn }; static struct builtin bintab[] = { BUILTIN("ztie", 0, bin_ztie, 1, -1, 0, "d:f:", NULL), @@ -84,12 +87,14 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func)) return 1; } - if (!(tied_param = createspecialhash(pmname, &getgdbmnode, &scangdbmkeys, 0))) { + if (!(tied_param = createspecialhash(pmname, &getgdbmnode, &scangdbmkeys, + PM_REMOVABLE))) { zwarnnam(nam, "cannot create the requested parameter %s", pmname); gdbm_close(dbf); return 1; } + tied_param->gsu.h = &gdbm_hash_gsu; tied_param->u.hash->tmpdata = (void *)dbf; return 0; @@ -225,6 +230,25 @@ scangdbmkeys(HashTable ht, ScanFunc func, int flags) } +/**/ +static void +gdbmhashunsetfn(Param pm, UNUSED(int exp)) +{ + GDBM_FILE dbf = (GDBM_FILE)(pm->u.hash->tmpdata); + + if (!dbf) /* paranoia */ + return; + + gdbm_close(dbf); + pm->u.hash->tmpdata = NULL; + + /* hash table is now normal, so proceed normally... */ + pm->node.flags &= ~PM_SPECIAL; + pm->gsu.h = &stdhash_gsu; + pm->gsu.h->setfn(pm, NULL); + pm->node.flags |= PM_UNSET; +} + #else # error no gdbm #endif /* have gdbm */ |