Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: Re: signal queueing



Peter Stephenson wrote:

> > On Dec 20,  9:53am, Sven Wischnowsky wrote:
> > } Subject: signal queueing
> > } 
> > } Here is the current version of the patch. It's the old version plus
> > } Bart's fix plus some. Still not committed.
> > 
> > Is there any reason Sven shouldn't go ahead and commit these?  I've been
> > using the first version since the day it was posted with no trouble.  I
> > haven't had a chance yet to try this version since returning from my
> > holiday trip, but I don't anticipate any new problems.
> 
> I've got it running, although unfortunately the code I use which depends
> most heavily on this isn't working for completely different reasons, so I
> haven't tested it as much as I should have been able to.  But I haven't
> seen any problems.

So we are (at least) three who have tried it. Ok, I'll commit it now
and we'll see what happens.

Maybe I'll find some time to look after the things I mentioned in
13301, of course, others may have a look, too ;-) Here is what I wrote 
then:

> What's still missing is: the code in jobs.c, the signal handling code
> and places where we use Param pointers (in params.c most things should 
> be safe already). Many of these places should be protected already
> because of the code in exec.c and subst.c (prefork()), but looking at
> it again might be a good idea.


Bye
 Sven

Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.39
diff -u -r1.39 builtin.c
--- Src/builtin.c	2000/12/03 20:53:25	1.39
+++ Src/builtin.c	2001/01/16 13:27:10
@@ -407,7 +407,9 @@
      * print nodes NOT containing the DISABLED flag, else scanhashtable will *
      * print nodes containing the DISABLED flag.                             */
     if (!*argv) {
+	queue_signals();
 	scanhashtable(ht, 1, flags1, flags2, ht->printnode, 0);
+	unqueue_signals();
 	return 0;
     }
 
@@ -416,8 +418,11 @@
 	for (; *argv; argv++) {
 	    /* parse pattern */
 	    tokenize(*argv);
-	    if ((pprog = patcompile(*argv, PAT_STATIC, 0)))
+	    if ((pprog = patcompile(*argv, PAT_STATIC, 0))) {
+		queue_signals();
 		match += scanmatchtable(ht, pprog, 0, 0, scanfunc, 0);
+		unqueue_signals();
+	    }
 	    else {
 		untokenize(*argv);
 		zwarnnam(name, "bad pattern : %s", *argv, 0);
@@ -431,6 +436,7 @@
     }
 
     /* Take arguments literally -- do not glob */
+    queue_signals();
     for (; *argv; argv++) {
 	    if ((hn = ht->getnode2(ht, *argv))) {
 		scanfunc(hn, 0);
@@ -439,6 +445,7 @@
 		returnval = 1;
 	    }
 	}
+    unqueue_signals();
     return returnval;
 }
 
@@ -511,6 +518,7 @@
     inittyptab();
 
     /* Show the parameters, possibly with values */
+    queue_signals();
     if (!hadopt && !*args)
 	scanhashtable(paramtab, 1, 0, 0, paramtab->printnode,
 	    hadplus ? PRINT_NAMEONLY : 0);
@@ -520,8 +528,10 @@
 	scanhashtable(paramtab, 1, PM_ARRAY, 0, paramtab->printnode,
 	    hadplus ? PRINT_NAMEONLY : 0);
     }
-    if (!*args && !hadend)
+    if (!*args && !hadend) {
+	unqueue_signals();
 	return 0;
+    }
     if (array)
 	args++;
     if (sort)
@@ -550,6 +560,7 @@
 	freearray(pparams);
 	pparams = zarrdup(args);
     }
+    unqueue_signals();
     return 0;
 }
 
@@ -588,6 +599,7 @@
 
     /* with the -v option, provide a numbered list of directories, starting at
     zero */
+    queue_signals();
     if (ops['v']) {
 	LinkNode node;
 	int pos = 1;
@@ -599,11 +611,13 @@
 	    fprintdir(getdata(node), stdout);
 	}
 	putchar('\n');
+	unqueue_signals();
 	return 0;
     }
     /* given no arguments, list the stack normally */
     if (!*argv) {
 	printdirstack();
+	unqueue_signals();
 	return 0;
     }
     /* replace the stack with the specified directories */
@@ -614,6 +628,7 @@
 	freelinklist(dirstack, freestr);
 	dirstack = l;
     }
+    unqueue_signals();
     return 0;
 }
 
@@ -693,9 +708,11 @@
     }
   brk:
     chasinglinks = ops['P'] || (isset(CHASELINKS) && !ops['L']);
+    queue_signals();
     zpushnode(dirstack, ztrdup(pwd));
     if (!(dir = cd_get_dest(nam, argv, ops, func))) {
 	zsfree(getlinknode(dirstack));
+	unqueue_signals();
 	return 1;
     }
     cd_new_pwd(func, dir);
@@ -715,6 +732,7 @@
 	    chdir(unmeta(pwd));
 	}
     }
+    unqueue_signals();
     return 0;
 }
 
@@ -1192,19 +1210,23 @@
 	    return 1;
 	}
     }
+    queue_signals();
     if (ops['R']) {
 	/* read history from a file */
 	readhistfile(*argv, 1, ops['I'] ? HFILE_SKIPOLD : 0);
+	unqueue_signals();
 	return 0;
     }
     if (ops['W']) {
 	/* write history to a file */
 	savehistfile(*argv, 1, ops['I'] ? HFILE_SKIPOLD : 0);
+	unqueue_signals();
 	return 0;
     }
     if (ops['A']) {
 	/* append history to a file */
 	savehistfile(*argv, 1, HFILE_APPEND | (ops['I'] ? HFILE_SKIPOLD : 0));
+	unqueue_signals();
 	return 0;
     }
     /* put foo=bar type arguments into the substitution list */
@@ -1226,20 +1248,25 @@
     if (*argv) {
 	minflag = **argv == '-';
 	first = fcgetcomm(*argv);
-	if (first == -1)
+	if (first == -1) {
+	    unqueue_signals();
 	    return 1;
+	}
 	argv++;
     }
     /* interpret and check second history line specifier */
     if (*argv) {
 	last = fcgetcomm(*argv);
-	if (last == -1)
+	if (last == -1) {
+	    unqueue_signals();
 	    return 1;
+	}
 	argv++;
     }
     /* There is a maximum of two history specifiers.  At least, there *
      * will be as long as the history list is one-dimensional.        */
     if (*argv) {
+	unqueue_signals();
 	zwarnnam("fc", "too many arguments", NULL, 0);
 	return 1;
     }
@@ -1256,11 +1283,13 @@
 	last = (minflag) ? curhist : first;
     else if (last < first)
 	last = first;
-    if (ops['l'])
+    if (ops['l']) {
 	/* list the required part of the history */
 	retval = fclist(stdout, !ops['n'], ops['r'], ops['D'],
 			ops['d'] + ops['f'] * 2 + ops['E'] * 4 + ops['i'] * 8,
 			first, last, asgf, pprog);
+	unqueue_signals();
+    }
     else {
 	/* edit history file, and (if successful) use the result as a new command */
 	int tempfd;
@@ -1272,6 +1301,7 @@
 	if (((tempfd = open(fil, O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0600))
 	    == -1) ||
 		((out = fdopen(tempfd, "w")) == NULL)) {
+	    unqueue_signals();
 	    zwarnnam("fc", "can't open temp file: %e", NULL, errno);
 	} else {
 	    if (!fclist(out, 0, ops['r'], 0, 0, first, last, asgf, pprog)) {
@@ -1281,6 +1311,7 @@
 		if (!editor)
 		    editor = DEFAULT_FCEDIT;
 
+		unqueue_signals();
 		if (fcedit(editor, fil)) {
 		    if (stuff(fil))
 			zwarnnam("fc", "%e: %s", s, errno);
@@ -1289,7 +1320,8 @@
 			retval = lastval;
 		    }
 		}
-	    }
+	    } else
+		unqueue_signals();
 	}
 	unlink(fil);
     }
@@ -1847,6 +1879,8 @@
 
     on &= ~off;
 
+    queue_signals();
+
     /* Given no arguments, list whatever the options specify. */
     if (!*argv) {
 	if (!(on|roff))
@@ -1854,6 +1888,7 @@
 	if (roff || ops['+'])
 	    printflags |= PRINT_NAMEONLY;
 	scanhashtable(paramtab, 1, on|roff, 0, paramtab->printnode, printflags);
+	unqueue_signals();
 	return 0;
     }
 
@@ -1868,20 +1903,27 @@
 
 	if (ops['m']) {
 	    zwarnnam(name, "incompatible options for -T", NULL, 0);
+	    unqueue_signals();
 	    return 1;
 	}
 	on &= ~off;
 	if (!argv[1] || argv[2]) {
 	    zwarnnam(name, "-T requires names of scalar and array", NULL, 0);
+	    unqueue_signals();
 	    return 1;
 	}
 
-	if (!(asg = getasg(argv[0])))
+	if (!(asg = getasg(argv[0]))) {
+	    unqueue_signals();
 	    return 1;
+	}
 	asg0 = *asg;
-	if (!(asg = getasg(argv[1])))
+	if (!(asg = getasg(argv[1]))) {
+	    unqueue_signals();
 	    return 1;
+	}
 	if (!strcmp(asg0.name, asg->name)) {
+	    unqueue_signals();
 	    zerrnam(name, "can't tie a variable to itself", NULL, 0);
 	    return 1;
 	}
@@ -1910,9 +1952,10 @@
 				 (Param)paramtab->getnode(paramtab,
 							  asg->name),
 				 func, (on | PM_ARRAY) & ~PM_EXPORTED,
-				 off, roff, asg->value, NULL)))
+				 off, roff, asg->value, NULL))) {
+	    unqueue_signals();
 	    return 1;
-
+	}
 	/*
 	 * Create the tied colonarray.  We make it as a normal scalar
 	 * and fix up the oddities later.
@@ -1924,6 +1967,7 @@
 	    if (oldval)
 		zsfree(oldval);
 	    unsetparam_pm(apm, 1, 1);
+	    unqueue_signals();
 	    return 1;
 	}
 
@@ -1931,6 +1975,7 @@
 	apm->ename = ztrdup(asg0.name);
 	if (oldval)
 	    setsparam(asg0.name, oldval);
+	unqueue_signals();
 
 	return 0;
     }
@@ -1987,6 +2032,7 @@
 		    returnval = 1;
 	    }
 	}
+	unqueue_signals();
 	return returnval;
     }
 
@@ -2005,6 +2051,7 @@
 			    func, on, off, roff, asg->value, NULL))
 	    returnval = 1;
     }
+    unqueue_signals();
     return returnval;
 }
 
@@ -2074,6 +2121,9 @@
      * are given, we will print only functions containing these  *
      * flags, else we'll print them all.                         */
     if (!*argv) {
+	int ret = 0;
+
+	queue_signals();
 	if (ops['X'] == 1) {
 	    if ((shf = (Shfunc) shfunctab->getnode(shfunctab, scriptname))) {
 		DPUTS(!shf->funcdef,
@@ -2083,14 +2133,15 @@
 		shfunctab->addnode(shfunctab, ztrdup(scriptname), shf);
 	    }
 	    shf->flags = on;
-	    return eval_autoload(shf, scriptname, ops, func);
+	    ret = eval_autoload(shf, scriptname, ops, func);
 	} else {
 	    if (ops['U'] && !ops['u'])
 		on &= ~PM_UNDEFINED;
 	    scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode,
 			  pflags);
 	}
-	return 0;
+	unqueue_signals();
+	return ret;
     }
 
     /* With the -m option, treat arguments as glob patterns */
@@ -2101,6 +2152,7 @@
 	    tokenize(*argv);
 	    if ((pprog = patcompile(*argv, PAT_STATIC, 0))) {
 		/* with no options, just print all functions matching the glob pattern */
+		queue_signals();
 		if (!(on|off)) {
 		    scanmatchtable(shfunctab, pprog, 0, DISABLED,
 				   shfunctab->printnode, pflags);
@@ -2120,6 +2172,7 @@
 			    }
 		    }
 		}
+		unqueue_signals();
 	    } else {
 		untokenize(*argv);
 		zwarnnam(name, "bad pattern : %s", *argv, 0);
@@ -2130,6 +2183,7 @@
     }
 
     /* Take the arguments literally -- do not glob */
+    queue_signals();
     for (; *argv; argv++) {
 	if (ops['w'])
 	    returnval = dump_autoload(name, *argv, on, ops, func);
@@ -2155,6 +2209,7 @@
 	} else
 	    returnval = 1;
     }
+    unqueue_signals();
     return returnval;
 }
 
@@ -2206,6 +2261,7 @@
 	    tokenize(s);
 	    if ((pprog = patcompile(s, PAT_STATIC, NULL))) {
 		/* Go through the parameter table, and unset any matches */
+		queue_signals();
 		for (i = 0; i < paramtab->hsize; i++) {
 		    for (pm = (Param) paramtab->nodes[i]; pm; pm = next) {
 			/* record pointer to next, since we may free this one */
@@ -2218,6 +2274,7 @@
 			}
 		    }
 		}
+		unqueue_signals();
 	    } else {
 		untokenize(s);
 		zwarnnam(name, "bad pattern : %s", s, 0);
@@ -2231,6 +2288,7 @@
     }
 
     /* do not glob -- unset the given parameter */
+    queue_signals();
     while ((s = *argv++)) {
 	char *ss = strchr(s, '[');
 	char *sse = ss;
@@ -2268,6 +2326,7 @@
 	if (ss)
 	    *ss = '[';
     }
+    unqueue_signals();
     return returnval;
 }
 
@@ -2313,6 +2372,7 @@
 		returnval = 1;
 		continue;
 	    }
+	    queue_signals();
 	    if (!ops['p']) {
 		/* -p option is for path search only.    *
 		 * We're not using it, so search for ... */
@@ -2339,11 +2399,13 @@
 	    scanmatchtable(cmdnamtab, pprog, 0, 0,
 			   cmdnamtab->printnode, printflags);
 
+	    unqueue_signals();
 	}
-    return returnval;
+	return returnval;
     }
 
     /* Take arguments literally -- do not glob */
+    queue_signals();
     for (; *argv; argv++) {
 	informed = 0;
 
@@ -2436,6 +2498,7 @@
 	    returnval = 1;
 	}
     }
+    unqueue_signals();
     return returnval;
 }
 
@@ -2496,10 +2559,13 @@
 
     /* Given no arguments, display current hash table. */
     if (!*argv) {
+	queue_signals();
 	scanhashtable(ht, 1, 0, 0, ht->printnode, printflags);
+	unqueue_signals();
 	return 0;
     }
 
+    queue_signals();
     while (*argv) {
 	void *hn;
 	if (ops['m']) {
@@ -2553,6 +2619,7 @@
 	    ht->printnode(hn, 0);
 	argv++;
     }
+    unqueue_signals();
     return returnval;
 }
 
@@ -2586,6 +2653,7 @@
 	    tokenize(*argv);
 	    if ((pprog = patcompile(*argv, PAT_STATIC, NULL))) {
 		/* remove all nodes matching glob pattern */
+		queue_signals();
 		for (i = 0; i < ht->hsize; i++) {
 		    for (hn = ht->nodes[i]; hn; hn = nhn) {
 			/* record pointer to next, since we may free this one */
@@ -2596,6 +2664,7 @@
 			}
 		    }
 		}
+		unqueue_signals();
 	    } else {
 		untokenize(*argv);
 		zwarnnam(name, "bad pattern : %s", *argv, 0);
@@ -2609,6 +2678,7 @@
     }
 
     /* Take arguments literally -- do not glob */
+    queue_signals();
     for (; *argv; argv++) {
 	if ((hn = ht->removenode(ht, *argv))) {
 	    ht->freenode(hn);
@@ -2617,6 +2687,7 @@
 	    returnval = 1;
 	}
     }
+    unqueue_signals();
     return returnval;
 }
 
@@ -2656,7 +2727,9 @@
     /* In the absence of arguments, list all aliases.  If a command *
      * line flag is specified, list only those of that type.        */
     if (!*argv) {
+	queue_signals();
 	scanhashtable(aliastab, 1, flags1, flags2, aliastab->printnode, printflags);
+	unqueue_signals();
 	return 0;
     }
 
@@ -2667,8 +2740,10 @@
 	    tokenize(*argv);  /* expand argument */
 	    if ((pprog = patcompile(*argv, PAT_STATIC, NULL))) {
 		/* display the matching aliases */
+		queue_signals();
 		scanmatchtable(aliastab, pprog, flags1, flags2,
 			       aliastab->printnode, printflags);
+		unqueue_signals();
 	    } else {
 		untokenize(*argv);
 		zwarnnam(name, "bad pattern : %s", *argv, 0);
@@ -2679,6 +2754,7 @@
     }
 
     /* Take arguments literally.  Don't glob */
+    queue_signals();
     while ((asg = getasg(*argv++))) {
 	if (asg->value && !ops['L']) {
 	    /* The argument is of the form foo=bar and we are not *
@@ -2694,6 +2770,7 @@
 	} else
 	    returnval = 1;
     }
+    unqueue_signals();
     return returnval;
 }
 
@@ -2774,7 +2851,10 @@
 	}
 	/* -D option -- interpret as a directory, and use ~ */
 	if(ops['D']) {
-	    Nameddir d = finddir(args[n]);
+	    Nameddir d;
+
+	    queue_signals();
+	    d = finddir(args[n]);
 	    if(d) {
 		char *arg = zhalloc(strlen(args[n]) + 1);
 		sprintf(arg, "~%s%s", d->nam,
@@ -2782,12 +2862,15 @@
 		args[n] = arg;
 		len[n] = strlen(args[n]);
 	    }
+	    unqueue_signals();
 	}
     }
 
     /* -z option -- push the arguments onto the editing buffer stack */
     if (ops['z']) {
+	queue_signals();
 	zpushnode(bufstack, sepjoin(args, NULL, 0));
+	unqueue_signals();
 	return 0;
     }
     /* -s option -- add the arguments to the history list */
@@ -2795,6 +2878,7 @@
 	int nwords = 0, nlen, iwords;
 	char **pargs = args;
 
+	queue_signals();
 	ent = prepnexthistent();
 	while (*pargs++)
 	    nwords++;
@@ -2813,6 +2897,7 @@
 	ent->stim = ent->ftim = time(NULL);
 	ent->flags = 0;
 	addhistnode(histtab, ent->text, ent);
+	unqueue_signals();
 	return 0;
     }
     /* -u and -p -- output to other than standard output */
@@ -2908,10 +2993,12 @@
     char **s;
  
     /* optional argument can be either numeric or an array */
+    queue_signals();
     if (*argv && !getaparam(*argv))
         num = mathevali(*argv++);
  
     if (num < 0) {
+	unqueue_signals();
         zwarnnam(name, "argument to shift must be non-negative", NULL, 0);
         return 1;
     }
@@ -2940,6 +3027,7 @@
 	    pparams = s;
 	}
     }
+    unqueue_signals();
     return ret;
 }
 
@@ -3169,7 +3257,7 @@
 	}
     }
     if (sigtrapped[SIGEXIT])
-	dotrap(SIGEXIT, 1);
+	dotrap(SIGEXIT);
     runhookdef(EXITHOOK, NULL);
     if (mypid != getpid())
 	_exit(val);
@@ -3415,7 +3503,7 @@
 		    *bptr = readchar;
 		    val = 1;
 		    readchar = -1;
-		} else if ((val = ztrapread(readfd, bptr, nchars)) <= 0)
+		} else if ((val = read(readfd, bptr, nchars)) <= 0)
 		    break;
 	    
 		/* decrement number of characters read from number required */
@@ -3429,7 +3517,7 @@
 	if (!izle && !ops['u'] && !ops['p']) {
 	    /* dispose of result appropriately, etc. */
 	    if (isem)
-		while (val > 0 && ztrapread(SHTTY, &d, 1) == 1 && d != '\n');
+		while (val > 0 && read(SHTTY, &d, 1) == 1 && d != '\n');
 	    else
 		settyinfo(&shttyinfo);
 	    if (haso) {
@@ -3686,7 +3774,7 @@
     }
     for (;;) {
 	/* read a character from readfd */
-	ret = ztrapread(readfd, &cc, 1);
+	ret = read(readfd, &cc, 1);
 	switch (ret) {
 	case 1:
 	    /* return the character read */
@@ -3839,6 +3927,7 @@
 
     /* If given no arguments, list all currently-set traps */
     if (!*argv) {
+	queue_signals();
 	for (sig = 0; sig < VSIGCOUNT; sig++) {
 	    if (sigtrapped[sig] & ZSIG_FUNC) {
 		char fname[20];
@@ -3860,6 +3949,7 @@
 		}
 	    }
 	}
+	unqueue_signals();
 	return 0;
     }
 
Index: Src/exec.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/exec.c,v
retrieving revision 1.23
diff -u -r1.23 exec.c
--- Src/exec.c	2000/12/05 10:34:23	1.23
+++ Src/exec.c	2001/01/16 13:27:12
@@ -759,8 +759,6 @@
     } else
 	lv = (execfuncs[code - WC_CURSH])(state, 0);
 
-    RUNTRAPS();
-
     return lastval = lv;
 }
 
@@ -892,19 +890,19 @@
 	noerrexit = oldnoerrexit;
 
 	if (sigtrapped[SIGDEBUG])
-	    dotrap(SIGDEBUG, 1);
+	    dotrap(SIGDEBUG);
 
 	/* Check whether we are suppressing traps/errexit *
 	 * (typically in init scripts) and if we haven't  *
 	 * already performed them for this sublist.       */
 	if (!noerrexit && !donetrap) {
 	    if (sigtrapped[SIGZERR] && lastval) {
-		dotrap(SIGZERR, 1);
+		dotrap(SIGZERR);
 		donetrap = 1;
 	    }
 	    if (lastval && isset(ERREXIT)) {
 		if (sigtrapped[SIGEXIT])
-		    dotrap(SIGEXIT, 1);
+		    dotrap(SIGEXIT);
 		if (mypid != getpid())
 		    _exit(lastval);
 		else
@@ -951,9 +949,10 @@
     child_block();
 
     /* get free entry in job table and initialize it */
-    if ((thisjob = newjob = initjob()) == -1)
+    if ((thisjob = newjob = initjob()) == -1) {
+	child_unblock();
 	return 1;
-
+    }
     if (how & Z_TIMED)
 	jobtab[thisjob].stat |= STAT_TIMED;
 
@@ -1186,10 +1185,9 @@
 	else
 	    list_pipe_text[0] = '\0';
     }
-    if (WC_PIPE_TYPE(pcode) == WC_PIPE_END) {
+    if (WC_PIPE_TYPE(pcode) == WC_PIPE_END)
 	execcmd(state, input, output, how, last1 ? 1 : 2);
-	RUNTRAPS();
-    } else {
+    else {
 	int old_list_pipe = list_pipe;
 	Wordcode next = state->pc + (*state->pc);
 	wordcode code;
@@ -1224,14 +1222,12 @@
 		entersubsh(how, 2, 0);
 		close(synch[1]);
 		execcmd(state, input, pipes[1], how, 0);
-		RUNTRAPS();
 		_exit(lastval);
 	    }
 	} else {
 	    /* otherwise just do the pipeline normally. */
 	    subsh_close = pipes[0];
 	    execcmd(state, input, pipes[1], how, 0);
-	    RUNTRAPS();
 	}
 	zclose(pipes[1]);
 	state->pc = next;
@@ -1611,7 +1607,7 @@
     }
 }
 
-/* These describe the type of espansions that need to be done on the words
+/* These describe the type of expansions that need to be done on the words
  * used in the thing we are about to execute. They are set in execcmd() and
  * used in execsubst() which might be called from one of the functions
  * called from execcmd() (like execfor() and so on). */
@@ -2274,6 +2270,7 @@
 		if (subsh_close >= 0)
 		    zclose(subsh_close);
 		subsh_close = -1;
+
 		execshfunc((Shfunc) hn, args);
 #ifdef PATH_DEV_FD
 		for (i = 10; i <= max_zsh_fd; i++)
Index: Src/glob.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/glob.c,v
retrieving revision 1.13
diff -u -r1.13 glob.c
--- Src/glob.c	2000/12/05 10:34:23	1.13
+++ Src/glob.c	2001/01/16 13:27:13
@@ -279,14 +279,17 @@
     char *news = s;
     int statted = 0;
 
+    queue_signals();
     inserts = NULL;
 
     if (gf_listtypes || gf_markdirs) {
 	/* Add the type marker to the end of the filename */
 	mode_t mode;
 	checked = statted = 1;
-	if (statfullpath(s, &buf, 1))
+	if (statfullpath(s, &buf, 1)) {
+	    unqueue_signals();
 	    return;
+	}
 	mode = buf.st_mode;
 	if (gf_follow) {
 	    if (!S_ISLNK(mode) || statfullpath(s, &buf2, 0))
@@ -307,9 +310,10 @@
 	/* Go through the qualifiers, rejecting the file if appropriate */
 	struct qual *qo, *qn;
 
-	if (!statted && statfullpath(s, &buf, 1))
+	if (!statted && statfullpath(s, &buf, 1)) {
+	    unqueue_signals();
 	    return;
-
+	}
 	news = dyncat(pathbuf, news);
 
 	statted = 1;
@@ -330,16 +334,20 @@
 	     * vice versa.                                   */
 	    if ((!((qn->func) (news, bp, qn->data, qn->sdata)) ^ qn->sense) & 1) {
 		/* Try next alternative, or return if there are no more */
-		if (!(qo = qo->or))
+		if (!(qo = qo->or)) {
+		    unqueue_signals();
 		    return;
+		}
 		qn = qo;
 		continue;
 	    }
 	    qn = qn->next;
 	}
     } else if (!checked) {
-	if (statfullpath(s, NULL, 1))
+	if (statfullpath(s, NULL, 1)) {
+	    unqueue_signals();
 	    return;
+	}
 	statted = 1;
 	news = dyncat(pathbuf, news);
     } else
@@ -389,6 +397,7 @@
 	if (!inserts)
 	    break;
     }
+    unqueue_signals();
 }
 
 /* Check to see if str is eligible for filename generation. */
Index: Src/hashtable.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/hashtable.c,v
retrieving revision 1.7
diff -u -r1.7 hashtable.c
--- Src/hashtable.c	2000/05/15 00:31:20	1.7
+++ Src/hashtable.c	2001/01/16 13:27:13
@@ -560,11 +560,14 @@
 bin_hashinfo(char *nam, char **args, char *ops, int func)
 {
     HashTable ht;
+
     printf("----------------------------------------------------\n");
+    queue_signals();
     for(ht = firstht; ht; ht = ht->next) {
 	ht->printinfo(ht);
 	printf("----------------------------------------------------\n");
     }
+    unqueue_signals();
     return 0;
 }
 
Index: Src/hist.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/hist.c,v
retrieving revision 1.20
diff -u -r1.20 hist.c
--- Src/hist.c	2000/10/21 03:15:36	1.20
+++ Src/hist.c	2001/01/16 13:27:14
@@ -382,6 +382,7 @@
 
 	/* get event number */
 
+	queue_signals();
 	if (c == '?') {
 	    for (;;) {
 		c = ingetc();
@@ -397,6 +398,7 @@
 	    evset = 0;
 	    if (ev == -1) {
 		herrflush();
+		unqueue_signals();
 		zerr("no such event: %s", buf, 0);
 		return -1;
 	    }
@@ -450,6 +452,7 @@
 		evset = 1;
 	    } else if ((ev = hcomsearch(buf)) == -1) {
 		herrflush();
+		unqueue_signals();
 		zerr("event not found: %s", buf, 0);
 		return -1;
 	    } else
@@ -458,9 +461,10 @@
 
 	/* get the event */
 
-	if (!(ehist = gethist(defev = ev)))
+	if (!(ehist = gethist(defev = ev))) {
+	    unqueue_signals();
 	    return -1;
-
+	}
 	/* extract the relevant arguments */
 
 	argc = getargc(ehist);
@@ -473,6 +477,7 @@
 		    argc = getargc(ehist);
 		} else {
 		    herrflush();
+		    unqueue_signals();
 		    zerr("Ambiguous history reference", NULL, 0);
 		    return -1;
 		}
@@ -486,8 +491,10 @@
 	} else {
 	    inungetc(c);
 	    larg = farg = getargspec(argc, marg, evset);
-	    if (larg == -2)
+	    if (larg == -2) {
+		unqueue_signals();
 		return -1;
+	    }
 	    if (farg != -1)
 		cflag = 0;
 	    c = ingetc();
@@ -497,8 +504,10 @@
 	    } else if (c == '-') {
 		cflag = 0;
 		larg = getargspec(argc, marg, evset);
-		if (larg == -2)
+		if (larg == -2) {
+		    unqueue_signals();
 		    return -1;
+		}
 		if (larg == -1)
 		    larg = argc - 1;
 	    } else
@@ -508,8 +517,11 @@
 	    farg = 0;
 	if (larg == -1)
 	    larg = argc;
-	if (!(sline = getargs(ehist, farg, larg)))
+	if (!(sline = getargs(ehist, farg, larg))) {
+	    unqueue_signals();
 	    return -1;
+	}
+	unqueue_signals();
     }
 
     /* do the modifiers */
@@ -1000,10 +1012,12 @@
 hend(Eprog prog)
 {
     int flag, save = 1;
-    char *hf = getsparam("HISTFILE");
+    char *hf;
 
     DPUTS(stophist != 2 && !(inbufflags & INP_ALIAS) && !chline,
 	  "BUG: chline is NULL in hend()");
+    queue_signals();
+    hf = getsparam("HISTFILE");
     if (histdone & HISTFLAG_SETTY)
 	settyinfo(&shttyinfo);
     if (!(histactive & HA_NOINC))
@@ -1013,6 +1027,7 @@
 	zfree(chwords, chwordlen*sizeof(short));
 	chline = NULL;
 	histactive = 0;
+	unqueue_signals();
 	return 1;
     }
     if (hist_ignore_all_dups != isset(HISTIGNOREALLDUPS)
@@ -1107,6 +1122,7 @@
     if (isset(SHAREHISTORY)? histfileIsLocked() : isset(INCAPPENDHISTORY))
 	savehistfile(hf, 0, HFILE_USE_OPTIONS | HFILE_FAST);
     unlockhistfile(hf); /* It's OK to call this even if we aren't locked */
+    unqueue_signals();
     return !(flag & HISTFLAG_NOEXEC || errflag);
 }
 
Index: Src/init.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/init.c,v
retrieving revision 1.15
diff -u -r1.15 init.c
--- Src/init.c	2000/11/11 19:50:29	1.15
+++ Src/init.c	2001/01/16 13:27:14
@@ -170,7 +170,7 @@
 	}
 	if (isset(SINGLECOMMAND) && toplevel) {
 	    if (sigtrapped[SIGEXIT])
-		dotrap(SIGEXIT, 1);
+		dotrap(SIGEXIT);
 	    exit(lastval);
 	}
 	if (justonce)
@@ -1022,6 +1022,7 @@
 {
     char *h;
 
+    queue_signals();
     if (emulation == EMULATE_SH || emulation == EMULATE_KSH ||
 	!(h = getsparam("ZDOTDIR")))
 	h = home;
@@ -1030,6 +1031,7 @@
 	/* Let source() complain if path is too long */
 	VARARR(char, buf, strlen(h) + strlen(s) + 2);
 	sprintf(buf, "%s/%s", h, s);
+	unqueue_signals();
 	source(buf);
     }
 }
Index: Src/input.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/input.c,v
retrieving revision 1.3
diff -u -r1.3 input.c
--- Src/input.c	2000/11/11 19:50:29	1.3
+++ Src/input.c	2001/01/16 13:27:14
@@ -141,9 +141,7 @@
     for (;;) {
 	do {
 	    errno = 0;
-	    ALLOWTRAPS {
-		c = fgetc(bshin);
-	    } DISALLOWTRAPS;
+	    c = fgetc(bshin);
 	} while (c < 0 && errno == EINTR);
 	if (c < 0 || c == '\n') {
 	    if (c == '\n')
Index: Src/jobs.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/jobs.c,v
retrieving revision 1.8
diff -u -r1.8 jobs.c
--- Src/jobs.c	2000/12/06 12:22:41	1.8
+++ Src/jobs.c	2001/01/16 13:27:15
@@ -378,7 +378,7 @@
 	    zrefresh();
     }
     if (sigtrapped[SIGCHLD] && job != thisjob)
-	dotrap(SIGCHLD, 0);
+	dotrap(SIGCHLD);
 
     /* When MONITOR is set, the foreground process runs in a different *
      * process group from the shell, so the shell will not receive     *
@@ -389,7 +389,7 @@
 
 	if (sig == SIGINT || sig == SIGQUIT) {
 	    if (sigtrapped[sig]) {
-		dotrap(sig, 0);
+		dotrap(sig);
 		/* We keep the errflag as set or not by dotrap.
 		 * This is to fulfil the promise to carry on
 		 * with the jobs if trap returns zero.
@@ -497,6 +497,7 @@
     percent      =  100.0 * (ti->ut + ti->st)
 	/ (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0);
 
+    queue_signals();
     if (!(s = getsparam("TIMEFMT")))
 	s = DEFAULT_TIMEFMT;
 
@@ -546,6 +547,7 @@
 		break;
 	} else
 	    putc(*s, stderr);
+    unqueue_signals();
     putc('\n', stderr);
     fflush(stderr);
 }
@@ -580,10 +582,13 @@
     if (j->stat & STAT_TIMED)
 	return 1;
 
+    queue_signals();
     if (!(v = getvalue(&vbuf, &s, 0)) ||
 	(reporttime = getintvalue(v)) < 0) {
+	unqueue_signals();
 	return 0;
     }
+    unqueue_signals();
     /* can this ever happen? */
     if (!j->procs)
 	return 0;
@@ -868,9 +873,10 @@
 void
 waitforpid(pid_t pid)
 {
-    int first = 1;
+    int first = 1, q = queue_signal_level();
 
     /* child_block() around this loop in case #ifndef WNOHANG */
+    dont_queue_signals();
     child_block();		/* unblocked in child_suspend() */
     while (!errflag && (kill(pid, 0) >= 0 || errno != ESRCH)) {
 	if (first)
@@ -878,12 +884,11 @@
 	else
 	    kill(pid, SIGCONT);
 
-	ALLOWTRAPS {
-	    child_suspend(SIGINT);
-	} DISALLOWTRAPS;
+	child_suspend(SIGINT);
 	child_block();
     }
     child_unblock();
+    restore_queue_signals(q);
 }
 
 /* wait for a job to finish */
@@ -892,8 +897,10 @@
 static void
 zwaitjob(int job, int sig)
 {
+    int q = queue_signal_level();
     Job jn = jobtab + job;
 
+    dont_queue_signals();
     child_block();		 /* unblocked during child_suspend() */
     if (jn->procs) {		 /* if any forks were done         */
 	jn->stat |= STAT_LOCKED;
@@ -902,9 +909,7 @@
 	while (!errflag && jn->stat &&
 	       !(jn->stat & STAT_DONE) &&
 	       !(interact && (jn->stat & STAT_STOPPED))) {
-	    ALLOWTRAPS {
-		child_suspend(sig);
-	    } DISALLOWTRAPS;
+	    child_suspend(sig);
 	    /* Commenting this out makes ^C-ing a job started by a function
 	       stop the whole function again.  But I guess it will stop
 	       something else from working properly, we have to find out
@@ -926,6 +931,7 @@
 	numpipestats = 1;
     }
     child_unblock();
+    restore_queue_signals(q);
 }
 
 /* wait for running job to finish */
@@ -1222,11 +1228,13 @@
 	    zwarnnam(name, "-Z requires one argument", NULL, 0);
 	    return 1;
 	}
+	queue_signals();
 	unmetafy(*argv, &len);
 	if(len > hackspace)
 	    len = hackspace;
 	memcpy(hackzero, *argv, len);
 	memset(hackzero + len, 0, hackspace - len);
+	unqueue_signals();
 	return 0;
     }
 
@@ -1292,6 +1300,7 @@
 	    pid_t pid = (long)atoi(*argv);
 	    Job j;
 	    Process p;
+
 	    if (findproc(pid, &j, &p))
 		waitforpid(pid);
 	    else
Index: Src/math.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/math.c,v
retrieving revision 1.7
diff -u -r1.7 math.c
--- Src/math.c	2000/09/04 15:52:16	1.7
+++ Src/math.c	2001/01/16 13:27:15
@@ -495,10 +495,12 @@
     mnumber mn;
     mn.type = MN_INTEGER;
 
+    queue_signals();
     if (!(t = getsparam(s)))
 	mn.u.l = 0;
     else
         mn.u.l = STOUC(*t == Meta ? t[1] ^ 32 : *t);
+    unqueue_signals();
     return mn;
 }
 
Index: Src/mem.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/mem.c,v
retrieving revision 1.3
diff -u -r1.3 mem.c
--- Src/mem.c	2000/09/19 15:54:31	1.3
+++ Src/mem.c	2001/01/16 13:27:15
@@ -115,9 +115,13 @@
 mod_export Heap
 new_heaps(void)
 {
-    Heap h = heaps;
+    Heap h;
+
+    queue_signals();
+    h = heaps;
 
     fheap = heaps = NULL;
+    unqueue_signals();
 
     return h;
 }
@@ -130,6 +134,7 @@
 {
     Heap h, n;
 
+    queue_signals();
     for (h = heaps; h; h = n) {
 	n = h->next;
 	DPUTS(h->sp, "BUG: old_heaps() with pushed heaps");
@@ -141,6 +146,7 @@
     }
     heaps = old;
     fheap = NULL;
+    unqueue_signals();
 }
 
 /* Temporarily switch to other heaps (or back again). */
@@ -149,10 +155,14 @@
 mod_export Heap
 switch_heaps(Heap new)
 {
-    Heap h = heaps;
+    Heap h;
+
+    queue_signals();
+    h = heaps;
 
     heaps = new;
     fheap = NULL;
+    unqueue_signals();
 
     return h;
 }
@@ -166,6 +176,8 @@
     Heap h;
     Heapstack hs;
 
+    queue_signals();
+
 #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
     h_push++;
 #endif
@@ -177,6 +189,7 @@
 	h->sp = hs;
 	hs->used = h->used;
     }
+    unqueue_signals();
 }
 
 /* reset heaps to previous state */
@@ -187,6 +200,8 @@
 {
     Heap h, hn, hl = NULL;
 
+    queue_signals();
+
 #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
     h_free++;
 #endif
@@ -214,6 +229,8 @@
 	hl->next = NULL;
     else
 	heaps = NULL;
+
+    unqueue_signals();
 }
 
 /* reset heap to previous state and destroy state information */
@@ -225,6 +242,8 @@
     Heap h, hn, hl = NULL;
     Heapstack hs;
 
+    queue_signals();
+
 #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
     h_pop++;
 #endif
@@ -255,6 +274,8 @@
 	hl->next = NULL;
     else
 	heaps = NULL;
+
+    unqueue_signals();
 }
 
 /* allocate memory from the current memory pool */
@@ -268,6 +289,8 @@
 
     size = (size + H_ISIZE - 1) & ~(H_ISIZE - 1);
 
+    queue_signals();
+
 #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
     h_m[size < (1024 * H_ISIZE) ? (size / H_ISIZE) : 1024]++;
 #endif
@@ -276,8 +299,12 @@
 
     for (h = (fheap ? fheap : heaps); h; h = h->next) {
 	if (HEAP_ARENA_SIZE >= (n = size + h->used)) {
+	    void *ret;
+
 	    h->used = n;
-	    return arena(h) + n - size;
+	    ret = arena(h) + n - size;
+	    unqueue_signals();
+	    return ret;
 	}
     }
     {
@@ -289,7 +316,6 @@
             /* tricky, see above */
 #endif
 
-	queue_signals();
 	n = HEAP_ARENA_SIZE > size ? HEAPSIZE : size + sizeof(*h);
 	for (hp = NULL, h = heaps; h; hp = h, h = h->next);
 
@@ -361,6 +387,7 @@
 
     /* find the heap with p */
 
+    queue_signals();
     for (h = heaps, ph = NULL; h; ph = h, h = h->next)
 	if (p >= arena(h) && p < arena(h) + HEAP_ARENA_SIZE)
 	    break;
@@ -376,9 +403,12 @@
 #ifdef ZSH_MEM_DEBUG
 	    memset(p, 0xff, old);
 #endif
+	    unqueue_signals();
 	    return ptr;
-	} else
+	} else {
+	    unqueue_signals();
 	    return new ? p : NULL;
+	}
     }
 
     DPUTS(p + old != arena(h) + h->used, "BUG: hrealloc more than allocated");
@@ -395,6 +425,7 @@
 #else
 	    zfree(h, HEAPSIZE);
 #endif
+	    unqueue_signals();
 	    return NULL;
 	}
 #ifndef USE_MMAP
@@ -407,6 +438,7 @@
 		heaps = h = (Heap) realloc(h, n);
 	}
 	h->used = new;
+	unqueue_signals();
 	return arena(h);
 #endif
     }
@@ -415,6 +447,7 @@
 #endif
     if (h->used + (new - old) <= HEAP_ARENA_SIZE) {
 	h->used += new - old;
+	unqueue_signals();
 	return p;
     } else {
 	char *t = zhalloc(new);
@@ -423,6 +456,7 @@
 #ifdef ZSH_MEM_DEBUG
 	memset(p, 0xff, old);
 #endif
+	unqueue_signals();
 	return t;
     }
 }
@@ -450,10 +484,12 @@
 
     if (!size)
 	size = 1;
+    queue_signals();
     if (!(ptr = (void *) malloc(size))) {
 	zerr("fatal error: out of memory", NULL, 0);
 	exit(1);
     }
+    unqueue_signals();
 
     return ptr;
 }
@@ -466,10 +502,12 @@
 
     if (!size)
 	size = 1;
+    queue_signals();
     if (!(ptr = (void *) malloc(size))) {
 	zerr("fatal error: out of memory", NULL, 0);
 	exit(1);
     }
+    unqueue_signals();
     memset(ptr, 0, size);
 
     return ptr;
@@ -485,6 +523,7 @@
 mod_export void *
 zrealloc(void *ptr, size_t size)
 {
+    queue_signals();
     if (ptr) {
 	if (size) {
 	    /* Do normal realloc */
@@ -492,18 +531,22 @@
 		zerr("fatal error: out of memory", NULL, 0);
 		exit(1);
 	    }
+	    unqueue_signals();
 	    return ptr;
 	}
 	else
 	    /* If ptr is not NULL, but size is zero, *
 	     * then object pointed to is freed.      */
 	    free(ptr);
+
+	ptr = NULL;
     } else {
 	/* If ptr is NULL, then behave like malloc */
-	return malloc(size);
+	ptr = malloc(size);
     }
+    unqueue_signals();
 
-    return NULL;
+    return ptr;
 }
 
 /**/
@@ -1200,6 +1243,7 @@
     char *b, *c, buf[40];
     long u = 0, f = 0, to, cu;
 
+    queue_signals();
     if (ops['v']) {
 	printf("The lower and the upper addresses of the heap. Diff gives\n");
 	printf("the difference between them, i.e. the size of the heap.\n\n");
@@ -1328,6 +1372,7 @@
     if (h_m[1024])
 	printf("big\t%d\n", h_m[1024]);
 
+    unqueue_signals();
     return 0;
 }
 
Index: Src/module.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/module.c,v
retrieving revision 1.7
diff -u -r1.7 module.c
--- Src/module.c	2000/08/15 16:53:08	1.7
+++ Src/module.c	2001/01/16 13:27:16
@@ -763,10 +763,13 @@
      * chain of aliases.  This makes sure the actual module loaded
      * is the right one.
      */
+    queue_signals();
     if (!(node = find_module(name, 1, &name))) {
 	if (!(linked = module_linked(name)) &&
-	    !(handle = do_load_module(name)))
+	    !(handle = do_load_module(name))) {
+	    unqueue_signals();
 	    return 0;
+	}
 	m = zcalloc(sizeof(*m));
 	m->nam = ztrdup(name);
 	if (handle) {
@@ -782,19 +785,25 @@
 	    if (!set)
 		finish_module(m);
 	    delete_module(node);
+	    unqueue_signals();
 	    return 0;
 	}
 	m->flags |= MOD_INIT_S | MOD_INIT_B;
 	m->flags &= ~MOD_SETUP;
+	unqueue_signals();
 	return 1;
     } 
     m = (Module) getdata(node);
-    if (m->flags & MOD_SETUP)
+    if (m->flags & MOD_SETUP) {
+	unqueue_signals();
 	return 1;
+    }
     if (m->flags & MOD_UNLOAD)
 	m->flags &= ~MOD_UNLOAD;
-    else if ((m->flags & MOD_LINKED) ? m->u.linked : m->u.handle)
+    else if ((m->flags & MOD_LINKED) ? m->u.linked : m->u.handle) {
+	unqueue_signals();
 	return 1;
+    }
     if (m->flags & MOD_BUSY) {
 	zerr("circular dependencies for module %s", name, 0);
 	return 0;
@@ -804,14 +813,17 @@
 	for (n = firstnode(m->deps); n; incnode(n))
 	    if (!load_module((char *) getdata(n))) {
 		m->flags &= ~MOD_BUSY;
+		unqueue_signals();
 		return 0;
 	    }
     m->flags &= ~MOD_BUSY;
     if (!m->u.handle) {
 	handle = NULL;
 	if (!(linked = module_linked(name)) &&
-	    !(handle = do_load_module(name)))
+	    !(handle = do_load_module(name))) {
+	    unqueue_signals();
 	    return 0;
+	}
 	if (handle) {
 	    m->u.handle = handle;
 	    m->flags |= MOD_SETUP;
@@ -825,6 +837,7 @@
 	    else
 		m->u.linked = NULL;
 	    m->flags &= ~MOD_SETUP;
+	    unqueue_signals();
 	    return 0;
 	}
 	m->flags |= MOD_INIT_S;
@@ -837,10 +850,12 @@
 	else
 	    m->u.handle = NULL;
 	m->flags &= ~MOD_SETUP;
+	unqueue_signals();
 	return 0;
     }
     m->flags |= MOD_INIT_B;
     m->flags &= ~MOD_SETUP;
+    unqueue_signals();
     return 1;
 }
 
@@ -858,19 +873,23 @@
 {
     Module m = NULL;
     LinkNode node;
+    int ret = 1;
 
     /* Resolve aliases and actual loadable module as for load_module */
+    queue_signals();
     node = find_module(module, 1, &module);
     if (node && (m = ((Module) getdata(node)))->u.handle &&
 	!(m->flags & MOD_UNLOAD)) {
 	if (test) {
+	    unqueue_signals();
 	    zwarnnam(nam, "module %s already loaded.", module, 0);
 	    return 0;
 	}
     } else
-	return load_module(module);
+	ret = load_module(module);
+    unqueue_signals();
 
-    return 1;
+    return ret;
 }
 
 /**/
@@ -941,6 +960,8 @@
 {
     int ops_bcpf = ops['b'] || ops['c'] || ops['p'] || ops['f'];
     int ops_au = ops['a'] || ops['u'];
+    int ret = 1;
+
     if (ops_bcpf && !ops_au) {
 	zwarnnam(nam, "-b, -c, -f, and -p must be combined with -a or -u",
 		 NULL, 0);
@@ -967,24 +988,26 @@
 	zwarnnam(nam, "-e cannot be combined with other options", NULL, 0);
 	return 1;
     }
+    queue_signals();
     if (ops['e'])
-	return bin_zmodload_exist(nam, args, ops);
+	ret = bin_zmodload_exist(nam, args, ops);
     else if (ops['d'])
-	return bin_zmodload_dep(nam, args, ops);
+	ret = bin_zmodload_dep(nam, args, ops);
     else if ((ops['a'] || ops['b']) && !(ops['c'] || ops['p'] || ops['f']))
-	return bin_zmodload_auto(nam, args, ops);
+	ret = bin_zmodload_auto(nam, args, ops);
     else if (ops['c'] && !(ops['b'] || ops['p']))
-	return bin_zmodload_cond(nam, args, ops);
+	ret = bin_zmodload_cond(nam, args, ops);
     else if (ops['f'] && !(ops['b'] || ops['p']))
-	return bin_zmodload_math(nam, args, ops);
+	ret = bin_zmodload_math(nam, args, ops);
     else if (ops['p'] && !(ops['b'] || ops['c']))
-	return bin_zmodload_param(nam, args, ops);
+	ret = bin_zmodload_param(nam, args, ops);
     else if (!(ops['a'] || ops['b'] || ops['c'] || ops['p']))
-	return bin_zmodload_load(nam, args, ops);
+	ret = bin_zmodload_load(nam, args, ops);
     else
 	zwarnnam(nam, "use only one of -b, -c, or -p", NULL, 0);
+    unqueue_signals();
 
-    return 1;
+    return ret;
 }
 
 /**/
@@ -1993,12 +2016,14 @@
 {
     Param pm;
 
+    queue_signals();
     if ((pm = (Param) gethashnode2(paramtab, nam)))
 	unsetparam_pm(pm, 0, 1);
 
     pm = setsparam(nam, ztrdup(module));
 
     pm->flags |= PM_AUTOLOAD;
+    unqueue_signals();
 }
 
 /* List of math functions. */
Index: Src/params.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/params.c,v
retrieving revision 1.29
diff -u -r1.29 params.c
--- Src/params.c	2000/11/25 23:50:02	1.29
+++ Src/params.c	2001/01/16 13:27:17
@@ -1806,6 +1806,7 @@
 	errflag = 1;
 	return NULL;
     }
+    queue_signals();
     if ((ss = strchr(s, '['))) {
 	*ss = '\0';
 	if (!(v = getvalue(&vbuf, &s, 1)))
@@ -1823,10 +1824,12 @@
 	}
     }
     if (!v && !(v = getvalue(&vbuf, &t, 1))) {
+	unqueue_signals();
 	zsfree(val);
 	return NULL;
     }
     setstrvalue(v, val);
+    unqueue_signals();
     return v->pm;
 }
 
@@ -1845,12 +1848,14 @@
 	errflag = 1;
 	return NULL;
     }
+    queue_signals();
     if ((ss = strchr(s, '['))) {
 	*ss = '\0';
 	if (!(v = getvalue(&vbuf, &s, 1)))
 	    createparam(t, PM_ARRAY);
 	*ss = '[';
 	if (v && PM_TYPE(v->pm->flags) == PM_HASHED) {
+	    unqueue_signals();
 	    zerr("attempt to set slice of associative array", NULL, 0);
 	    freearray(val);
 	    errflag = 1;
@@ -1869,9 +1874,12 @@
 	}
     }
     if (!v)
-	if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING)))
+	if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING))) {
+	    unqueue_signals();
 	    return NULL;
+	}
     setarrvalue(v, val);
+    unqueue_signals();
     return v->pm;
 }
 
@@ -1894,20 +1902,23 @@
 	zerr("nested associative arrays not yet supported", NULL, 0);
 	errflag = 1;
 	return NULL;
-    } else {
-	if (!(v = fetchvalue(&vbuf, &s, 1, SCANPM_ASSIGNING)))
-	    createparam(t, PM_HASHED);
-	else if (!(PM_TYPE(v->pm->flags) & PM_HASHED) &&
-		 !(v->pm->flags & PM_SPECIAL)) {
-	    unsetparam(t);
-	    createparam(t, PM_HASHED);
-	    v = NULL;
-	}
     }
+    queue_signals();
+    if (!(v = fetchvalue(&vbuf, &s, 1, SCANPM_ASSIGNING)))
+	createparam(t, PM_HASHED);
+    else if (!(PM_TYPE(v->pm->flags) & PM_HASHED) &&
+	     !(v->pm->flags & PM_SPECIAL)) {
+	unsetparam(t);
+	createparam(t, PM_HASHED);
+	v = NULL;
+    }
     if (!v)
-	if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING)))
+	if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING))) {
+	    unqueue_signals();
 	    return NULL;
+	}
     setarrvalue(v, val);
+    unqueue_signals();
     return v->pm;
 }
 
@@ -1926,6 +1937,7 @@
 	errflag = 1;
 	return NULL;
     }
+    queue_signals();
     if (!(v = getvalue(&vbuf, &s, 1))) {
 	if ((ss = strchr(s, '[')))
 	    *ss = '\0';
@@ -1937,12 +1949,14 @@
 	    DPUTS(!v, "BUG: value not found for new parameter");
 	} else {
 	    pm->u.val = val;
+	    unqueue_signals();
 	    return pm;
 	}
     }
     mnval.type = MN_INTEGER;
     mnval.u.l = val;
     setnumvalue(v, mnval);
+    unqueue_signals();
     return v->pm;
 }
 
@@ -1965,6 +1979,7 @@
 	errflag = 1;
 	return NULL;
     }
+    queue_signals();
     if (!(v = getvalue(&vbuf, &s, 1))) {
 	if ((ss = strchr(s, '[')))
 	    *ss = '\0';
@@ -1981,10 +1996,12 @@
 		pm->u.val = val.u.l;
 	    } else
 		pm->u.dval = val.u.d;
+	    unqueue_signals();
 	    return pm;
 	}
     }
     setnumvalue(v, val);
+    unqueue_signals();
     return v->pm;
 }
 
@@ -1996,10 +2013,12 @@
 {
     Param pm;
 
+    queue_signals();
     if ((pm = (Param) (paramtab == realparamtab ?
 		       gethashnode2(paramtab, s) :
 		       paramtab->getnode(paramtab, s))))
 	unsetparam_pm(pm, 0, 1);
+    unqueue_signals();
 }
 
 /* Unset a parameter */
@@ -2614,9 +2633,11 @@
     struct localename *ln;
 
     setlocale(LC_ALL, x ? x : "");
+    queue_signals();
     for (ln = lc_names; ln->name; ln++)
 	if ((x = getsparam(ln->name)))
 	    setlocale(ln->category, x);
+    unqueue_signals();
 }
 
 /**/
@@ -2624,8 +2645,11 @@
 lc_allsetfn(Param pm, char *x)
 {
     strsetfn(pm, x);
-    if (!x)
+    if (!x) {
+	queue_signals();
 	setlang(getsparam("LANG"));
+	unqueue_signals();
+    }
     else
 	setlocale(LC_ALL, x);
 }
@@ -2647,12 +2671,14 @@
     strsetfn(pm, x);
     if (getsparam("LC_ALL"))
 	return;
+    queue_signals();
     if (!x)
 	x = getsparam("LANG");
 
     for (ln = lc_names; ln->name; ln++)
 	if (!strcmp(ln->name, pm->nam))
 	    setlocale(ln->category, x ? x : "");
+    unqueue_signals();
 }
 #endif /* USE_LOCALE */
 
Index: Src/parse.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/parse.c,v
retrieving revision 1.15
diff -u -r1.15 parse.c
--- Src/parse.c	2000/12/05 10:34:23	1.15
+++ Src/parse.c	2001/01/16 13:27:18
@@ -2312,7 +2312,7 @@
 int
 bin_zcompile(char *nam, char **args, char *ops, int func)
 {
-    int map, flags;
+    int map, flags, ret;
     char *dump;
 
     if ((ops['k'] && ops['z']) || (ops['R'] && ops['M']) ||
@@ -2359,15 +2359,22 @@
     }
     map = (ops['M'] ? 2 : (ops['R'] ? 0 : 1));
 
-    if (!args[1] && !(ops['c'] || ops['a']))
-	return build_dump(nam, dyncat(*args, FD_EXT), args, ops['U'], map, flags);
-
+    if (!args[1] && !(ops['c'] || ops['a'])) {
+	queue_signals();
+	ret = build_dump(nam, dyncat(*args, FD_EXT), args, ops['U'], map, flags);
+	unqueue_signals();
+	return ret;
+    }
     dump = (strsfx(FD_EXT, *args) ? *args : dyncat(*args, FD_EXT));
 
-    return ((ops['c'] || ops['a']) ?
-	    build_cur_dump(nam, dump, args + 1, ops['m'], map,
-			   (ops['c'] ? 1 : 0) | (ops['a'] ? 2 : 0)) :
-	    build_dump(nam, dump, args + 1, ops['U'], map, flags));
+    queue_signals();
+    ret = ((ops['c'] || ops['a']) ?
+	   build_cur_dump(nam, dump, args + 1, ops['m'], map,
+			  (ops['c'] ? 1 : 0) | (ops['a'] ? 2 : 0)) :
+	   build_dump(nam, dump, args + 1, ops['U'], map, flags));
+    unqueue_signals();
+
+    return ret;
 }
 
 /* Load the header of a dump file. Returns NULL if the file isn't a
@@ -2824,10 +2831,13 @@
     struct stat std, stc, stn;
     int rd, rc, rn;
     char *dig, *wc;
-
-    if (strsfx(FD_EXT, path))
-	return check_dump_file(path, NULL, name, ksh);
 
+    if (strsfx(FD_EXT, path)) {
+	queue_signals();
+	prog = check_dump_file(path, NULL, name, ksh);
+	unqueue_signals();
+	return prog;
+    }
     dig = dyncat(path, FD_EXT);
     wc = dyncat(file, FD_EXT);
 
@@ -2839,20 +2849,24 @@
      * both the uncompiled function file and its compiled version (or they
      * don't exist) and the digest file contains the definition for the
      * function. */
+    queue_signals();
     if (!rd &&
 	(rc || std.st_mtime > stc.st_mtime) &&
 	(rn || std.st_mtime > stn.st_mtime) &&
-	(prog = check_dump_file(dig, &std, name, ksh)))
+	(prog = check_dump_file(dig, &std, name, ksh))) {
+	unqueue_signals();
 	return prog;
-
+    }
     /* No digest file. Now look for the per-function compiled file. */
     if (!rc &&
 	(rn || stc.st_mtime > stn.st_mtime) &&
-	(prog = check_dump_file(wc, &stc, name, ksh)))
+	(prog = check_dump_file(wc, &stc, name, ksh))) {
+	unqueue_signals();
 	return prog;
-
+    }
     /* No compiled file for the function. The caller (getfpfunc() will
      * check if the directory contains the uncompiled file for it. */
+    unqueue_signals();
     return NULL;
 }
 
@@ -2872,18 +2886,24 @@
     else
 	tail = file;
 
-    if (strsfx(FD_EXT, file))
-	return check_dump_file(file, NULL, tail, NULL);
-
+    if (strsfx(FD_EXT, file)) {
+	queue_signals();
+	prog = check_dump_file(file, NULL, tail, NULL);
+	unqueue_signals();
+	return prog;
+    }
     wc = dyncat(file, FD_EXT);
 
     rc = stat(wc, &stc);
     rn = stat(file, &stn);
 
+    queue_signals();
     if (!rc && (rn || stc.st_mtime > stn.st_mtime) &&
-	(prog = check_dump_file(wc, &stc, tail, NULL)))
+	(prog = check_dump_file(wc, &stc, tail, NULL))) {
+	unqueue_signals();
 	return prog;
-
+    }
+    unqueue_signals();
     return NULL;
 }
 
Index: Src/prompt.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/prompt.c,v
retrieving revision 1.3
diff -u -r1.3 prompt.c
--- Src/prompt.c	2000/07/13 17:06:19	1.3
+++ Src/prompt.c	2001/01/16 13:27:18
@@ -372,12 +372,15 @@
 		bp += strlen(bp);
 		break;
 	    case 'M':
+		queue_signals();
 		if ((hostnam = getsparam("HOST")))
 		    stradd(hostnam);
+		unqueue_signals();
 		break;
 	    case 'm':
 		if (!arg)
 		    arg++;
+		queue_signals();
 		if (!(hostnam = getsparam("HOST")))
 		    break;
 		if (arg < 0) {
@@ -394,6 +397,7 @@
 		    stradd(hostnam);
 		    *ss = t0;
 		}
+		unqueue_signals();
 		break;
 	    case 'S':
 		txtchangeset(TXTSTANDOUT, TXTNOSTANDOUT);
Index: Src/signals.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/signals.c,v
retrieving revision 1.13
diff -u -r1.13 signals.c
--- Src/signals.c	2000/11/11 19:50:29	1.13
+++ Src/signals.c	2001/01/16 13:27:18
@@ -497,7 +497,7 @@
  
     case SIGHUP:
         if (sigtrapped[SIGHUP])
-            dotrap(SIGHUP, 0);
+            dotrap(SIGHUP);
         else {
             stopmsg = 1;
             zexit(SIGHUP, 1);
@@ -506,7 +506,7 @@
  
     case SIGINT:
         if (sigtrapped[SIGINT])
-            dotrap(SIGINT, 0);
+            dotrap(SIGINT);
         else {
 	    if ((isset(PRIVILEGED) || isset(RESTRICTED)) &&
 		isset(INTERACTIVE) && noerrexit < 0)
@@ -523,14 +523,14 @@
     case SIGWINCH:
         adjustwinsize(1);  /* check window size and adjust */
 	if (sigtrapped[SIGWINCH])
-	    dotrap(SIGWINCH, 0);
+	    dotrap(SIGWINCH);
         break;
 #endif
 
     case SIGALRM:
         if (sigtrapped[SIGALRM]) {
 	    int tmout;
-            dotrap(SIGALRM, 0);
+            dotrap(SIGALRM);
 
 	    if ((tmout = getiparam("TMOUT")))
 		alarm(tmout);           /* reset the alarm */
@@ -549,7 +549,7 @@
         break;
  
     default:
-        dotrap(sig, 0);
+        dotrap(sig);
         break;
     }   /* end of switch(sig) */
  
@@ -703,6 +703,7 @@
      * Call unsettrap() unconditionally, to make sure trap is saved
      * if necessary.
      */
+    queue_signals();
     unsettrap(sig);
 
     sigfuncs[sig] = l;
@@ -729,6 +730,7 @@
      * works just the same.
      */
     sigtrapped[sig] |= (locallevel << ZSIG_SHIFT);
+    unqueue_signals();
     return 0;
 }
 
@@ -736,9 +738,13 @@
 void
 unsettrap(int sig)
 {
-    HashNode hn = removetrap(sig);
+    HashNode hn;
+
+    queue_signals();
+    hn = removetrap(sig);
     if (hn)
 	shfunctab->freenode(hn);
+    unqueue_signals();
 }
 
 /**/
@@ -751,6 +757,7 @@
 	(jobbing && (sig == SIGTTOU || sig == SIGTSTP || sig == SIGTTIN)))
 	return NULL;
 
+    queue_signals();
     trapped = sigtrapped[sig];
     /*
      * Note that we save the trap here even if there isn't an existing
@@ -762,9 +769,10 @@
 	(!trapped || locallevel > (sigtrapped[sig] >> ZSIG_SHIFT)))
 	dosavetrap(sig, locallevel);
 
-    if (!trapped)
+    if (!trapped) {
+	unqueue_signals();
         return NULL;
-
+    }
     sigtrapped[sig] = 0;
     if (sig == SIGINT && interact) {
 	/* PWS 1995/05/16:  added test for interactive, also noholdintr() *
@@ -790,6 +798,7 @@
      */
     if (trapped & ZSIG_FUNC) {
 	char func[20];
+	HashNode node;
 
 	sprintf(func, "TRAP%s", sigs[sig]);
 	/*
@@ -797,11 +806,15 @@
 	 * that calls back into unsettrap();
 	 */
 	sigfuncs[sig] = NULL;
-	return removehashnode(shfunctab, func);
+	node = removehashnode(shfunctab, func);
+	unqueue_signals();
+
+	return node;
     } else if (sigfuncs[sig]) {
 	freeeprog(sigfuncs[sig]);
 	sigfuncs[sig] = NULL;
     }
+    unqueue_signals();
 
     return NULL;
 }
@@ -965,57 +978,16 @@
     if (*sigtr != ZSIG_IGNORED)
 	*sigtr &= ~ZSIG_IGNORED;
 }
-
-/* != 0 if trap handlers can be called immediately */
-
-/**/
-mod_export int trapsallowed;
-
-/* Queued traps and allocated length of queue. */
-
-static int *trapqueue, trapqlen;
-
-/* Number of used slots in trap queue. */
 
-/**/
-mod_export int trapqused;
-
-/* Standard call to execute a trap for a given signal.  The second
- * argument should be zero if we may need to put the trap on the queue
- * and 1 if it may be called immediately.  It should never be set to
- * anything less than zero, that's used internally. */
+/* Standard call to execute a trap for a given signal. */
 
 /**/
 void
-dotrap(int sig, int now)
+dotrap(int sig)
 {
     /* Copied from dotrapargs(). */
     if ((sigtrapped[sig] & ZSIG_IGNORED) || !sigfuncs[sig] || errflag)
 	return;
-
-    if (now || trapsallowed) {
-	if (now < 0)
-	    RUNTRAPS();
-	dotrapargs(sig, sigtrapped+sig, sigfuncs[sig]);
-    } else {
-	if (trapqlen == trapqused)
-	    trapqueue = (int *) zrealloc(trapqueue, (trapqlen += 32));
-	trapqueue[trapqused++] = sig;
-    }
-}
 
-/**/
-mod_export void
-doqueuedtraps(void)
-{
-    int sig, ota = trapsallowed;
-
-    trapsallowed = 1;
-    while (trapqused) {
-	trapqused--;
-	sig = *trapqueue;
-	memcpy(trapqueue, trapqueue + 1, trapqused * sizeof(int));
-	dotrap(sig, -1);
-    }
-    trapsallowed = ota;
+    dotrapargs(sig, sigtrapped+sig, sigfuncs[sig]);
 }
Index: Src/signals.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/signals.h,v
retrieving revision 1.2
diff -u -r1.2 signals.h
--- Src/signals.h	2000/11/11 19:50:29	1.2
+++ Src/signals.h	2001/01/16 13:27:18
@@ -73,27 +73,35 @@
  * queue signals, it is probably overkill for zsh to do  *
  * this, but it shouldn't hurt anything to do it anyway. */
 
-/* Right now I'm queueing all signals, but maybe we only *
- * need to queue SIGCHLD.  Anybody know?                 */
+#define MAX_QUEUE_SIZE 128
 
-#define MAX_QUEUE_SIZE 16
-
 #define queue_signals()    (queueing_enabled++)
 
+#define run_queued_signals() do { \
+    while (queue_front != queue_rear) {      /* while signals in queue */ \
+	sigset_t oset; \
+	queue_front = (queue_front + 1) % MAX_QUEUE_SIZE; \
+	oset = signal_setmask(signal_mask_queue[queue_front]); \
+	handler(signal_queue[queue_front]);  /* handle queued signal   */ \
+	signal_setmask(oset); \
+    } \
+} while (0)
+
 #define unqueue_signals()  do { \
     DPUTS(!queueing_enabled, "BUG: unqueue_signals called but not queueing"); \
-    if (!--queueing_enabled) { \
-	while (queue_front != queue_rear) {      /* while signals in queue */ \
-	    sigset_t oset; \
-	    queue_front = (queue_front + 1) % MAX_QUEUE_SIZE; \
-	    oset = signal_setmask(signal_mask_queue[queue_front]); \
-	    handler(signal_queue[queue_front]);  /* handle queued signal   */ \
-	    signal_setmask(oset); \
-	} \
-    } \
+    if (!--queueing_enabled) run_queued_signals(); \
 } while (0)
 
+#define queue_signal_level() queueing_enabled
 
+#define dont_queue_signals() do { \
+    queueing_enabled = 0; \
+    run_queued_signals(); \
+} while (0)
+
+#define restore_queue_signals(q) (queueing_enabled = (q))
+
+
 /* Make some signal functions faster. */
 
 #ifdef POSIX_SIGNALS
@@ -117,9 +125,3 @@
 #else
 extern sigset_t signal_unblock _((sigset_t));
 #endif   /* POSIX_SIGNALS */
-
-#define RUNTRAPS() do { if (trapqused) doqueuedtraps(); } while (0)
-#define ALLOWTRAPS do { RUNTRAPS(); trapsallowed++; do
-#define DISALLOWTRAPS while (0); RUNTRAPS(); trapsallowed--; } while (0)
-#define ALLOWTRAPS_RETURN(V) \
-    do { RUNTRAPS(); trapsallowed--; return (V); } while (0)
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.12
diff -u -r1.12 subst.c
--- Src/subst.c	2000/06/17 19:51:51	1.12
+++ Src/subst.c	2001/01/16 13:27:19
@@ -51,6 +51,7 @@
 {
     LinkNode node;
 
+    queue_signals();
     for (node = firstnode(list); node; incnode(node)) {
 	char *str, c;
 
@@ -61,14 +62,18 @@
 		setdata(node, (void *) getproc(str));	/* <(...) or >(...) */
 	    else
 		setdata(node, (void *) getoutputfile(str));	/* =(...) */
-	    if (!getdata(node))
+	    if (!getdata(node)) {
+		unqueue_signals();
 		return;
+	    }
 	} else {
 	    if (isset(SHFILEEXPANSION))
 		filesub((char **)getaddrdata(node),
 			flags & (PF_TYPESET|PF_ASSIGN));
-	    if (!(node = stringsubst(list, node, flags & PF_SINGLE)))
+	    if (!(node = stringsubst(list, node, flags & PF_SINGLE))) {
+		unqueue_signals();
 		return;
+	    }
 	}
     }
     for (node = firstnode(list); node; incnode(node)) {
@@ -82,9 +87,12 @@
 			flags & (PF_TYPESET|PF_ASSIGN));
 	} else if (!(flags & PF_SINGLE))
 	    uremnode(list, node);
-	if (errflag)
+	if (errflag) {
+	    unqueue_signals();
 	    return;
+	}
     }
+    unqueue_signals();
 }
 
 /**/
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.27
diff -u -r1.27 utils.c
--- Src/utils.c	2000/11/29 08:04:28	1.27
+++ Src/utils.c	2001/01/16 13:27:20
@@ -691,12 +691,16 @@
 
 	if (mailpath && *mailpath && **mailpath)
 	    checkmailpath(mailpath);
-	else if ((mailfile = getsparam("MAIL")) && *mailfile) {
-	    char *x[2];
-
-	    x[0] = mailfile;
-	    x[1] = NULL;
-	    checkmailpath(x);
+	else {
+	    queue_signals();
+	    if ((mailfile = getsparam("MAIL")) && *mailfile) {
+		char *x[2];
+
+		x[0] = mailfile;
+		x[1] = NULL;
+		checkmailpath(x);
+	    }
+	    unqueue_signals();
 	}
 	lastmailcheck = time(NULL);
     }
@@ -1091,17 +1095,21 @@
 mod_export char *
 gettempname(void)
 {
-    char *s;
+    char *s, *ret;
  
+    queue_signals();
     if (!(s = getsparam("TMPPREFIX")))
 	s = DEFAULT_TMPPREFIX;
  
 #ifdef HAVE__MKTEMP
     /* Zsh uses mktemp() safely, so silence the warnings */
-    return ((char *) _mktemp(dyncat(unmeta(s), "XXXXXX")));
+    ret = ((char *) _mktemp(dyncat(unmeta(s), "XXXXXX")));
 #else
-    return ((char *) mktemp(dyncat(unmeta(s), "XXXXXX")));
+    ret = ((char *) mktemp(dyncat(unmeta(s), "XXXXXX")));
 #endif
+    unqueue_signals();
+
+    return ret;
 }
 
 /* Check if a string contains a token */
@@ -1418,38 +1426,12 @@
 }
 
 /**/
-mod_export int
-ztrapread(int fd, char *buf, int len)
-{
-    int ret;
-
-    ALLOWTRAPS {
-	ret = read(fd, buf, len);
-    } DISALLOWTRAPS;
-
-    return ret;
-}
-
-/**/
-mod_export int
-ztrapwrite(int fd, char *buf, int len)
-{
-    int ret;
-
-    ALLOWTRAPS {
-	ret = write(fd, buf, len);
-    } DISALLOWTRAPS;
-
-    return ret;
-}
-
-/**/
 int
 read1char(void)
 {
     char c;
 
-    while (ztrapread(SHTTY, &c, 1) != 1) {
+    while (read(SHTTY, &c, 1) != 1) {
 	if (errno != EINTR || errflag || retflag || breaks || contflag)
 	    return -1;
     }
@@ -1467,7 +1449,7 @@
     ioctl(SHTTY, FIONREAD, (char *)&val);
     if (purge) {
 	for (; val; val--)
-	    ztrapread(SHTTY, &c, 1);
+	    read(SHTTY, &c, 1);
     }
 #endif
 
@@ -2122,12 +2104,14 @@
 zbeep(void)
 {
     char *vb;
+    queue_signals();
     if ((vb = getsparam("ZBEEP"))) {
 	int len;
 	vb = getkeystring(vb, &len, 2, NULL);
 	write(SHTTY, vb, len);
     } else if (isset(BEEP))
 	write(SHTTY, "\07", 1);
+    unqueue_signals();
 }
 
 /**/
Index: Src/watch.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/watch.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 watch.c
--- Src/watch.c	1999/04/15 18:12:08	1.1.1.2
+++ Src/watch.c	2001/01/16 13:27:20
@@ -491,8 +491,6 @@
     int uct, wct;
 
     s = watch;
-    if (!(fmt = getsparam("WATCHFMT")))
-	fmt = DEFAULT_WATCHFMT;
 
     holdintr();
     if (!wtab) {
@@ -542,6 +540,9 @@
 	free(utab);
 	return;
     }
+    queue_signals();
+    if (!(fmt = getsparam("WATCHFMT")))
+	fmt = DEFAULT_WATCHFMT;
     while ((uct || wct) && !errflag)
 	if (!uct || (wct && ucmp(uptr, wptr) > 0))
 	    wct--, watchlog(0, wptr++, s, fmt);
@@ -549,6 +550,7 @@
 	    uct--, watchlog(1, uptr++, s, fmt);
 	else
 	    uptr++, wptr++, wct--, uct--;
+    unqueue_signals();
     free(wtab);
     wtab = utab;
     wtabsz = utabsz;
Index: Src/Modules/zftp.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/zftp.c,v
retrieving revision 1.9
diff -u -r1.9 zftp.c
--- Src/Modules/zftp.c	2000/12/17 21:47:54	1.9
+++ Src/Modules/zftp.c	2001/01/16 13:27:21
@@ -801,7 +801,7 @@
 		cmdbuf[0] = (char)IAC;
 		cmdbuf[1] = (char)DONT;
 		cmdbuf[2] = ch;
-		ztrapwrite(zfsess->cfd, cmdbuf, 3);
+		write(zfsess->cfd, cmdbuf, 3);
 		continue;
 
 	    case DO:
@@ -811,7 +811,7 @@
 		cmdbuf[0] = (char)IAC;
 		cmdbuf[1] = (char)WONT;
 		cmdbuf[2] = ch;
-		ztrapwrite(zfsess->cfd, cmdbuf, 3);
+		write(zfsess->cfd, cmdbuf, 3);
 		continue;
 
 	    case EOF:
@@ -863,8 +863,6 @@
 
     if (zfsess->cfd == -1)
 	return 6;
-    if (!(verbose = getsparam("ZFTP_VERBOSE")))
-	verbose = "";
     zsfree(lastmsg);
     lastmsg = NULL;
 
@@ -890,6 +888,9 @@
     zfsetparam("ZFTP_CODE", ztrdup(lastcodestr), ZFPM_READONLY);
     stopit = (*ptr++ != '-');
 
+    queue_signals();
+    if (!(verbose = getsparam("ZFTP_VERBOSE")))
+	verbose = "";
     if (strchr(verbose, lastcodestr[0])) {
 	/* print the whole thing verbatim */
 	printing = 1;
@@ -899,6 +900,7 @@
 	printing = 2;
 	fputs(ptr, stderr);
     }
+    unqueue_signals();
     if (printing)
 	fputc('\n', stderr);
 
@@ -996,7 +998,7 @@
 	return 6;
     }
     zfalarm(tmout);
-    ret = ztrapwrite(zfsess->cfd, cmd, strlen(cmd));
+    ret = write(zfsess->cfd, cmd, strlen(cmd));
     alarm(0);
 
     if (ret <= 0) {
@@ -1470,7 +1472,7 @@
     int ret;
 
     if (!tmout)
-	return ztrapread(fd, bf, sz);
+	return read(fd, bf, sz);
 
     if (setjmp(zfalrmbuf)) {
 	alarm(0);
@@ -1479,7 +1481,7 @@
     }
     zfalarm(tmout);
 
-    ret = ztrapread(fd, bf, sz);
+    ret = read(fd, bf, sz);
 
     /* we don't bother turning off the whole alarm mechanism here */
     alarm(0);
@@ -1495,7 +1497,7 @@
     int ret;
 
     if (!tmout)
-	return ztrapwrite(fd, bf, sz);
+	return write(fd, bf, sz);
 
     if (setjmp(zfalrmbuf)) {
 	alarm(0);
@@ -1504,7 +1506,7 @@
     }
     zfalarm(tmout);
 
-    ret = ztrapwrite(fd, bf, sz);
+    ret = write(fd, bf, sz);
 
     /* we don't bother turning off the whole alarm mechanism here */
     alarm(0);
@@ -1894,10 +1896,12 @@
     if (setjmp(zfalrmbuf)) {
 	char *hname;
 	alarm(0);
+	queue_signals();
 	if ((hname = getsparam("ZFTP_HOST")) && *hname) 
 	    zwarnnam(name, "timeout connecting to %s", hname, 0);
 	else
 	    zwarnnam(name, "timeout on host name lookup", NULL, 0);
+	unqueue_signals();
 	zfclose(0);
 	return 1;
     }
@@ -2846,7 +2850,7 @@
 	if (!zfnopen) {
 	    /* Write the final status in case this is a subshell */
 	    lseek(zfstatfd, zfsessno*sizeof(int), 0);
-	    ztrapwrite(zfstatfd, (char *)zfstatusp+zfsessno, sizeof(int));
+	    write(zfstatfd, (char *)zfstatusp+zfsessno, sizeof(int));
 
 	    close(zfstatfd);
 	    zfstatfd = -1;
@@ -2933,10 +2937,12 @@
     for (ps = zfparams, pd = zfsess->params; *ps; ps++, pd++) {
 	if (*pd)
 	    zsfree(*pd);
+	queue_signals();
 	if ((val = getsparam(*ps)))
 	    *pd = ztrdup(val);
 	else
 	    *pd = NULL;
+	unqueue_signals();
     }
     *pd = NULL;
 }
@@ -3123,7 +3129,7 @@
 	/* Get the status in case it was set by a forked process */
 	int oldstatus = zfstatusp[zfsessno];
 	lseek(zfstatfd, 0, 0);
-	ztrapread(zfstatfd, (char *)zfstatusp, sizeof(int)*zfsesscnt);
+	read(zfstatfd, (char *)zfstatusp, sizeof(int)*zfsesscnt);
 	if (zfsess->cfd != -1 && (zfstatusp[zfsessno] & ZFST_CLOS)) {
 	    /* got closed in subshell without us knowing */
 	    zcfinish = 2;
@@ -3166,6 +3172,7 @@
 	return 1;
     }
 
+    queue_signals();
     if ((prefs = getsparam("ZFTP_PREFS"))) {
 	zfprefs = 0;
 	for (ptr = prefs; *ptr; ptr++) {
@@ -3196,6 +3203,7 @@
 	    }
 	}
     }
+    unqueue_signals();
 
     ret = (*zptr->fun)(fullname, args, zptr->flags);
 
@@ -3212,7 +3220,7 @@
 	 * but only for the active session.
 	 */
 	lseek(zfstatfd, zfsessno*sizeof(int), 0);
-	ztrapwrite(zfstatfd, (char *)zfstatusp+zfsessno, sizeof(int));
+	write(zfstatfd, (char *)zfstatusp+zfsessno, sizeof(int));
     }
     return ret;
 }
Index: Src/Modules/zpty.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/zpty.c,v
retrieving revision 1.20
diff -u -r1.20 zpty.c
--- Src/Modules/zpty.c	2000/11/14 11:51:29	1.20
+++ Src/Modules/zpty.c	2001/01/16 13:27:21
@@ -539,7 +539,7 @@
 
     for (; !errflag && !breaks && !retflag && !contflag && len;
 	 len -= written, s += written) {
-	if ((written = ztrapwrite(cmd->fd, s, len)) < 0 && cmd->nblock &&
+	if ((written = write(cmd->fd, s, len)) < 0 && cmd->nblock &&
 #ifdef EWOULDBLOCK
 	    errno == EWOULDBLOCK
 #else
@@ -583,7 +583,7 @@
 	int n;
 	char buf[BUFSIZ];
 
-	while ((n = ztrapread(0, buf, BUFSIZ)) > 0)
+	while ((n = read(0, buf, BUFSIZ)) > 0)
 	    if (ptywritestr(cmd, buf, n))
 		return 1;
     }
Index: Src/Modules/zutil.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/zutil.c,v
retrieving revision 1.7
diff -u -r1.7 zutil.c
--- Src/Modules/zutil.c	2000/06/16 07:31:10	1.7
+++ Src/Modules/zutil.c	2001/01/16 13:27:22
@@ -219,12 +219,14 @@
     }
     errflag = ef;
 
+    queue_signals();
     if ((ret = getaparam("reply")))
 	ret = arrdup(ret);
     else if ((str = getsparam("reply"))) {
 	ret = (char **) hcalloc(2 * sizeof(char *));
 	ret[0] = dupstring(str);
     }
+    unqueue_signals();
     unsetparam("reply");
 
     return ret;
@@ -725,12 +727,14 @@
 {
     char **a;
 
+    queue_signals();
     a = getaparam("match");
     m->match = a ? zarrdup(a) : NULL;
     a = getaparam("mbegin");
     m->mbegin = a ? zarrdup(a) : NULL;
     a = getaparam("mend");
     m->mend = a ? zarrdup(a) : NULL;
+    unqueue_signals();
 }
 
 static void
@@ -1078,8 +1082,13 @@
 	    if (next->pattern && pattry(next->patprog, subj) &&
 		(!next->guard || (execstring(next->guard, 1, 0), !lastval))) {
 		LinkNode aln;
-		char **mend = getaparam("mend");
-		int len = atoi(mend[0]);
+		char **mend;
+		int len;
+
+		queue_signals();
+		mend = getaparam("mend");
+		len = atoi(mend[0]);
+		unqueue_signals();
 
 		for (i = len; i; i--)
 		  if (*subj++ == Meta)
Index: Src/Zle/compcore.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/compcore.c,v
retrieving revision 1.42
diff -u -r1.42 compcore.c
--- Src/Zle/compcore.c	2001/01/08 15:25:04	1.42
+++ Src/Zle/compcore.c	2001/01/16 13:27:23
@@ -1526,14 +1526,15 @@
 	/* Otherwise it should be a parameter name. */
 	char **arr = NULL, *val;
 
+	queue_signals();
 	if ((arr = getaparam(nam)) || (arr = gethparam(nam)))
-	    return (incompfunc ? arrdup(arr) : arr);
-
-	if ((val = getsparam(nam))) {
+	    arr = (incompfunc ? arrdup(arr) : arr);
+	else if ((val = getsparam(nam))) {
 	    arr = (char **) zhalloc(2*sizeof(char *));
 	    arr[0] = (incompfunc ? dupstring(val) : val);
 	    arr[1] = NULL;
 	}
+	unqueue_signals();
 	return arr;
     }
 }
@@ -1542,14 +1543,19 @@
 get_data_arr(char *name, int keys)
 {
     struct value vbuf;
+    char **ret;
     Value v;
 
+    queue_signals();
     if (!(v = fetchvalue(&vbuf, &name, 1,
 			 (keys ? SCANPM_WANTKEYS : SCANPM_WANTVALS) |
 			 SCANPM_MATCHMANY)))
-	return NULL;
+	ret = NULL;
+    else
+	ret = getarrvalue(v);
+    unqueue_signals();
 
-    return getarrvalue(v);
+    return ret;
 }
 
 /* This is used by compadd to add a couple of matches. The arguments are
Index: Src/Zle/complist.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/complist.c,v
retrieving revision 1.37
diff -u -r1.37 complist.c
--- Src/Zle/complist.c	2000/10/25 10:52:25	1.37
+++ Src/Zle/complist.c	2001/01/16 13:27:23
@@ -340,6 +340,7 @@
     int i, l;
 
     max_caplen = lr_caplen = 0;
+    queue_signals();
     if (!(s = getsparam("ZLS_COLORS")) &&
 	!(s = getsparam("ZLS_COLOURS"))) {
 	for (i = 0; i < NUM_COLS; i++)
@@ -356,6 +357,7 @@
 	if ((max_caplen = strlen(c->files[COL_MA]->col)) <
 	    (l = strlen(c->files[COL_EC]->col)))
 	    max_caplen = l;
+	unqueue_signals();
 	return;
     }
     /* We have one of the parameters, use it. */
@@ -366,6 +368,7 @@
 	    s++;
 	else
 	    s = getcoldef(c, s);
+    unqueue_signals();
 
     /* Use default values for those that aren't set explicitly. */
     for (i = 0; i < NUM_COLS; i++) {
@@ -1528,8 +1531,10 @@
     mscroll = 0;
     mlistp = NULL;
 
+    queue_signals();
     if (mselect >= 0 || mlbeg >= 0 ||
-	(mlistp = getsparam("LISTPROMPT"))) {
+	(mlistp = dupstring(getsparam("LISTPROMPT")))) {
+	unqueue_signals();
 	if (mlistp && !*mlistp)
 	    mlistp = "%SAt %p: Hit TAB for more, or the character to insert%s";
 	trashzle();
@@ -1545,6 +1550,7 @@
 	    minfo.asked = (listdat.nlines + nlnct <= lines);
 	}
     } else {
+	unqueue_signals();
 	mlistp = NULL;
 	if (asklist()) {
 	    amatches = oamatches;
@@ -1641,6 +1647,7 @@
     int nolist = 0;
     char *s;
 
+    queue_signals();
     if (fdat || (dummy && (!(s = getsparam("MENUSELECT")) ||
 			   (dat && dat->num < atoi(s))))) {
 	if (fdat) {
@@ -1648,6 +1655,7 @@
 	    fdat->num = dat->num;
 	    fdat->nmesg = dat->nmesg;
 	}
+	unqueue_signals();
 	return 0;
     }
     if ((s = getsparam("MENUSCROLL"))) {
@@ -1659,6 +1667,7 @@
     }
     if ((mstatus = dupstring(getsparam("MENUPROMPT"))) && !*mstatus)
 	mstatus = "%SScrolling active: current selection at %p%s";
+    unqueue_signals();
     mhasstat = (mstatus && *mstatus);
     fdat = dat;
     selectlocalmap(mskeymap);
Index: Src/Zle/computil.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/computil.c,v
retrieving revision 1.44
diff -u -r1.44 computil.c
--- Src/Zle/computil.c	2000/10/17 14:04:13	1.44
+++ Src/Zle/computil.c	2001/01/16 13:27:24
@@ -2606,6 +2606,7 @@
 
     while ((name = *args++)) {
 	name = dupstring(name);
+	queue_signals();
 	if ((v = getvalue(&vbuf, &name, 0))) {
 	    switch (PM_TYPE(v->pm->flags)) {
 	    case PM_SCALAR:
@@ -2630,6 +2631,7 @@
 	    }
 	} else
 	    zwarnnam(nam, "unknown parameter: %s", args[-1], 0);
+	unqueue_signals();
     }
     return 0;
 }
@@ -3580,6 +3582,7 @@
 		zwarnnam(nam, "too few arguments", NULL, 0);
 		return 1;
 	    }
+	    queue_signals();
 	    if (!(tmp = getaparam(args[1]))) {
 		zwarnnam(nam, "unknown parameter: %s", args[1], 0);
 		return 0;
@@ -3590,6 +3593,7 @@
 					    l, getaparam(args[2]), args[3],
 					    args[4], args[5],
 					    getaparam(args[6]), args + 7));
+	    unqueue_signals();
 	    return 0;
 	}
     case 'i':
@@ -3608,16 +3612,19 @@
 		zwarnnam(nam, "too many arguments", NULL, 0);
 		return 1;
 	    }
+	    queue_signals();
 	    tmp = getaparam(args[2]);
 	    l = newlinklist();
 	    if (tmp)
 		for (; *tmp; tmp++)
 		    addlinknode(l, *tmp);
 	    if (!(tmp = getaparam(args[1]))) {
+		unqueue_signals();
 		zwarnnam(nam, "unknown parameter: %s", args[1], 0);
 		return 0;
 	    }
 	    cf_ignore(tmp, l, args[3], args[4]);
+	    unqueue_signals();
 	    set_list_array(args[2], l);
 	    return 0;
 	}
@@ -3635,12 +3642,15 @@
 		zwarnnam(nam, "too many arguments", NULL, 0);
 		return 1;
 	    }
+	    queue_signals();
 	    if (!(tmp = getaparam(args[1]))) {
+		unqueue_signals();
 		zwarnnam(nam, "unknown parameter: %s", args[1], 0);
 		return 0;
 	    }
 	    if ((l = cf_remove_other(tmp, args[2], &ret)))
 		set_list_array(args[1], l);
+	    unqueue_signals();
 	    return ret;
 	}
     }
Index: Src/Zle/zle_main.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_main.c,v
retrieving revision 1.14
diff -u -r1.14 zle_main.c
--- Src/Zle/zle_main.c	2000/11/11 19:50:29	1.14
+++ Src/Zle/zle_main.c	2001/01/16 13:27:25
@@ -313,17 +313,12 @@
 breakread(int fd, char *buf, int n)
 {
     fd_set f;
-    int ret;
 
     FD_ZERO(&f);
     FD_SET(fd, &f);
 
-    ALLOWTRAPS {
-	ret = (select(fd + 1, (SELECT_ARG_2_T) & f, NULL, NULL, NULL) == -1 ?
-	       EOF : read(fd, buf, n));
-    } DISALLOWTRAPS;
-
-    return ret;
+    return (select(fd + 1, (SELECT_ARG_2_T) & f, NULL, NULL, NULL) == -1 ?
+	    EOF : read(fd, buf, n));
 }
 
 # define read    breakread
@@ -394,7 +389,7 @@
 #  else
 	    ioctl(SHTTY, TCSETA, &ti.tio);
 #  endif
-	    r = ztrapread(SHTTY, &cc, 1);
+	    r = read(SHTTY, &cc, 1);
 #  ifdef HAVE_TERMIOS_H
 	    tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio);
 #  else
@@ -405,7 +400,7 @@
 #endif
 	}
 	for (;;) {
-	    r = ztrapread(SHTTY, &cc, 1);
+	    r = read(SHTTY, &cc, 1);
 	    if (r == 1)
 		break;
 	    if (r == 0) {
@@ -664,8 +659,11 @@
 		ret = completecall(args);
 		if (atcurhist)
 		    histline = curhist;
-	    } else
+	    } else {
+		queue_signals();
 		ret = w->u.fn(args);
+		unqueue_signals();
+	    }
 	    if (!(wflags & ZLE_NOTCOMMAND))
 		lastcmd = wflags;
 	}
@@ -836,9 +834,11 @@
     }
     /* handle non-existent parameter */
     s = args[0];
+    queue_signals();
     v = fetchvalue(&vbuf, &s, (!create || type == PM_SCALAR),
 		   SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY);
     if (!v && !create) {
+	unqueue_signals();
 	zwarnnam(name, "no such variable: %s", args[0], 0);
 	return 1;
     } else if (v) {
@@ -885,11 +885,13 @@
 	} else {
 	    s = ztrdup(getstrvalue(v));
 	}
-	pm = v->pm;
+	unqueue_signals();
     } else if (*s) {
+	unqueue_signals();
 	zwarnnam(name, "invalid parameter name: %s", args[0], 0);
 	return 1;
     } else {
+	unqueue_signals();
 	s = ztrdup(s);
     }
 
@@ -935,14 +937,12 @@
     if (t[strlen(t) - 1] == '\n')
 	t[strlen(t) - 1] = '\0';
     /* final assignment of parameter value */
-    if (create && (!pm || (type && PM_TYPE(pm->flags) != type))) {
-	if (pm)
-	    unsetparam(args[0]);
+    if (create) {
+	unsetparam(args[0]);
 	createparam(args[0], type);
-	pm = 0;
     }
-    if (!pm)
-	pm = (Param) paramtab->getnode(paramtab, args[0]);
+    queue_signals();
+    pm = (Param) paramtab->getnode(paramtab, args[0]);
     if (pm && (PM_TYPE(pm->flags) & (PM_ARRAY|PM_HASHED))) {
 	char **a;
 
@@ -957,6 +957,7 @@
 	    sethparam(args[0], a);
     } else
 	setsparam(args[0], t);
+    unqueue_signals();
     return 0;
 }
 
Index: Src/Zle/zle_tricky.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_tricky.c,v
retrieving revision 1.21
diff -u -r1.21 zle_tricky.c
--- Src/Zle/zle_tricky.c	2000/10/04 13:54:00	1.21
+++ Src/Zle/zle_tricky.c	2001/01/16 13:27:26
@@ -535,24 +535,33 @@
 static int
 docomplete(int lst)
 {
+    static int active = 0;
+
     char *s, *ol;
     int olst = lst, chl = 0, ne = noerrs, ocs, ret = 0, dat[2];
 
+    if (active) {
+	zwarn("completion cannot be used recursively (yet)", NULL, 0);
+	return 1;
+    }
+    active = 1;
     if (undoing)
 	setlastline();
 
     if (!module_loaded("zsh/complete"))
 	load_module("zsh/compctl");
 
-    if (runhookdef(BEFORECOMPLETEHOOK, (void *) &lst))
+    if (runhookdef(BEFORECOMPLETEHOOK, (void *) &lst)) {
+	active = 0;
 	return 0;
-
+    }
     /* Expand history references before starting completion.  If anything *
      * changed, do no more.                                               */
 
-    if (doexpandhist())
+    if (doexpandhist()) {
+	active = 0;
 	return 0;
-
+    }
     metafy_line();
 
     ocs = cs;
@@ -608,6 +617,7 @@
 	    unmetafy_line();
 	    zsfree(s);
 	    zsfree(qword);
+	    active = 0;
 	    return 1;
 	}
 	ocs = cs;
@@ -785,6 +795,7 @@
     dat[1] = ret;
     runhookdef(AFTERCOMPLETEHOOK, (void *) dat);
 
+    active = 0;
     return dat[1];
 }
 

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author