diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/builtin.c | 4 | ||||
-rw-r--r-- | Src/hashtable.c | 3 | ||||
-rw-r--r-- | Src/signals.c | 29 |
3 files changed, 20 insertions, 16 deletions
diff --git a/Src/builtin.c b/Src/builtin.c index 6d9fcd493..79648561e 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2592,14 +2592,12 @@ bin_unhash(char *name, char **argv, char *ops, int func) /* Take arguments literally -- do not glob */ for (; *argv; argv++) { - int ne = noerrs; if ((hn = ht->removenode(ht, *argv))) { ht->freenode(hn); } else { zwarnnam(name, "no such hash table element: %s", *argv, 0); - returnval |= !noerrs; + returnval = 1; } - noerrs = ne; } return returnval; } diff --git a/Src/hashtable.c b/Src/hashtable.c index 3595c2721..19f23086b 100644 --- a/Src/hashtable.c +++ b/Src/hashtable.c @@ -787,8 +787,9 @@ static HashNode removeshfuncnode(HashTable ht, char *nam) { HashNode hn; + int signum; - if (!strncmp(nam, "TRAP", 4)) + if (!strncmp(nam, "TRAP", 4) && (signum = getsignum(nam +4)) != -1) hn = removetrap(getsignum(nam + 4)); else hn = removehashnode(shfunctab, nam); diff --git a/Src/signals.c b/Src/signals.c index 891ea1143..e93030002 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -644,7 +644,8 @@ struct savetrap { static LinkList savetraps; /* - * Save the current trap and unset it. + * Save the current trap by copying it. This does nothing to + * the existing value of sigtrapped or sigfuncs. */ static void @@ -660,15 +661,18 @@ dosavetrap(int sig, int level) * the new one yet. */ char func[20]; + Shfunc shf, newshf = NULL; sprintf(func, "TRAP%s", sigs[sig]); - /* We call removehashnode() directly because otherwise - * removeshfuncnode() would be called which in turn would - * call us again so that we would end up with a NULL pointer - * instead of the list for the trap. */ - st->list = removehashnode(shfunctab, func); + if ((shf = (Shfunc)shfunctab->getnode2(shfunctab, func))) { + /* Copy the node for saving */ + newshf = (Shfunc) zalloc(sizeof(*newshf)); + newshf->nam = ztrdup(shf->nam); + newshf->flags = shf->flags; + newshf->funcdef = dupeprog(shf->funcdef, 0); + } + st->list = newshf; } else { - st->list = sigfuncs[sig]; - sigfuncs[sig] = NULL; + st->list = sigfuncs[sig] ? dupeprog(sigfuncs[sig], 0) : NULL; } noerrs = !!st->list; if (!savetraps) @@ -774,10 +778,11 @@ removetrap(int sig) /* * At this point we free the appropriate structs. If we don't - * want that to happen (e.g. we are saving the trap), then - * either the function should already have been removed from shfunctab, - * or the entry in sigfuncs should have been set to NULL, and then - * we're laughing, in a sort of vague virtual sense. + * want that to happen then either the function should already have been + * removed from shfunctab, or the entry in sigfuncs should have been set + * to NULL. This is no longer necessary for saving traps as that + * copies the structures, so here we are remove the originals. + * That causes a little inefficiency, but a good deal more reliability. */ if (trapped & ZSIG_FUNC) { char func[20]; |