From 757168e2c8af374436108266cc3cfd32a946a590 Mon Sep 17 00:00:00 2001 From: Sven Wischnowsky Date: Tue, 16 Jan 2001 13:44:18 +0000 Subject: 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) --- ChangeLog | 11 +++++ Src/Modules/zftp.c | 32 ++++++++----- Src/Modules/zpty.c | 4 +- Src/Modules/zutil.c | 13 +++++- Src/Zle/compcore.c | 16 +++++-- Src/Zle/complist.c | 11 ++++- Src/Zle/computil.c | 10 ++++ Src/Zle/zle_main.c | 35 +++++++------- Src/Zle/zle_tricky.c | 19 ++++++-- Src/builtin.c | 126 +++++++++++++++++++++++++++++++++++++++++++-------- Src/exec.c | 23 ++++------ Src/glob.c | 19 ++++++-- Src/hashtable.c | 3 ++ Src/hist.c | 28 +++++++++--- Src/init.c | 4 +- Src/input.c | 4 +- Src/jobs.c | 27 +++++++---- Src/math.c | 2 + Src/mem.c | 59 +++++++++++++++++++++--- Src/module.c | 53 ++++++++++++++++------ Src/params.c | 50 +++++++++++++++----- Src/parse.c | 60 ++++++++++++++++-------- Src/prompt.c | 4 ++ Src/signals.c | 78 ++++++++++--------------------- Src/signals.h | 40 ++++++++-------- Src/subst.c | 14 ++++-- Src/utils.c | 58 +++++++++--------------- Src/watch.c | 9 ++-- 28 files changed, 546 insertions(+), 266 deletions(-) diff --git a/ChangeLog b/ChangeLog index be44b1a64..3ad62c8a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2001-01-16 Sven Wischnowsky + * 13365: Src/builtin.c, Src/exec.c, Src/glob.c, Src/hashtable.c, + Src/hist.c, Src/init.c, Src/input.c, Src/jobs.c, Src/math.c, + Src/mem.c, Src/module.c, Src/params.c, Src/parse.c, Src/prompt.c, + Src/signals.c, Src/signals.h, Src/subst.c, Src/utils.c, + Src/watch.c, Src/Modules/zftp.c, Src/Modules/zpty.c, + Src/Modules/zutil.c, Src/Zle/compcore.c, Src/Zle/complist.c, + Src/Zle/computil.c, Src/Zle/zle_main.c, Src/Zle/zle_tricky.c: + remove 13108 (trap queues); replace with signal queueing to ensure + that user signal handlers are only executed when it is safe to run + them + * 13364: Src/Zle/compctl.c: fix for ol' compctl when completing hash keys 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 */ @@ -1417,39 +1425,13 @@ checkrmall(char *s) return (getquery("ny", 1) == 'y'); } -/**/ -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; -- cgit 1.4.1