summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
authorSven Wischnowsky <wischnow@users.sourceforge.net>2001-01-16 13:44:18 +0000
committerSven Wischnowsky <wischnow@users.sourceforge.net>2001-01-16 13:44:18 +0000
commit757168e2c8af374436108266cc3cfd32a946a590 (patch)
tree293929274f50de8733f00c4ae561a85e9c5fc16f /Src
parent052316fea3b74599de04fb3990a444b0ba08b04b (diff)
downloadzsh-757168e2c8af374436108266cc3cfd32a946a590.tar.gz
zsh-757168e2c8af374436108266cc3cfd32a946a590.zip
remove 13108 (trap queues); replace with signal queueing to ensure that user signal handlers are only executed when it is safe to run them (13365)
Diffstat (limited to 'Src')
-rw-r--r--Src/Modules/zftp.c32
-rw-r--r--Src/Modules/zpty.c4
-rw-r--r--Src/Modules/zutil.c13
-rw-r--r--Src/Zle/compcore.c16
-rw-r--r--Src/Zle/complist.c11
-rw-r--r--Src/Zle/computil.c10
-rw-r--r--Src/Zle/zle_main.c35
-rw-r--r--Src/Zle/zle_tricky.c19
-rw-r--r--Src/builtin.c126
-rw-r--r--Src/exec.c23
-rw-r--r--Src/glob.c19
-rw-r--r--Src/hashtable.c3
-rw-r--r--Src/hist.c28
-rw-r--r--Src/init.c4
-rw-r--r--Src/input.c4
-rw-r--r--Src/jobs.c27
-rw-r--r--Src/math.c2
-rw-r--r--Src/mem.c59
-rw-r--r--Src/module.c53
-rw-r--r--Src/params.c50
-rw-r--r--Src/parse.c60
-rw-r--r--Src/prompt.c4
-rw-r--r--Src/signals.c78
-rw-r--r--Src/signals.h40
-rw-r--r--Src/subst.c14
-rw-r--r--Src/utils.c58
-rw-r--r--Src/watch.c9
27 files changed, 535 insertions, 266 deletions
diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c
index 5813a9144..9bcc65fa2 100644
--- a/Src/Modules/zftp.c
+++ b/Src/Modules/zftp.c
@@ -801,7 +801,7 @@ zfgetline(char *ln, int lnsize, int tmout)
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 @@ zfgetline(char *ln, int lnsize, int tmout)
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 @@ zfgetmsg(void)
if (zfsess->cfd == -1)
return 6;
- if (!(verbose = getsparam("ZFTP_VERBOSE")))
- verbose = "";
zsfree(lastmsg);
lastmsg = NULL;
@@ -890,6 +888,9 @@ zfgetmsg(void)
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 @@ zfgetmsg(void)
printing = 2;
fputs(ptr, stderr);
}
+ unqueue_signals();
if (printing)
fputc('\n', stderr);
@@ -996,7 +998,7 @@ zfsendcmd(char *cmd)
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 @@ zfread(int fd, char *bf, off_t sz, int tmout)
int ret;
if (!tmout)
- return ztrapread(fd, bf, sz);
+ return read(fd, bf, sz);
if (setjmp(zfalrmbuf)) {
alarm(0);
@@ -1479,7 +1481,7 @@ zfread(int fd, char *bf, off_t sz, int tmout)
}
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 @@ zfwrite(int fd, char *bf, off_t sz, int tmout)
int ret;
if (!tmout)
- return ztrapwrite(fd, bf, sz);
+ return write(fd, bf, sz);
if (setjmp(zfalrmbuf)) {
alarm(0);
@@ -1504,7 +1506,7 @@ zfwrite(int fd, char *bf, off_t sz, int tmout)
}
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 @@ zftp_open(char *name, char **args, int flags)
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 @@ zfclose(int leaveparams)
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 @@ savesession()
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 @@ bin_zftp(char *name, char **args, char *ops, int func)
/* 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 @@ bin_zftp(char *name, char **args, char *ops, int func)
return 1;
}
+ queue_signals();
if ((prefs = getsparam("ZFTP_PREFS"))) {
zfprefs = 0;
for (ptr = prefs; *ptr; ptr++) {
@@ -3196,6 +3203,7 @@ bin_zftp(char *name, char **args, char *ops, int func)
}
}
}
+ unqueue_signals();
ret = (*zptr->fun)(fullname, args, zptr->flags);
@@ -3212,7 +3220,7 @@ bin_zftp(char *name, char **args, char *ops, int func)
* 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;
}
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index 297833a79..f96ffa0e3 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -539,7 +539,7 @@ ptywritestr(Ptycmd cmd, char *s, int len)
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 @@ ptywrite(Ptycmd cmd, char **args, int nonl)
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;
}
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 9dae030df..8a69a561b 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -219,12 +219,14 @@ evalstyle(Stypat p)
}
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 @@ savematch(MatchData *m)
{
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 @@ rmatch(RParseResult *sm, char *subj, char *var1, char *var2, int comp)
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)
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 06e7afbfb..a7ada2564 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -1526,14 +1526,15 @@ get_user_var(char *nam)
/* 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 @@ static char **
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
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 6982dc774..714719d62 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -340,6 +340,7 @@ getcols(Listcols c)
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 @@ getcols(Listcols c)
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 @@ getcols(Listcols c)
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 @@ complistmatches(Hookdef dummy, Chdata dat)
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 @@ complistmatches(Hookdef dummy, Chdata dat)
minfo.asked = (listdat.nlines + nlnct <= lines);
}
} else {
+ unqueue_signals();
mlistp = NULL;
if (asklist()) {
amatches = oamatches;
@@ -1641,6 +1647,7 @@ domenuselect(Hookdef dummy, Chdata dat)
int nolist = 0;
char *s;
+ queue_signals();
if (fdat || (dummy && (!(s = getsparam("MENUSELECT")) ||
(dat && dat->num < atoi(s))))) {
if (fdat) {
@@ -1648,6 +1655,7 @@ domenuselect(Hookdef dummy, Chdata dat)
fdat->num = dat->num;
fdat->nmesg = dat->nmesg;
}
+ unqueue_signals();
return 0;
}
if ((s = getsparam("MENUSCROLL"))) {
@@ -1659,6 +1667,7 @@ domenuselect(Hookdef dummy, Chdata dat)
}
if ((mstatus = dupstring(getsparam("MENUPROMPT"))) && !*mstatus)
mstatus = "%SScrolling active: current selection at %p%s";
+ unqueue_signals();
mhasstat = (mstatus && *mstatus);
fdat = dat;
selectlocalmap(mskeymap);
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index 3672de687..4afc492dc 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -2606,6 +2606,7 @@ bin_compquote(char *nam, char **args, char *ops, int func)
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 @@ bin_compquote(char *nam, char **args, char *ops, int func)
}
} else
zwarnnam(nam, "unknown parameter: %s", args[-1], 0);
+ unqueue_signals();
}
return 0;
}
@@ -3580,6 +3582,7 @@ bin_compfiles(char *nam, char **args, char *ops, int func)
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 @@ bin_compfiles(char *nam, char **args, char *ops, int func)
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 @@ bin_compfiles(char *nam, char **args, char *ops, int func)
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 @@ bin_compfiles(char *nam, char **args, char *ops, int func)
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;
}
}
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index b2a662072..c5923d74d 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -313,17 +313,12 @@ static int
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 @@ getkey(int keytmout)
# 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 @@ getkey(int keytmout)
#endif
}
for (;;) {
- r = ztrapread(SHTTY, &cc, 1);
+ r = read(SHTTY, &cc, 1);
if (r == 1)
break;
if (r == 0) {
@@ -664,8 +659,11 @@ execzlefunc(Thingy func, char **args)
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 @@ bin_vared(char *name, char **args, char *ops, int func)
}
/* 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 @@ bin_vared(char *name, char **args, char *ops, int func)
} 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 @@ bin_vared(char *name, char **args, char *ops, int func)
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 @@ bin_vared(char *name, char **args, char *ops, int func)
sethparam(args[0], a);
} else
setsparam(args[0], t);
+ unqueue_signals();
return 0;
}
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index d6250ce23..7476b833b 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -535,24 +535,33 @@ parambeg(char *s)
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 @@ docomplete(int lst)
unmetafy_line();
zsfree(s);
zsfree(qword);
+ active = 0;
return 1;
}
ocs = cs;
@@ -785,6 +795,7 @@ docomplete(int lst)
dat[1] = ret;
runhookdef(AFTERCOMPLETEHOOK, (void *) dat);
+ active = 0;
return dat[1];
}
diff --git a/Src/builtin.c b/Src/builtin.c
index 16e5caca7..1d54804d1 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -407,7 +407,9 @@ bin_enable(char *name, char **argv, char *ops, int func)
* 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 @@ bin_enable(char *name, char **argv, char *ops, int func)
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 @@ bin_enable(char *name, char **argv, char *ops, int func)
}
/* Take arguments literally -- do not glob */
+ queue_signals();
for (; *argv; argv++) {
if ((hn = ht->getnode2(ht, *argv))) {
scanfunc(hn, 0);
@@ -439,6 +445,7 @@ bin_enable(char *name, char **argv, char *ops, int func)
returnval = 1;
}
}
+ unqueue_signals();
return returnval;
}
@@ -511,6 +518,7 @@ bin_set(char *nam, char **args, char *ops, int func)
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 @@ bin_set(char *nam, char **args, char *ops, int func)
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 @@ bin_set(char *nam, char **args, char *ops, int func)
freearray(pparams);
pparams = zarrdup(args);
}
+ unqueue_signals();
return 0;
}
@@ -588,6 +599,7 @@ bin_dirs(char *name, char **argv, char *ops, int func)
/* 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 @@ bin_dirs(char *name, char **argv, char *ops, int func)
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 @@ bin_dirs(char *name, char **argv, char *ops, int func)
freelinklist(dirstack, freestr);
dirstack = l;
}
+ unqueue_signals();
return 0;
}
@@ -693,9 +708,11 @@ bin_cd(char *nam, char **argv, char *ops, int func)
}
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 @@ bin_cd(char *nam, char **argv, char *ops, int func)
chdir(unmeta(pwd));
}
}
+ unqueue_signals();
return 0;
}
@@ -1192,19 +1210,23 @@ bin_fc(char *nam, char **argv, char *ops, int func)
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 @@ bin_fc(char *nam, char **argv, char *ops, int func)
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 @@ bin_fc(char *nam, char **argv, char *ops, int func)
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 @@ bin_fc(char *nam, char **argv, char *ops, int func)
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 @@ bin_fc(char *nam, char **argv, char *ops, int func)
if (!editor)
editor = DEFAULT_FCEDIT;
+ unqueue_signals();
if (fcedit(editor, fil)) {
if (stuff(fil))
zwarnnam("fc", "%e: %s", s, errno);
@@ -1289,7 +1320,8 @@ bin_fc(char *nam, char **argv, char *ops, int func)
retval = lastval;
}
}
- }
+ } else
+ unqueue_signals();
}
unlink(fil);
}
@@ -1847,6 +1879,8 @@ bin_typeset(char *name, char **argv, char *ops, int func)
on &= ~off;
+ queue_signals();
+
/* Given no arguments, list whatever the options specify. */
if (!*argv) {
if (!(on|roff))
@@ -1854,6 +1888,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
if (roff || ops['+'])
printflags |= PRINT_NAMEONLY;
scanhashtable(paramtab, 1, on|roff, 0, paramtab->printnode, printflags);
+ unqueue_signals();
return 0;
}
@@ -1868,20 +1903,27 @@ bin_typeset(char *name, char **argv, char *ops, int func)
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 @@ bin_typeset(char *name, char **argv, char *ops, int func)
(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 @@ bin_typeset(char *name, char **argv, char *ops, int func)
if (oldval)
zsfree(oldval);
unsetparam_pm(apm, 1, 1);
+ unqueue_signals();
return 1;
}
@@ -1931,6 +1975,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
apm->ename = ztrdup(asg0.name);
if (oldval)
setsparam(asg0.name, oldval);
+ unqueue_signals();
return 0;
}
@@ -1987,6 +2032,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
returnval = 1;
}
}
+ unqueue_signals();
return returnval;
}
@@ -2005,6 +2051,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
func, on, off, roff, asg->value, NULL))
returnval = 1;
}
+ unqueue_signals();
return returnval;
}
@@ -2074,6 +2121,9 @@ bin_functions(char *name, char **argv, char *ops, int func)
* 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 @@ bin_functions(char *name, char **argv, char *ops, int func)
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 @@ bin_functions(char *name, char **argv, char *ops, int func)
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 @@ bin_functions(char *name, char **argv, char *ops, int func)
}
}
}
+ unqueue_signals();
} else {
untokenize(*argv);
zwarnnam(name, "bad pattern : %s", *argv, 0);
@@ -2130,6 +2183,7 @@ bin_functions(char *name, char **argv, char *ops, int func)
}
/* 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 @@ bin_functions(char *name, char **argv, char *ops, int func)
} else
returnval = 1;
}
+ unqueue_signals();
return returnval;
}
@@ -2206,6 +2261,7 @@ bin_unset(char *name, char **argv, char *ops, int func)
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 @@ bin_unset(char *name, char **argv, char *ops, int func)
}
}
}
+ unqueue_signals();
} else {
untokenize(s);
zwarnnam(name, "bad pattern : %s", s, 0);
@@ -2231,6 +2288,7 @@ bin_unset(char *name, char **argv, char *ops, int func)
}
/* do not glob -- unset the given parameter */
+ queue_signals();
while ((s = *argv++)) {
char *ss = strchr(s, '[');
char *sse = ss;
@@ -2268,6 +2326,7 @@ bin_unset(char *name, char **argv, char *ops, int func)
if (ss)
*ss = '[';
}
+ unqueue_signals();
return returnval;
}
@@ -2313,6 +2372,7 @@ bin_whence(char *nam, char **argv, char *ops, int func)
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 @@ bin_whence(char *nam, char **argv, char *ops, int func)
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 @@ bin_whence(char *nam, char **argv, char *ops, int func)
returnval = 1;
}
}
+ unqueue_signals();
return returnval;
}
@@ -2496,10 +2559,13 @@ bin_hash(char *name, char **argv, char *ops, int func)
/* 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 @@ bin_hash(char *name, char **argv, char *ops, int func)
ht->printnode(hn, 0);
argv++;
}
+ unqueue_signals();
return returnval;
}
@@ -2586,6 +2653,7 @@ bin_unhash(char *name, char **argv, char *ops, int func)
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 @@ bin_unhash(char *name, char **argv, char *ops, int func)
}
}
}
+ unqueue_signals();
} else {
untokenize(*argv);
zwarnnam(name, "bad pattern : %s", *argv, 0);
@@ -2609,6 +2678,7 @@ bin_unhash(char *name, char **argv, char *ops, int func)
}
/* Take arguments literally -- do not glob */
+ queue_signals();
for (; *argv; argv++) {
if ((hn = ht->removenode(ht, *argv))) {
ht->freenode(hn);
@@ -2617,6 +2687,7 @@ bin_unhash(char *name, char **argv, char *ops, int func)
returnval = 1;
}
}
+ unqueue_signals();
return returnval;
}
@@ -2656,7 +2727,9 @@ bin_alias(char *name, char **argv, char *ops, int func)
/* 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 @@ bin_alias(char *name, char **argv, char *ops, int func)
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 @@ bin_alias(char *name, char **argv, char *ops, int func)
}
/* 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 @@ bin_alias(char *name, char **argv, char *ops, int func)
} else
returnval = 1;
}
+ unqueue_signals();
return returnval;
}
@@ -2774,7 +2851,10 @@ bin_print(char *name, char **args, char *ops, int func)
}
/* -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 @@ bin_print(char *name, char **args, char *ops, int func)
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 @@ bin_print(char *name, char **args, char *ops, int func)
int nwords = 0, nlen, iwords;
char **pargs = args;
+ queue_signals();
ent = prepnexthistent();
while (*pargs++)
nwords++;
@@ -2813,6 +2897,7 @@ bin_print(char *name, char **args, char *ops, int func)
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 @@ bin_shift(char *name, char **argv, char *ops, int func)
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 @@ bin_shift(char *name, char **argv, char *ops, int func)
pparams = s;
}
}
+ unqueue_signals();
return ret;
}
@@ -3169,7 +3257,7 @@ zexit(int val, int from_signal)
}
}
if (sigtrapped[SIGEXIT])
- dotrap(SIGEXIT, 1);
+ dotrap(SIGEXIT);
runhookdef(EXITHOOK, NULL);
if (mypid != getpid())
_exit(val);
@@ -3415,7 +3503,7 @@ bin_read(char *name, char **args, char *ops, int func)
*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 @@ bin_read(char *name, char **args, char *ops, int func)
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 @@ zread(int izle, int *readchar)
}
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 @@ bin_trap(char *name, char **argv, char *ops, int func)
/* 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 @@ bin_trap(char *name, char **argv, char *ops, int func)
}
}
}
+ unqueue_signals();
return 0;
}
diff --git a/Src/exec.c b/Src/exec.c
index dc57291dc..ce083da86 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -759,8 +759,6 @@ execsimple(Estate state)
} else
lv = (execfuncs[code - WC_CURSH])(state, 0);
- RUNTRAPS();
-
return lastval = lv;
}
@@ -892,19 +890,19 @@ sublist_done:
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 @@ execpline(Estate state, wordcode slcode, int how, int last1)
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 @@ execpline2(Estate state, wordcode pcode,
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 @@ execpline2(Estate state, wordcode pcode,
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 @@ setunderscore(char *str)
}
}
-/* 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 @@ execcmd(Estate state, int input, int output, int how, int last1)
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++)
diff --git a/Src/glob.c b/Src/glob.c
index 8f2f54952..90b291459 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -279,14 +279,17 @@ insert(char *s, int checked)
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 @@ insert(char *s, int checked)
/* 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 @@ insert(char *s, int checked)
* 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 @@ insert(char *s, int checked)
if (!inserts)
break;
}
+ unqueue_signals();
}
/* Check to see if str is eligible for filename generation. */
diff --git a/Src/hashtable.c b/Src/hashtable.c
index 9a1010ec6..884c98412 100644
--- a/Src/hashtable.c
+++ b/Src/hashtable.c
@@ -560,11 +560,14 @@ int
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;
}
diff --git a/Src/hist.c b/Src/hist.c
index 9149d479b..b9480d786 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -382,6 +382,7 @@ histsubchar(int c)
/* get event number */
+ queue_signals();
if (c == '?') {
for (;;) {
c = ingetc();
@@ -397,6 +398,7 @@ histsubchar(int c)
evset = 0;
if (ev == -1) {
herrflush();
+ unqueue_signals();
zerr("no such event: %s", buf, 0);
return -1;
}
@@ -450,6 +452,7 @@ histsubchar(int c)
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 @@ histsubchar(int c)
/* 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 @@ histsubchar(int c)
argc = getargc(ehist);
} else {
herrflush();
+ unqueue_signals();
zerr("Ambiguous history reference", NULL, 0);
return -1;
}
@@ -486,8 +491,10 @@ histsubchar(int c)
} 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 @@ histsubchar(int c)
} 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 @@ histsubchar(int c)
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 @@ mod_export int
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 @@ hend(Eprog prog)
zfree(chwords, chwordlen*sizeof(short));
chline = NULL;
histactive = 0;
+ unqueue_signals();
return 1;
}
if (hist_ignore_all_dups != isset(HISTIGNOREALLDUPS)
@@ -1107,6 +1122,7 @@ hend(Eprog prog)
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);
}
diff --git a/Src/init.c b/Src/init.c
index 290384c1a..b07ac80d5 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -170,7 +170,7 @@ loop(int toplevel, int justonce)
}
if (isset(SINGLECOMMAND) && toplevel) {
if (sigtrapped[SIGEXIT])
- dotrap(SIGEXIT, 1);
+ dotrap(SIGEXIT);
exit(lastval);
}
if (justonce)
@@ -1022,6 +1022,7 @@ sourcehome(char *s)
{
char *h;
+ queue_signals();
if (emulation == EMULATE_SH || emulation == EMULATE_KSH ||
!(h = getsparam("ZDOTDIR")))
h = home;
@@ -1030,6 +1031,7 @@ sourcehome(char *s)
/* 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);
}
}
diff --git a/Src/input.c b/Src/input.c
index e82d25011..8f33e3631 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -141,9 +141,7 @@ shingetline(void)
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')
diff --git a/Src/jobs.c b/Src/jobs.c
index 966263645..c491094b3 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -378,7 +378,7 @@ update_job(Job jn)
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 @@ update_job(Job jn)
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 @@ printtime(struct timeval *real, struct timeinfo *ti, char *desc)
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 @@ printtime(struct timeval *real, struct timeinfo *ti, char *desc)
break;
} else
putc(*s, stderr);
+ unqueue_signals();
putc('\n', stderr);
fflush(stderr);
}
@@ -580,10 +582,13 @@ should_report_time(Job j)
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 @@ havefiles(void)
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 @@ waitforpid(pid_t pid)
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 @@ waitforpid(pid_t pid)
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 @@ zwaitjob(int job, int sig)
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 @@ zwaitjob(int job, int sig)
numpipestats = 1;
}
child_unblock();
+ restore_queue_signals(q);
}
/* wait for running job to finish */
@@ -1222,11 +1228,13 @@ bin_fg(char *name, char **argv, char *ops, int func)
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 @@ bin_fg(char *name, char **argv, char *ops, int func)
pid_t pid = (long)atoi(*argv);
Job j;
Process p;
+
if (findproc(pid, &j, &p))
waitforpid(pid);
else
diff --git a/Src/math.c b/Src/math.c
index 282622f73..bad958243 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -495,10 +495,12 @@ getcvar(char *s)
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;
}
diff --git a/Src/mem.c b/Src/mem.c
index b21ef210f..5c995c634 100644
--- a/Src/mem.c
+++ b/Src/mem.c
@@ -115,9 +115,13 @@ static Heap fheap;
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 @@ old_heaps(Heap old)
{
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 @@ old_heaps(Heap old)
}
heaps = old;
fheap = NULL;
+ unqueue_signals();
}
/* Temporarily switch to other heaps (or back again). */
@@ -149,10 +155,14 @@ old_heaps(Heap old)
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 @@ pushheap(void)
Heap h;
Heapstack hs;
+ queue_signals();
+
#if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
h_push++;
#endif
@@ -177,6 +189,7 @@ pushheap(void)
h->sp = hs;
hs->used = h->used;
}
+ unqueue_signals();
}
/* reset heaps to previous state */
@@ -187,6 +200,8 @@ freeheap(void)
{
Heap h, hn, hl = NULL;
+ queue_signals();
+
#if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
h_free++;
#endif
@@ -214,6 +229,8 @@ freeheap(void)
hl->next = NULL;
else
heaps = NULL;
+
+ unqueue_signals();
}
/* reset heap to previous state and destroy state information */
@@ -225,6 +242,8 @@ popheap(void)
Heap h, hn, hl = NULL;
Heapstack hs;
+ queue_signals();
+
#if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
h_pop++;
#endif
@@ -255,6 +274,8 @@ popheap(void)
hl->next = NULL;
else
heaps = NULL;
+
+ unqueue_signals();
}
/* allocate memory from the current memory pool */
@@ -268,6 +289,8 @@ zhalloc(size_t size)
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 @@ zhalloc(size_t size)
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 @@ zhalloc(size_t size)
/* 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 @@ hrealloc(char *p, size_t old, size_t new)
/* 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 @@ hrealloc(char *p, size_t old, size_t new)
#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 @@ hrealloc(char *p, size_t old, size_t new)
#else
zfree(h, HEAPSIZE);
#endif
+ unqueue_signals();
return NULL;
}
#ifndef USE_MMAP
@@ -407,6 +438,7 @@ hrealloc(char *p, size_t old, size_t new)
heaps = h = (Heap) realloc(h, n);
}
h->used = new;
+ unqueue_signals();
return arena(h);
#endif
}
@@ -415,6 +447,7 @@ hrealloc(char *p, size_t old, size_t new)
#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 @@ hrealloc(char *p, size_t old, size_t new)
#ifdef ZSH_MEM_DEBUG
memset(p, 0xff, old);
#endif
+ unqueue_signals();
return t;
}
}
@@ -450,10 +484,12 @@ zalloc(size_t size)
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 @@ zcalloc(size_t size)
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 @@ zcalloc(size_t size)
mod_export void *
zrealloc(void *ptr, size_t size)
{
+ queue_signals();
if (ptr) {
if (size) {
/* Do normal realloc */
@@ -492,18 +531,22 @@ zrealloc(void *ptr, size_t size)
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 @@ bin_mem(char *name, char **argv, char *ops, int func)
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 @@ bin_mem(char *name, char **argv, char *ops, int func)
if (h_m[1024])
printf("big\t%d\n", h_m[1024]);
+ unqueue_signals();
return 0;
}
diff --git a/Src/module.c b/Src/module.c
index 13b747f05..cd68627ae 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -763,10 +763,13 @@ load_module(char const *name)
* 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 @@ load_module(char const *name)
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 @@ load_module(char const *name)
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 @@ load_module(char const *name)
else
m->u.linked = NULL;
m->flags &= ~MOD_SETUP;
+ unqueue_signals();
return 0;
}
m->flags |= MOD_INIT_S;
@@ -837,10 +850,12 @@ load_module(char const *name)
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 @@ require_module(char *nam, const char *module, int res, int test)
{
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 @@ bin_zmodload(char *nam, char **args, char *ops, int func)
{
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 @@ bin_zmodload(char *nam, char **args, char *ops, int func)
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 @@ add_autoparam(char *nam, char *module)
{
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. */
diff --git a/Src/params.c b/Src/params.c
index 1c41d2fc2..c4e6127ba 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -1806,6 +1806,7 @@ setsparam(char *s, char *val)
errflag = 1;
return NULL;
}
+ queue_signals();
if ((ss = strchr(s, '['))) {
*ss = '\0';
if (!(v = getvalue(&vbuf, &s, 1)))
@@ -1823,10 +1824,12 @@ setsparam(char *s, char *val)
}
}
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 @@ setaparam(char *s, char **val)
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 @@ setaparam(char *s, char **val)
}
}
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 @@ sethparam(char *s, char **val)
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 @@ setiparam(char *s, zlong val)
errflag = 1;
return NULL;
}
+ queue_signals();
if (!(v = getvalue(&vbuf, &s, 1))) {
if ((ss = strchr(s, '[')))
*ss = '\0';
@@ -1937,12 +1949,14 @@ setiparam(char *s, zlong val)
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 @@ setnparam(char *s, mnumber val)
errflag = 1;
return NULL;
}
+ queue_signals();
if (!(v = getvalue(&vbuf, &s, 1))) {
if ((ss = strchr(s, '[')))
*ss = '\0';
@@ -1981,10 +1996,12 @@ setnparam(char *s, mnumber val)
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 @@ unsetparam(char *s)
{
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 @@ setlang(char *x)
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 @@ void
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 @@ lcsetfn(Param pm, char *x)
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 */
diff --git a/Src/parse.c b/Src/parse.c
index fafe65f43..4d9a48370 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -2312,7 +2312,7 @@ dump_find_func(Wordcode h, char *name)
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 @@ bin_zcompile(char *nam, char **args, char *ops, int func)
}
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
@@ -2825,9 +2832,12 @@ try_dump_file(char *path, char *name, char *file, int *ksh)
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 @@ try_dump_file(char *path, char *name, char *file, int *ksh)
* 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 @@ try_source_file(char *file)
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;
}
diff --git a/Src/prompt.c b/Src/prompt.c
index cca6da21f..b90bfff2a 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -372,12 +372,15 @@ putpromptchar(int doprint, int endchar)
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 @@ putpromptchar(int doprint, int endchar)
stradd(hostnam);
*ss = t0;
}
+ unqueue_signals();
break;
case 'S':
txtchangeset(TXTSTANDOUT, TXTNOSTANDOUT);
diff --git a/Src/signals.c b/Src/signals.c
index 693337dbd..47599a414 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -497,7 +497,7 @@ handler(int sig)
case SIGHUP:
if (sigtrapped[SIGHUP])
- dotrap(SIGHUP, 0);
+ dotrap(SIGHUP);
else {
stopmsg = 1;
zexit(SIGHUP, 1);
@@ -506,7 +506,7 @@ handler(int sig)
case SIGINT:
if (sigtrapped[SIGINT])
- dotrap(SIGINT, 0);
+ dotrap(SIGINT);
else {
if ((isset(PRIVILEGED) || isset(RESTRICTED)) &&
isset(INTERACTIVE) && noerrexit < 0)
@@ -523,14 +523,14 @@ handler(int sig)
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 @@ handler(int sig)
break;
default:
- dotrap(sig, 0);
+ dotrap(sig);
break;
} /* end of switch(sig) */
@@ -703,6 +703,7 @@ settrap(int sig, Eprog l)
* Call unsettrap() unconditionally, to make sure trap is saved
* if necessary.
*/
+ queue_signals();
unsettrap(sig);
sigfuncs[sig] = l;
@@ -729,6 +730,7 @@ settrap(int sig, Eprog l)
* works just the same.
*/
sigtrapped[sig] |= (locallevel << ZSIG_SHIFT);
+ unqueue_signals();
return 0;
}
@@ -736,9 +738,13 @@ settrap(int sig, Eprog l)
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 @@ removetrap(int sig)
(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 @@ removetrap(int sig)
(!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 @@ removetrap(int sig)
*/
if (trapped & ZSIG_FUNC) {
char func[20];
+ HashNode node;
sprintf(func, "TRAP%s", sigs[sig]);
/*
@@ -797,11 +806,15 @@ removetrap(int sig)
* 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;
}
@@ -966,56 +979,15 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
*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]);
}
diff --git a/Src/signals.h b/Src/signals.h
index 45978dd1e..4ac19aa3e 100644
--- a/Src/signals.h
+++ b/Src/signals.h
@@ -73,26 +73,34 @@
* 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 16
+#define MAX_QUEUE_SIZE 128
#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. */
@@ -117,9 +125,3 @@ extern sigset_t signal_block _((sigset_t));
#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)
diff --git a/Src/subst.c b/Src/subst.c
index 0cb985d71..bb90faf0c 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -51,6 +51,7 @@ prefork(LinkList list, int flags)
{
LinkNode node;
+ queue_signals();
for (node = firstnode(list); node; incnode(node)) {
char *str, c;
@@ -61,14 +62,18 @@ prefork(LinkList list, int flags)
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 @@ prefork(LinkList list, int flags)
flags & (PF_TYPESET|PF_ASSIGN));
} else if (!(flags & PF_SINGLE))
uremnode(list, node);
- if (errflag)
+ if (errflag) {
+ unqueue_signals();
return;
+ }
}
+ unqueue_signals();
}
/**/
diff --git a/Src/utils.c b/Src/utils.c
index 11908435c..3bdaef307 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -691,12 +691,16 @@ preprompt(void)
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 @@ zclose(int fd)
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 @@ checkrmall(char *s)
}
/**/
-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 @@ noquery(int purge)
ioctl(SHTTY, FIONREAD, (char *)&val);
if (purge) {
for (; val; val--)
- ztrapread(SHTTY, &c, 1);
+ read(SHTTY, &c, 1);
}
#endif
@@ -2122,12 +2104,14 @@ mod_export void
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();
}
/**/
diff --git a/Src/watch.c b/Src/watch.c
index 2532e0a63..4f63a5bd9 100644
--- a/Src/watch.c
+++ b/Src/watch.c
@@ -235,7 +235,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
# endif /* WATCH_UTMP_UT_HOST */
while (*fmt)
- if (*fmt == '\\')
+ if (*fmt == '\\') {
if (*++fmt) {
if (prnt)
putchar(*fmt);
@@ -244,6 +244,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
return fmt;
else
break;
+ }
else if (*fmt == fini)
return ++fmt;
else if (*fmt != '%') {
@@ -490,8 +491,6 @@ dowatch(void)
int uct, wct;
s = watch;
- if (!(fmt = getsparam("WATCHFMT")))
- fmt = DEFAULT_WATCHFMT;
holdintr();
if (!wtab) {
@@ -541,6 +540,9 @@ dowatch(void)
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);
@@ -548,6 +550,7 @@ dowatch(void)
uct--, watchlog(1, uptr++, s, fmt);
else
uptr++, wptr++, wct--, uct--;
+ unqueue_signals();
free(wtab);
wtab = utab;
wtabsz = utabsz;