about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Src/builtin.c4
-rw-r--r--Src/hashtable.c15
-rw-r--r--Src/signals.c22
4 files changed, 32 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 706b715cb..827687d4c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2000-04-28  Bart Schaefer  <schaefer@zsh.org>
+
+	* 11015: Src/builtin.c, Src/hashtable.c, Src/signals.c:
+	`unfunction TRAPxxx' now works with localtraps in effect.
+
 2000-04-28  Peter Stephenson  <pws@cambridgesiliconradio.com>
 
 	* pws: 11013: Completion/Core/compinstall: more breaks and
diff --git a/Src/builtin.c b/Src/builtin.c
index 79648561e..6d9fcd493 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2592,12 +2592,14 @@ 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 = 1;
+	    returnval |= !noerrs;
 	}
+	noerrs = ne;
     }
     return returnval;
 }
diff --git a/Src/hashtable.c b/Src/hashtable.c
index b4c0a573b..3595c2721 100644
--- a/Src/hashtable.c
+++ b/Src/hashtable.c
@@ -788,12 +788,12 @@ removeshfuncnode(HashTable ht, char *nam)
 {
     HashNode hn;
 
-    if ((hn = removehashnode(shfunctab, nam))) {
-	if (!strncmp(hn->nam, "TRAP", 4))
-	    unsettrap(getsignum(hn->nam + 4));
-	return hn;
-    } else
-	return NULL;
+    if (!strncmp(nam, "TRAP", 4))
+	hn = removetrap(getsignum(nam + 4));
+    else
+	hn = removehashnode(shfunctab, nam);
+
+    return hn;
 }
 
 /* Disable an entry in the shell function hash table.    *
@@ -822,11 +822,10 @@ static void
 enableshfuncnode(HashNode hn, int flags)
 {
     Shfunc shf = (Shfunc) hn;
-    int signum;
 
     shf->flags &= ~DISABLED;
     if (!strncmp(shf->nam, "TRAP", 4)) {
-	signum = getsignum(shf->nam + 4);
+	int signum = getsignum(shf->nam + 4);
 	if (signum != -1) {
 	    settrap(signum, shf->funcdef);
 	    sigtrapped[signum] |= ZSIG_FUNC;
diff --git a/Src/signals.c b/Src/signals.c
index 0518b1927..891ea1143 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -670,6 +670,7 @@ dosavetrap(int sig, int level)
 	st->list = sigfuncs[sig];
 	sigfuncs[sig] = NULL;
     }
+    noerrs = !!st->list;
     if (!savetraps)
 	savetraps = znewlinklist();
     /*
@@ -726,11 +727,22 @@ settrap(int sig, Eprog l)
 void
 unsettrap(int sig)
 {
+    int ne = noerrs;
+    HashNode hn = removetrap(sig);
+    noerrs = ne;
+    if (hn)
+	shfunctab->freenode(hn);
+}
+
+/**/
+HashNode
+removetrap(int sig)
+{
     int trapped;
 
     if (sig == -1 ||
 	(jobbing && (sig == SIGTTOU || sig == SIGTSTP || sig == SIGTTIN)))
-	return;
+	return NULL;
 
     trapped = sigtrapped[sig];
     /*
@@ -743,7 +755,7 @@ unsettrap(int sig)
 	dosavetrap(sig, locallevel);
 
     if (!trapped)
-        return;
+        return NULL;
 
     sigtrapped[sig] = 0;
     if (sig == SIGINT && interact) {
@@ -769,19 +781,19 @@ unsettrap(int sig)
      */
     if (trapped & ZSIG_FUNC) {
 	char func[20];
-	HashNode hn;
 
 	sprintf(func, "TRAP%s", sigs[sig]);
 	/*
 	 * As in dosavetrap(), don't call removeshfuncnode() because
 	 * that calls back into unsettrap();
 	 */
-	if ((hn = removehashnode(shfunctab, func)))
-	    shfunctab->freenode(hn);
+	return removehashnode(shfunctab, func);
     } else if (sigfuncs[sig]) {
 	freeeprog(sigfuncs[sig]);
 	sigfuncs[sig] = NULL;
     }
+
+    return NULL;
 }
 
 /**/