1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-23 16:40:24 +02:00

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)

This commit is contained in:
Sven Wischnowsky 2001-01-16 13:44:18 +00:00
parent 052316fea3
commit 757168e2c8
28 changed files with 546 additions and 266 deletions

View file

@ -1,5 +1,16 @@
2001-01-16 Sven Wischnowsky <wischnow@zsh.org> 2001-01-16 Sven Wischnowsky <wischnow@zsh.org>
* 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 * 13364: Src/Zle/compctl.c: fix for ol' compctl when completing
hash keys hash keys

View file

@ -801,7 +801,7 @@ zfgetline(char *ln, int lnsize, int tmout)
cmdbuf[0] = (char)IAC; cmdbuf[0] = (char)IAC;
cmdbuf[1] = (char)DONT; cmdbuf[1] = (char)DONT;
cmdbuf[2] = ch; cmdbuf[2] = ch;
ztrapwrite(zfsess->cfd, cmdbuf, 3); write(zfsess->cfd, cmdbuf, 3);
continue; continue;
case DO: case DO:
@ -811,7 +811,7 @@ zfgetline(char *ln, int lnsize, int tmout)
cmdbuf[0] = (char)IAC; cmdbuf[0] = (char)IAC;
cmdbuf[1] = (char)WONT; cmdbuf[1] = (char)WONT;
cmdbuf[2] = ch; cmdbuf[2] = ch;
ztrapwrite(zfsess->cfd, cmdbuf, 3); write(zfsess->cfd, cmdbuf, 3);
continue; continue;
case EOF: case EOF:
@ -863,8 +863,6 @@ zfgetmsg(void)
if (zfsess->cfd == -1) if (zfsess->cfd == -1)
return 6; return 6;
if (!(verbose = getsparam("ZFTP_VERBOSE")))
verbose = "";
zsfree(lastmsg); zsfree(lastmsg);
lastmsg = NULL; lastmsg = NULL;
@ -890,6 +888,9 @@ zfgetmsg(void)
zfsetparam("ZFTP_CODE", ztrdup(lastcodestr), ZFPM_READONLY); zfsetparam("ZFTP_CODE", ztrdup(lastcodestr), ZFPM_READONLY);
stopit = (*ptr++ != '-'); stopit = (*ptr++ != '-');
queue_signals();
if (!(verbose = getsparam("ZFTP_VERBOSE")))
verbose = "";
if (strchr(verbose, lastcodestr[0])) { if (strchr(verbose, lastcodestr[0])) {
/* print the whole thing verbatim */ /* print the whole thing verbatim */
printing = 1; printing = 1;
@ -899,6 +900,7 @@ zfgetmsg(void)
printing = 2; printing = 2;
fputs(ptr, stderr); fputs(ptr, stderr);
} }
unqueue_signals();
if (printing) if (printing)
fputc('\n', stderr); fputc('\n', stderr);
@ -996,7 +998,7 @@ zfsendcmd(char *cmd)
return 6; return 6;
} }
zfalarm(tmout); zfalarm(tmout);
ret = ztrapwrite(zfsess->cfd, cmd, strlen(cmd)); ret = write(zfsess->cfd, cmd, strlen(cmd));
alarm(0); alarm(0);
if (ret <= 0) { if (ret <= 0) {
@ -1470,7 +1472,7 @@ zfread(int fd, char *bf, off_t sz, int tmout)
int ret; int ret;
if (!tmout) if (!tmout)
return ztrapread(fd, bf, sz); return read(fd, bf, sz);
if (setjmp(zfalrmbuf)) { if (setjmp(zfalrmbuf)) {
alarm(0); alarm(0);
@ -1479,7 +1481,7 @@ zfread(int fd, char *bf, off_t sz, int tmout)
} }
zfalarm(tmout); zfalarm(tmout);
ret = ztrapread(fd, bf, sz); ret = read(fd, bf, sz);
/* we don't bother turning off the whole alarm mechanism here */ /* we don't bother turning off the whole alarm mechanism here */
alarm(0); alarm(0);
@ -1495,7 +1497,7 @@ zfwrite(int fd, char *bf, off_t sz, int tmout)
int ret; int ret;
if (!tmout) if (!tmout)
return ztrapwrite(fd, bf, sz); return write(fd, bf, sz);
if (setjmp(zfalrmbuf)) { if (setjmp(zfalrmbuf)) {
alarm(0); alarm(0);
@ -1504,7 +1506,7 @@ zfwrite(int fd, char *bf, off_t sz, int tmout)
} }
zfalarm(tmout); zfalarm(tmout);
ret = ztrapwrite(fd, bf, sz); ret = write(fd, bf, sz);
/* we don't bother turning off the whole alarm mechanism here */ /* we don't bother turning off the whole alarm mechanism here */
alarm(0); alarm(0);
@ -1894,10 +1896,12 @@ zftp_open(char *name, char **args, int flags)
if (setjmp(zfalrmbuf)) { if (setjmp(zfalrmbuf)) {
char *hname; char *hname;
alarm(0); alarm(0);
queue_signals();
if ((hname = getsparam("ZFTP_HOST")) && *hname) if ((hname = getsparam("ZFTP_HOST")) && *hname)
zwarnnam(name, "timeout connecting to %s", hname, 0); zwarnnam(name, "timeout connecting to %s", hname, 0);
else else
zwarnnam(name, "timeout on host name lookup", NULL, 0); zwarnnam(name, "timeout on host name lookup", NULL, 0);
unqueue_signals();
zfclose(0); zfclose(0);
return 1; return 1;
} }
@ -2846,7 +2850,7 @@ zfclose(int leaveparams)
if (!zfnopen) { if (!zfnopen) {
/* Write the final status in case this is a subshell */ /* Write the final status in case this is a subshell */
lseek(zfstatfd, zfsessno*sizeof(int), 0); lseek(zfstatfd, zfsessno*sizeof(int), 0);
ztrapwrite(zfstatfd, (char *)zfstatusp+zfsessno, sizeof(int)); write(zfstatfd, (char *)zfstatusp+zfsessno, sizeof(int));
close(zfstatfd); close(zfstatfd);
zfstatfd = -1; zfstatfd = -1;
@ -2933,10 +2937,12 @@ savesession()
for (ps = zfparams, pd = zfsess->params; *ps; ps++, pd++) { for (ps = zfparams, pd = zfsess->params; *ps; ps++, pd++) {
if (*pd) if (*pd)
zsfree(*pd); zsfree(*pd);
queue_signals();
if ((val = getsparam(*ps))) if ((val = getsparam(*ps)))
*pd = ztrdup(val); *pd = ztrdup(val);
else else
*pd = NULL; *pd = NULL;
unqueue_signals();
} }
*pd = NULL; *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 */ /* Get the status in case it was set by a forked process */
int oldstatus = zfstatusp[zfsessno]; int oldstatus = zfstatusp[zfsessno];
lseek(zfstatfd, 0, 0); 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)) { if (zfsess->cfd != -1 && (zfstatusp[zfsessno] & ZFST_CLOS)) {
/* got closed in subshell without us knowing */ /* got closed in subshell without us knowing */
zcfinish = 2; zcfinish = 2;
@ -3166,6 +3172,7 @@ bin_zftp(char *name, char **args, char *ops, int func)
return 1; return 1;
} }
queue_signals();
if ((prefs = getsparam("ZFTP_PREFS"))) { if ((prefs = getsparam("ZFTP_PREFS"))) {
zfprefs = 0; zfprefs = 0;
for (ptr = prefs; *ptr; ptr++) { 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); 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. * but only for the active session.
*/ */
lseek(zfstatfd, zfsessno*sizeof(int), 0); lseek(zfstatfd, zfsessno*sizeof(int), 0);
ztrapwrite(zfstatfd, (char *)zfstatusp+zfsessno, sizeof(int)); write(zfstatfd, (char *)zfstatusp+zfsessno, sizeof(int));
} }
return ret; return ret;
} }

View file

@ -539,7 +539,7 @@ ptywritestr(Ptycmd cmd, char *s, int len)
for (; !errflag && !breaks && !retflag && !contflag && len; for (; !errflag && !breaks && !retflag && !contflag && len;
len -= written, s += written) { 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 #ifdef EWOULDBLOCK
errno == EWOULDBLOCK errno == EWOULDBLOCK
#else #else
@ -583,7 +583,7 @@ ptywrite(Ptycmd cmd, char **args, int nonl)
int n; int n;
char buf[BUFSIZ]; char buf[BUFSIZ];
while ((n = ztrapread(0, buf, BUFSIZ)) > 0) while ((n = read(0, buf, BUFSIZ)) > 0)
if (ptywritestr(cmd, buf, n)) if (ptywritestr(cmd, buf, n))
return 1; return 1;
} }

View file

@ -219,12 +219,14 @@ evalstyle(Stypat p)
} }
errflag = ef; errflag = ef;
queue_signals();
if ((ret = getaparam("reply"))) if ((ret = getaparam("reply")))
ret = arrdup(ret); ret = arrdup(ret);
else if ((str = getsparam("reply"))) { else if ((str = getsparam("reply"))) {
ret = (char **) hcalloc(2 * sizeof(char *)); ret = (char **) hcalloc(2 * sizeof(char *));
ret[0] = dupstring(str); ret[0] = dupstring(str);
} }
unqueue_signals();
unsetparam("reply"); unsetparam("reply");
return ret; return ret;
@ -725,12 +727,14 @@ savematch(MatchData *m)
{ {
char **a; char **a;
queue_signals();
a = getaparam("match"); a = getaparam("match");
m->match = a ? zarrdup(a) : NULL; m->match = a ? zarrdup(a) : NULL;
a = getaparam("mbegin"); a = getaparam("mbegin");
m->mbegin = a ? zarrdup(a) : NULL; m->mbegin = a ? zarrdup(a) : NULL;
a = getaparam("mend"); a = getaparam("mend");
m->mend = a ? zarrdup(a) : NULL; m->mend = a ? zarrdup(a) : NULL;
unqueue_signals();
} }
static void static void
@ -1078,8 +1082,13 @@ rmatch(RParseResult *sm, char *subj, char *var1, char *var2, int comp)
if (next->pattern && pattry(next->patprog, subj) && if (next->pattern && pattry(next->patprog, subj) &&
(!next->guard || (execstring(next->guard, 1, 0), !lastval))) { (!next->guard || (execstring(next->guard, 1, 0), !lastval))) {
LinkNode aln; LinkNode aln;
char **mend = getaparam("mend"); char **mend;
int len = atoi(mend[0]); int len;
queue_signals();
mend = getaparam("mend");
len = atoi(mend[0]);
unqueue_signals();
for (i = len; i; i--) for (i = len; i; i--)
if (*subj++ == Meta) if (*subj++ == Meta)

View file

@ -1526,14 +1526,15 @@ get_user_var(char *nam)
/* Otherwise it should be a parameter name. */ /* Otherwise it should be a parameter name. */
char **arr = NULL, *val; char **arr = NULL, *val;
queue_signals();
if ((arr = getaparam(nam)) || (arr = gethparam(nam))) if ((arr = getaparam(nam)) || (arr = gethparam(nam)))
return (incompfunc ? arrdup(arr) : arr); arr = (incompfunc ? arrdup(arr) : arr);
else if ((val = getsparam(nam))) {
if ((val = getsparam(nam))) {
arr = (char **) zhalloc(2*sizeof(char *)); arr = (char **) zhalloc(2*sizeof(char *));
arr[0] = (incompfunc ? dupstring(val) : val); arr[0] = (incompfunc ? dupstring(val) : val);
arr[1] = NULL; arr[1] = NULL;
} }
unqueue_signals();
return arr; return arr;
} }
} }
@ -1542,14 +1543,19 @@ static char **
get_data_arr(char *name, int keys) get_data_arr(char *name, int keys)
{ {
struct value vbuf; struct value vbuf;
char **ret;
Value v; Value v;
queue_signals();
if (!(v = fetchvalue(&vbuf, &name, 1, if (!(v = fetchvalue(&vbuf, &name, 1,
(keys ? SCANPM_WANTKEYS : SCANPM_WANTVALS) | (keys ? SCANPM_WANTKEYS : SCANPM_WANTVALS) |
SCANPM_MATCHMANY))) 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 /* This is used by compadd to add a couple of matches. The arguments are

View file

@ -340,6 +340,7 @@ getcols(Listcols c)
int i, l; int i, l;
max_caplen = lr_caplen = 0; max_caplen = lr_caplen = 0;
queue_signals();
if (!(s = getsparam("ZLS_COLORS")) && if (!(s = getsparam("ZLS_COLORS")) &&
!(s = getsparam("ZLS_COLOURS"))) { !(s = getsparam("ZLS_COLOURS"))) {
for (i = 0; i < NUM_COLS; i++) for (i = 0; i < NUM_COLS; i++)
@ -356,6 +357,7 @@ getcols(Listcols c)
if ((max_caplen = strlen(c->files[COL_MA]->col)) < if ((max_caplen = strlen(c->files[COL_MA]->col)) <
(l = strlen(c->files[COL_EC]->col))) (l = strlen(c->files[COL_EC]->col)))
max_caplen = l; max_caplen = l;
unqueue_signals();
return; return;
} }
/* We have one of the parameters, use it. */ /* We have one of the parameters, use it. */
@ -366,6 +368,7 @@ getcols(Listcols c)
s++; s++;
else else
s = getcoldef(c, s); s = getcoldef(c, s);
unqueue_signals();
/* Use default values for those that aren't set explicitly. */ /* Use default values for those that aren't set explicitly. */
for (i = 0; i < NUM_COLS; i++) { for (i = 0; i < NUM_COLS; i++) {
@ -1528,8 +1531,10 @@ complistmatches(Hookdef dummy, Chdata dat)
mscroll = 0; mscroll = 0;
mlistp = NULL; mlistp = NULL;
queue_signals();
if (mselect >= 0 || mlbeg >= 0 || if (mselect >= 0 || mlbeg >= 0 ||
(mlistp = getsparam("LISTPROMPT"))) { (mlistp = dupstring(getsparam("LISTPROMPT")))) {
unqueue_signals();
if (mlistp && !*mlistp) if (mlistp && !*mlistp)
mlistp = "%SAt %p: Hit TAB for more, or the character to insert%s"; mlistp = "%SAt %p: Hit TAB for more, or the character to insert%s";
trashzle(); trashzle();
@ -1545,6 +1550,7 @@ complistmatches(Hookdef dummy, Chdata dat)
minfo.asked = (listdat.nlines + nlnct <= lines); minfo.asked = (listdat.nlines + nlnct <= lines);
} }
} else { } else {
unqueue_signals();
mlistp = NULL; mlistp = NULL;
if (asklist()) { if (asklist()) {
amatches = oamatches; amatches = oamatches;
@ -1641,6 +1647,7 @@ domenuselect(Hookdef dummy, Chdata dat)
int nolist = 0; int nolist = 0;
char *s; char *s;
queue_signals();
if (fdat || (dummy && (!(s = getsparam("MENUSELECT")) || if (fdat || (dummy && (!(s = getsparam("MENUSELECT")) ||
(dat && dat->num < atoi(s))))) { (dat && dat->num < atoi(s))))) {
if (fdat) { if (fdat) {
@ -1648,6 +1655,7 @@ domenuselect(Hookdef dummy, Chdata dat)
fdat->num = dat->num; fdat->num = dat->num;
fdat->nmesg = dat->nmesg; fdat->nmesg = dat->nmesg;
} }
unqueue_signals();
return 0; return 0;
} }
if ((s = getsparam("MENUSCROLL"))) { if ((s = getsparam("MENUSCROLL"))) {
@ -1659,6 +1667,7 @@ domenuselect(Hookdef dummy, Chdata dat)
} }
if ((mstatus = dupstring(getsparam("MENUPROMPT"))) && !*mstatus) if ((mstatus = dupstring(getsparam("MENUPROMPT"))) && !*mstatus)
mstatus = "%SScrolling active: current selection at %p%s"; mstatus = "%SScrolling active: current selection at %p%s";
unqueue_signals();
mhasstat = (mstatus && *mstatus); mhasstat = (mstatus && *mstatus);
fdat = dat; fdat = dat;
selectlocalmap(mskeymap); selectlocalmap(mskeymap);

View file

@ -2606,6 +2606,7 @@ bin_compquote(char *nam, char **args, char *ops, int func)
while ((name = *args++)) { while ((name = *args++)) {
name = dupstring(name); name = dupstring(name);
queue_signals();
if ((v = getvalue(&vbuf, &name, 0))) { if ((v = getvalue(&vbuf, &name, 0))) {
switch (PM_TYPE(v->pm->flags)) { switch (PM_TYPE(v->pm->flags)) {
case PM_SCALAR: case PM_SCALAR:
@ -2630,6 +2631,7 @@ bin_compquote(char *nam, char **args, char *ops, int func)
} }
} else } else
zwarnnam(nam, "unknown parameter: %s", args[-1], 0); zwarnnam(nam, "unknown parameter: %s", args[-1], 0);
unqueue_signals();
} }
return 0; return 0;
} }
@ -3580,6 +3582,7 @@ bin_compfiles(char *nam, char **args, char *ops, int func)
zwarnnam(nam, "too few arguments", NULL, 0); zwarnnam(nam, "too few arguments", NULL, 0);
return 1; return 1;
} }
queue_signals();
if (!(tmp = getaparam(args[1]))) { if (!(tmp = getaparam(args[1]))) {
zwarnnam(nam, "unknown parameter: %s", args[1], 0); zwarnnam(nam, "unknown parameter: %s", args[1], 0);
return 0; return 0;
@ -3590,6 +3593,7 @@ bin_compfiles(char *nam, char **args, char *ops, int func)
l, getaparam(args[2]), args[3], l, getaparam(args[2]), args[3],
args[4], args[5], args[4], args[5],
getaparam(args[6]), args + 7)); getaparam(args[6]), args + 7));
unqueue_signals();
return 0; return 0;
} }
case 'i': case 'i':
@ -3608,16 +3612,19 @@ bin_compfiles(char *nam, char **args, char *ops, int func)
zwarnnam(nam, "too many arguments", NULL, 0); zwarnnam(nam, "too many arguments", NULL, 0);
return 1; return 1;
} }
queue_signals();
tmp = getaparam(args[2]); tmp = getaparam(args[2]);
l = newlinklist(); l = newlinklist();
if (tmp) if (tmp)
for (; *tmp; tmp++) for (; *tmp; tmp++)
addlinknode(l, *tmp); addlinknode(l, *tmp);
if (!(tmp = getaparam(args[1]))) { if (!(tmp = getaparam(args[1]))) {
unqueue_signals();
zwarnnam(nam, "unknown parameter: %s", args[1], 0); zwarnnam(nam, "unknown parameter: %s", args[1], 0);
return 0; return 0;
} }
cf_ignore(tmp, l, args[3], args[4]); cf_ignore(tmp, l, args[3], args[4]);
unqueue_signals();
set_list_array(args[2], l); set_list_array(args[2], l);
return 0; return 0;
} }
@ -3635,12 +3642,15 @@ bin_compfiles(char *nam, char **args, char *ops, int func)
zwarnnam(nam, "too many arguments", NULL, 0); zwarnnam(nam, "too many arguments", NULL, 0);
return 1; return 1;
} }
queue_signals();
if (!(tmp = getaparam(args[1]))) { if (!(tmp = getaparam(args[1]))) {
unqueue_signals();
zwarnnam(nam, "unknown parameter: %s", args[1], 0); zwarnnam(nam, "unknown parameter: %s", args[1], 0);
return 0; return 0;
} }
if ((l = cf_remove_other(tmp, args[2], &ret))) if ((l = cf_remove_other(tmp, args[2], &ret)))
set_list_array(args[1], l); set_list_array(args[1], l);
unqueue_signals();
return ret; return ret;
} }
} }

View file

@ -313,17 +313,12 @@ static int
breakread(int fd, char *buf, int n) breakread(int fd, char *buf, int n)
{ {
fd_set f; fd_set f;
int ret;
FD_ZERO(&f); FD_ZERO(&f);
FD_SET(fd, &f); FD_SET(fd, &f);
ALLOWTRAPS { return (select(fd + 1, (SELECT_ARG_2_T) & f, NULL, NULL, NULL) == -1 ?
ret = (select(fd + 1, (SELECT_ARG_2_T) & f, NULL, NULL, NULL) == -1 ? EOF : read(fd, buf, n));
EOF : read(fd, buf, n));
} DISALLOWTRAPS;
return ret;
} }
# define read breakread # define read breakread
@ -394,7 +389,7 @@ getkey(int keytmout)
# else # else
ioctl(SHTTY, TCSETA, &ti.tio); ioctl(SHTTY, TCSETA, &ti.tio);
# endif # endif
r = ztrapread(SHTTY, &cc, 1); r = read(SHTTY, &cc, 1);
# ifdef HAVE_TERMIOS_H # ifdef HAVE_TERMIOS_H
tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio); tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio);
# else # else
@ -405,7 +400,7 @@ getkey(int keytmout)
#endif #endif
} }
for (;;) { for (;;) {
r = ztrapread(SHTTY, &cc, 1); r = read(SHTTY, &cc, 1);
if (r == 1) if (r == 1)
break; break;
if (r == 0) { if (r == 0) {
@ -664,8 +659,11 @@ execzlefunc(Thingy func, char **args)
ret = completecall(args); ret = completecall(args);
if (atcurhist) if (atcurhist)
histline = curhist; histline = curhist;
} else } else {
queue_signals();
ret = w->u.fn(args); ret = w->u.fn(args);
unqueue_signals();
}
if (!(wflags & ZLE_NOTCOMMAND)) if (!(wflags & ZLE_NOTCOMMAND))
lastcmd = wflags; lastcmd = wflags;
} }
@ -836,9 +834,11 @@ bin_vared(char *name, char **args, char *ops, int func)
} }
/* handle non-existent parameter */ /* handle non-existent parameter */
s = args[0]; s = args[0];
queue_signals();
v = fetchvalue(&vbuf, &s, (!create || type == PM_SCALAR), v = fetchvalue(&vbuf, &s, (!create || type == PM_SCALAR),
SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY); SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY);
if (!v && !create) { if (!v && !create) {
unqueue_signals();
zwarnnam(name, "no such variable: %s", args[0], 0); zwarnnam(name, "no such variable: %s", args[0], 0);
return 1; return 1;
} else if (v) { } else if (v) {
@ -885,11 +885,13 @@ bin_vared(char *name, char **args, char *ops, int func)
} else { } else {
s = ztrdup(getstrvalue(v)); s = ztrdup(getstrvalue(v));
} }
pm = v->pm; unqueue_signals();
} else if (*s) { } else if (*s) {
unqueue_signals();
zwarnnam(name, "invalid parameter name: %s", args[0], 0); zwarnnam(name, "invalid parameter name: %s", args[0], 0);
return 1; return 1;
} else { } else {
unqueue_signals();
s = ztrdup(s); s = ztrdup(s);
} }
@ -935,14 +937,12 @@ bin_vared(char *name, char **args, char *ops, int func)
if (t[strlen(t) - 1] == '\n') if (t[strlen(t) - 1] == '\n')
t[strlen(t) - 1] = '\0'; t[strlen(t) - 1] = '\0';
/* final assignment of parameter value */ /* final assignment of parameter value */
if (create && (!pm || (type && PM_TYPE(pm->flags) != type))) { if (create) {
if (pm) unsetparam(args[0]);
unsetparam(args[0]);
createparam(args[0], type); createparam(args[0], type);
pm = 0;
} }
if (!pm) queue_signals();
pm = (Param) paramtab->getnode(paramtab, args[0]); pm = (Param) paramtab->getnode(paramtab, args[0]);
if (pm && (PM_TYPE(pm->flags) & (PM_ARRAY|PM_HASHED))) { if (pm && (PM_TYPE(pm->flags) & (PM_ARRAY|PM_HASHED))) {
char **a; char **a;
@ -957,6 +957,7 @@ bin_vared(char *name, char **args, char *ops, int func)
sethparam(args[0], a); sethparam(args[0], a);
} else } else
setsparam(args[0], t); setsparam(args[0], t);
unqueue_signals();
return 0; return 0;
} }

View file

@ -535,24 +535,33 @@ parambeg(char *s)
static int static int
docomplete(int lst) docomplete(int lst)
{ {
static int active = 0;
char *s, *ol; char *s, *ol;
int olst = lst, chl = 0, ne = noerrs, ocs, ret = 0, dat[2]; 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) if (undoing)
setlastline(); setlastline();
if (!module_loaded("zsh/complete")) if (!module_loaded("zsh/complete"))
load_module("zsh/compctl"); load_module("zsh/compctl");
if (runhookdef(BEFORECOMPLETEHOOK, (void *) &lst)) if (runhookdef(BEFORECOMPLETEHOOK, (void *) &lst)) {
active = 0;
return 0; return 0;
}
/* Expand history references before starting completion. If anything * /* Expand history references before starting completion. If anything *
* changed, do no more. */ * changed, do no more. */
if (doexpandhist()) if (doexpandhist()) {
active = 0;
return 0; return 0;
}
metafy_line(); metafy_line();
ocs = cs; ocs = cs;
@ -608,6 +617,7 @@ docomplete(int lst)
unmetafy_line(); unmetafy_line();
zsfree(s); zsfree(s);
zsfree(qword); zsfree(qword);
active = 0;
return 1; return 1;
} }
ocs = cs; ocs = cs;
@ -785,6 +795,7 @@ docomplete(int lst)
dat[1] = ret; dat[1] = ret;
runhookdef(AFTERCOMPLETEHOOK, (void *) dat); runhookdef(AFTERCOMPLETEHOOK, (void *) dat);
active = 0;
return dat[1]; return dat[1];
} }

View file

@ -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 NOT containing the DISABLED flag, else scanhashtable will *
* print nodes containing the DISABLED flag. */ * print nodes containing the DISABLED flag. */
if (!*argv) { if (!*argv) {
queue_signals();
scanhashtable(ht, 1, flags1, flags2, ht->printnode, 0); scanhashtable(ht, 1, flags1, flags2, ht->printnode, 0);
unqueue_signals();
return 0; return 0;
} }
@ -416,8 +418,11 @@ bin_enable(char *name, char **argv, char *ops, int func)
for (; *argv; argv++) { for (; *argv; argv++) {
/* parse pattern */ /* parse pattern */
tokenize(*argv); 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); match += scanmatchtable(ht, pprog, 0, 0, scanfunc, 0);
unqueue_signals();
}
else { else {
untokenize(*argv); untokenize(*argv);
zwarnnam(name, "bad pattern : %s", *argv, 0); 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 */ /* Take arguments literally -- do not glob */
queue_signals();
for (; *argv; argv++) { for (; *argv; argv++) {
if ((hn = ht->getnode2(ht, *argv))) { if ((hn = ht->getnode2(ht, *argv))) {
scanfunc(hn, 0); scanfunc(hn, 0);
@ -439,6 +445,7 @@ bin_enable(char *name, char **argv, char *ops, int func)
returnval = 1; returnval = 1;
} }
} }
unqueue_signals();
return returnval; return returnval;
} }
@ -511,6 +518,7 @@ bin_set(char *nam, char **args, char *ops, int func)
inittyptab(); inittyptab();
/* Show the parameters, possibly with values */ /* Show the parameters, possibly with values */
queue_signals();
if (!hadopt && !*args) if (!hadopt && !*args)
scanhashtable(paramtab, 1, 0, 0, paramtab->printnode, scanhashtable(paramtab, 1, 0, 0, paramtab->printnode,
hadplus ? PRINT_NAMEONLY : 0); 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, scanhashtable(paramtab, 1, PM_ARRAY, 0, paramtab->printnode,
hadplus ? PRINT_NAMEONLY : 0); hadplus ? PRINT_NAMEONLY : 0);
} }
if (!*args && !hadend) if (!*args && !hadend) {
unqueue_signals();
return 0; return 0;
}
if (array) if (array)
args++; args++;
if (sort) if (sort)
@ -550,6 +560,7 @@ bin_set(char *nam, char **args, char *ops, int func)
freearray(pparams); freearray(pparams);
pparams = zarrdup(args); pparams = zarrdup(args);
} }
unqueue_signals();
return 0; 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 /* with the -v option, provide a numbered list of directories, starting at
zero */ zero */
queue_signals();
if (ops['v']) { if (ops['v']) {
LinkNode node; LinkNode node;
int pos = 1; int pos = 1;
@ -599,11 +611,13 @@ bin_dirs(char *name, char **argv, char *ops, int func)
fprintdir(getdata(node), stdout); fprintdir(getdata(node), stdout);
} }
putchar('\n'); putchar('\n');
unqueue_signals();
return 0; return 0;
} }
/* given no arguments, list the stack normally */ /* given no arguments, list the stack normally */
if (!*argv) { if (!*argv) {
printdirstack(); printdirstack();
unqueue_signals();
return 0; return 0;
} }
/* replace the stack with the specified directories */ /* replace the stack with the specified directories */
@ -614,6 +628,7 @@ bin_dirs(char *name, char **argv, char *ops, int func)
freelinklist(dirstack, freestr); freelinklist(dirstack, freestr);
dirstack = l; dirstack = l;
} }
unqueue_signals();
return 0; return 0;
} }
@ -693,9 +708,11 @@ bin_cd(char *nam, char **argv, char *ops, int func)
} }
brk: brk:
chasinglinks = ops['P'] || (isset(CHASELINKS) && !ops['L']); chasinglinks = ops['P'] || (isset(CHASELINKS) && !ops['L']);
queue_signals();
zpushnode(dirstack, ztrdup(pwd)); zpushnode(dirstack, ztrdup(pwd));
if (!(dir = cd_get_dest(nam, argv, ops, func))) { if (!(dir = cd_get_dest(nam, argv, ops, func))) {
zsfree(getlinknode(dirstack)); zsfree(getlinknode(dirstack));
unqueue_signals();
return 1; return 1;
} }
cd_new_pwd(func, dir); cd_new_pwd(func, dir);
@ -715,6 +732,7 @@ bin_cd(char *nam, char **argv, char *ops, int func)
chdir(unmeta(pwd)); chdir(unmeta(pwd));
} }
} }
unqueue_signals();
return 0; return 0;
} }
@ -1192,19 +1210,23 @@ bin_fc(char *nam, char **argv, char *ops, int func)
return 1; return 1;
} }
} }
queue_signals();
if (ops['R']) { if (ops['R']) {
/* read history from a file */ /* read history from a file */
readhistfile(*argv, 1, ops['I'] ? HFILE_SKIPOLD : 0); readhistfile(*argv, 1, ops['I'] ? HFILE_SKIPOLD : 0);
unqueue_signals();
return 0; return 0;
} }
if (ops['W']) { if (ops['W']) {
/* write history to a file */ /* write history to a file */
savehistfile(*argv, 1, ops['I'] ? HFILE_SKIPOLD : 0); savehistfile(*argv, 1, ops['I'] ? HFILE_SKIPOLD : 0);
unqueue_signals();
return 0; return 0;
} }
if (ops['A']) { if (ops['A']) {
/* append history to a file */ /* append history to a file */
savehistfile(*argv, 1, HFILE_APPEND | (ops['I'] ? HFILE_SKIPOLD : 0)); savehistfile(*argv, 1, HFILE_APPEND | (ops['I'] ? HFILE_SKIPOLD : 0));
unqueue_signals();
return 0; return 0;
} }
/* put foo=bar type arguments into the substitution list */ /* 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) { if (*argv) {
minflag = **argv == '-'; minflag = **argv == '-';
first = fcgetcomm(*argv); first = fcgetcomm(*argv);
if (first == -1) if (first == -1) {
unqueue_signals();
return 1; return 1;
}
argv++; argv++;
} }
/* interpret and check second history line specifier */ /* interpret and check second history line specifier */
if (*argv) { if (*argv) {
last = fcgetcomm(*argv); last = fcgetcomm(*argv);
if (last == -1) if (last == -1) {
unqueue_signals();
return 1; return 1;
}
argv++; argv++;
} }
/* There is a maximum of two history specifiers. At least, there * /* There is a maximum of two history specifiers. At least, there *
* will be as long as the history list is one-dimensional. */ * will be as long as the history list is one-dimensional. */
if (*argv) { if (*argv) {
unqueue_signals();
zwarnnam("fc", "too many arguments", NULL, 0); zwarnnam("fc", "too many arguments", NULL, 0);
return 1; return 1;
} }
@ -1256,11 +1283,13 @@ bin_fc(char *nam, char **argv, char *ops, int func)
last = (minflag) ? curhist : first; last = (minflag) ? curhist : first;
else if (last < first) else if (last < first)
last = first; last = first;
if (ops['l']) if (ops['l']) {
/* list the required part of the history */ /* list the required part of the history */
retval = fclist(stdout, !ops['n'], ops['r'], ops['D'], retval = fclist(stdout, !ops['n'], ops['r'], ops['D'],
ops['d'] + ops['f'] * 2 + ops['E'] * 4 + ops['i'] * 8, ops['d'] + ops['f'] * 2 + ops['E'] * 4 + ops['i'] * 8,
first, last, asgf, pprog); first, last, asgf, pprog);
unqueue_signals();
}
else { else {
/* edit history file, and (if successful) use the result as a new command */ /* edit history file, and (if successful) use the result as a new command */
int tempfd; 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)) if (((tempfd = open(fil, O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0600))
== -1) || == -1) ||
((out = fdopen(tempfd, "w")) == NULL)) { ((out = fdopen(tempfd, "w")) == NULL)) {
unqueue_signals();
zwarnnam("fc", "can't open temp file: %e", NULL, errno); zwarnnam("fc", "can't open temp file: %e", NULL, errno);
} else { } else {
if (!fclist(out, 0, ops['r'], 0, 0, first, last, asgf, pprog)) { 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) if (!editor)
editor = DEFAULT_FCEDIT; editor = DEFAULT_FCEDIT;
unqueue_signals();
if (fcedit(editor, fil)) { if (fcedit(editor, fil)) {
if (stuff(fil)) if (stuff(fil))
zwarnnam("fc", "%e: %s", s, errno); zwarnnam("fc", "%e: %s", s, errno);
@ -1289,7 +1320,8 @@ bin_fc(char *nam, char **argv, char *ops, int func)
retval = lastval; retval = lastval;
} }
} }
} } else
unqueue_signals();
} }
unlink(fil); unlink(fil);
} }
@ -1847,6 +1879,8 @@ bin_typeset(char *name, char **argv, char *ops, int func)
on &= ~off; on &= ~off;
queue_signals();
/* Given no arguments, list whatever the options specify. */ /* Given no arguments, list whatever the options specify. */
if (!*argv) { if (!*argv) {
if (!(on|roff)) if (!(on|roff))
@ -1854,6 +1888,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
if (roff || ops['+']) if (roff || ops['+'])
printflags |= PRINT_NAMEONLY; printflags |= PRINT_NAMEONLY;
scanhashtable(paramtab, 1, on|roff, 0, paramtab->printnode, printflags); scanhashtable(paramtab, 1, on|roff, 0, paramtab->printnode, printflags);
unqueue_signals();
return 0; return 0;
} }
@ -1868,20 +1903,27 @@ bin_typeset(char *name, char **argv, char *ops, int func)
if (ops['m']) { if (ops['m']) {
zwarnnam(name, "incompatible options for -T", NULL, 0); zwarnnam(name, "incompatible options for -T", NULL, 0);
unqueue_signals();
return 1; return 1;
} }
on &= ~off; on &= ~off;
if (!argv[1] || argv[2]) { if (!argv[1] || argv[2]) {
zwarnnam(name, "-T requires names of scalar and array", NULL, 0); zwarnnam(name, "-T requires names of scalar and array", NULL, 0);
unqueue_signals();
return 1; return 1;
} }
if (!(asg = getasg(argv[0]))) if (!(asg = getasg(argv[0]))) {
unqueue_signals();
return 1; return 1;
}
asg0 = *asg; asg0 = *asg;
if (!(asg = getasg(argv[1]))) if (!(asg = getasg(argv[1]))) {
unqueue_signals();
return 1; return 1;
}
if (!strcmp(asg0.name, asg->name)) { if (!strcmp(asg0.name, asg->name)) {
unqueue_signals();
zerrnam(name, "can't tie a variable to itself", NULL, 0); zerrnam(name, "can't tie a variable to itself", NULL, 0);
return 1; return 1;
} }
@ -1910,9 +1952,10 @@ bin_typeset(char *name, char **argv, char *ops, int func)
(Param)paramtab->getnode(paramtab, (Param)paramtab->getnode(paramtab,
asg->name), asg->name),
func, (on | PM_ARRAY) & ~PM_EXPORTED, func, (on | PM_ARRAY) & ~PM_EXPORTED,
off, roff, asg->value, NULL))) off, roff, asg->value, NULL))) {
unqueue_signals();
return 1; return 1;
}
/* /*
* Create the tied colonarray. We make it as a normal scalar * Create the tied colonarray. We make it as a normal scalar
* and fix up the oddities later. * and fix up the oddities later.
@ -1924,6 +1967,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
if (oldval) if (oldval)
zsfree(oldval); zsfree(oldval);
unsetparam_pm(apm, 1, 1); unsetparam_pm(apm, 1, 1);
unqueue_signals();
return 1; return 1;
} }
@ -1931,6 +1975,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
apm->ename = ztrdup(asg0.name); apm->ename = ztrdup(asg0.name);
if (oldval) if (oldval)
setsparam(asg0.name, oldval); setsparam(asg0.name, oldval);
unqueue_signals();
return 0; return 0;
} }
@ -1987,6 +2032,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
returnval = 1; returnval = 1;
} }
} }
unqueue_signals();
return returnval; return returnval;
} }
@ -2005,6 +2051,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
func, on, off, roff, asg->value, NULL)) func, on, off, roff, asg->value, NULL))
returnval = 1; returnval = 1;
} }
unqueue_signals();
return returnval; 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 * * are given, we will print only functions containing these *
* flags, else we'll print them all. */ * flags, else we'll print them all. */
if (!*argv) { if (!*argv) {
int ret = 0;
queue_signals();
if (ops['X'] == 1) { if (ops['X'] == 1) {
if ((shf = (Shfunc) shfunctab->getnode(shfunctab, scriptname))) { if ((shf = (Shfunc) shfunctab->getnode(shfunctab, scriptname))) {
DPUTS(!shf->funcdef, DPUTS(!shf->funcdef,
@ -2083,14 +2133,15 @@ bin_functions(char *name, char **argv, char *ops, int func)
shfunctab->addnode(shfunctab, ztrdup(scriptname), shf); shfunctab->addnode(shfunctab, ztrdup(scriptname), shf);
} }
shf->flags = on; shf->flags = on;
return eval_autoload(shf, scriptname, ops, func); ret = eval_autoload(shf, scriptname, ops, func);
} else { } else {
if (ops['U'] && !ops['u']) if (ops['U'] && !ops['u'])
on &= ~PM_UNDEFINED; on &= ~PM_UNDEFINED;
scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode, scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode,
pflags); pflags);
} }
return 0; unqueue_signals();
return ret;
} }
/* With the -m option, treat arguments as glob patterns */ /* 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); tokenize(*argv);
if ((pprog = patcompile(*argv, PAT_STATIC, 0))) { if ((pprog = patcompile(*argv, PAT_STATIC, 0))) {
/* with no options, just print all functions matching the glob pattern */ /* with no options, just print all functions matching the glob pattern */
queue_signals();
if (!(on|off)) { if (!(on|off)) {
scanmatchtable(shfunctab, pprog, 0, DISABLED, scanmatchtable(shfunctab, pprog, 0, DISABLED,
shfunctab->printnode, pflags); shfunctab->printnode, pflags);
@ -2120,6 +2172,7 @@ bin_functions(char *name, char **argv, char *ops, int func)
} }
} }
} }
unqueue_signals();
} else { } else {
untokenize(*argv); untokenize(*argv);
zwarnnam(name, "bad pattern : %s", *argv, 0); 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 */ /* Take the arguments literally -- do not glob */
queue_signals();
for (; *argv; argv++) { for (; *argv; argv++) {
if (ops['w']) if (ops['w'])
returnval = dump_autoload(name, *argv, on, ops, func); returnval = dump_autoload(name, *argv, on, ops, func);
@ -2155,6 +2209,7 @@ bin_functions(char *name, char **argv, char *ops, int func)
} else } else
returnval = 1; returnval = 1;
} }
unqueue_signals();
return returnval; return returnval;
} }
@ -2206,6 +2261,7 @@ bin_unset(char *name, char **argv, char *ops, int func)
tokenize(s); tokenize(s);
if ((pprog = patcompile(s, PAT_STATIC, NULL))) { if ((pprog = patcompile(s, PAT_STATIC, NULL))) {
/* Go through the parameter table, and unset any matches */ /* Go through the parameter table, and unset any matches */
queue_signals();
for (i = 0; i < paramtab->hsize; i++) { for (i = 0; i < paramtab->hsize; i++) {
for (pm = (Param) paramtab->nodes[i]; pm; pm = next) { for (pm = (Param) paramtab->nodes[i]; pm; pm = next) {
/* record pointer to next, since we may free this one */ /* 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 { } else {
untokenize(s); untokenize(s);
zwarnnam(name, "bad pattern : %s", s, 0); 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 */ /* do not glob -- unset the given parameter */
queue_signals();
while ((s = *argv++)) { while ((s = *argv++)) {
char *ss = strchr(s, '['); char *ss = strchr(s, '[');
char *sse = ss; char *sse = ss;
@ -2268,6 +2326,7 @@ bin_unset(char *name, char **argv, char *ops, int func)
if (ss) if (ss)
*ss = '['; *ss = '[';
} }
unqueue_signals();
return returnval; return returnval;
} }
@ -2313,6 +2372,7 @@ bin_whence(char *nam, char **argv, char *ops, int func)
returnval = 1; returnval = 1;
continue; continue;
} }
queue_signals();
if (!ops['p']) { if (!ops['p']) {
/* -p option is for path search only. * /* -p option is for path search only. *
* We're not using it, so search for ... */ * 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, scanmatchtable(cmdnamtab, pprog, 0, 0,
cmdnamtab->printnode, printflags); cmdnamtab->printnode, printflags);
unqueue_signals();
} }
return returnval; return returnval;
} }
/* Take arguments literally -- do not glob */ /* Take arguments literally -- do not glob */
queue_signals();
for (; *argv; argv++) { for (; *argv; argv++) {
informed = 0; informed = 0;
@ -2436,6 +2498,7 @@ bin_whence(char *nam, char **argv, char *ops, int func)
returnval = 1; returnval = 1;
} }
} }
unqueue_signals();
return returnval; return returnval;
} }
@ -2496,10 +2559,13 @@ bin_hash(char *name, char **argv, char *ops, int func)
/* Given no arguments, display current hash table. */ /* Given no arguments, display current hash table. */
if (!*argv) { if (!*argv) {
queue_signals();
scanhashtable(ht, 1, 0, 0, ht->printnode, printflags); scanhashtable(ht, 1, 0, 0, ht->printnode, printflags);
unqueue_signals();
return 0; return 0;
} }
queue_signals();
while (*argv) { while (*argv) {
void *hn; void *hn;
if (ops['m']) { if (ops['m']) {
@ -2553,6 +2619,7 @@ bin_hash(char *name, char **argv, char *ops, int func)
ht->printnode(hn, 0); ht->printnode(hn, 0);
argv++; argv++;
} }
unqueue_signals();
return returnval; return returnval;
} }
@ -2586,6 +2653,7 @@ bin_unhash(char *name, char **argv, char *ops, int func)
tokenize(*argv); tokenize(*argv);
if ((pprog = patcompile(*argv, PAT_STATIC, NULL))) { if ((pprog = patcompile(*argv, PAT_STATIC, NULL))) {
/* remove all nodes matching glob pattern */ /* remove all nodes matching glob pattern */
queue_signals();
for (i = 0; i < ht->hsize; i++) { for (i = 0; i < ht->hsize; i++) {
for (hn = ht->nodes[i]; hn; hn = nhn) { for (hn = ht->nodes[i]; hn; hn = nhn) {
/* record pointer to next, since we may free this one */ /* 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 { } else {
untokenize(*argv); untokenize(*argv);
zwarnnam(name, "bad pattern : %s", *argv, 0); 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 */ /* Take arguments literally -- do not glob */
queue_signals();
for (; *argv; argv++) { for (; *argv; argv++) {
if ((hn = ht->removenode(ht, *argv))) { if ((hn = ht->removenode(ht, *argv))) {
ht->freenode(hn); ht->freenode(hn);
@ -2617,6 +2687,7 @@ bin_unhash(char *name, char **argv, char *ops, int func)
returnval = 1; returnval = 1;
} }
} }
unqueue_signals();
return returnval; 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 * /* In the absence of arguments, list all aliases. If a command *
* line flag is specified, list only those of that type. */ * line flag is specified, list only those of that type. */
if (!*argv) { if (!*argv) {
queue_signals();
scanhashtable(aliastab, 1, flags1, flags2, aliastab->printnode, printflags); scanhashtable(aliastab, 1, flags1, flags2, aliastab->printnode, printflags);
unqueue_signals();
return 0; return 0;
} }
@ -2667,8 +2740,10 @@ bin_alias(char *name, char **argv, char *ops, int func)
tokenize(*argv); /* expand argument */ tokenize(*argv); /* expand argument */
if ((pprog = patcompile(*argv, PAT_STATIC, NULL))) { if ((pprog = patcompile(*argv, PAT_STATIC, NULL))) {
/* display the matching aliases */ /* display the matching aliases */
queue_signals();
scanmatchtable(aliastab, pprog, flags1, flags2, scanmatchtable(aliastab, pprog, flags1, flags2,
aliastab->printnode, printflags); aliastab->printnode, printflags);
unqueue_signals();
} else { } else {
untokenize(*argv); untokenize(*argv);
zwarnnam(name, "bad pattern : %s", *argv, 0); 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 */ /* Take arguments literally. Don't glob */
queue_signals();
while ((asg = getasg(*argv++))) { while ((asg = getasg(*argv++))) {
if (asg->value && !ops['L']) { if (asg->value && !ops['L']) {
/* The argument is of the form foo=bar and we are not * /* 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 } else
returnval = 1; returnval = 1;
} }
unqueue_signals();
return returnval; return returnval;
} }
@ -2774,7 +2851,10 @@ bin_print(char *name, char **args, char *ops, int func)
} }
/* -D option -- interpret as a directory, and use ~ */ /* -D option -- interpret as a directory, and use ~ */
if(ops['D']) { if(ops['D']) {
Nameddir d = finddir(args[n]); Nameddir d;
queue_signals();
d = finddir(args[n]);
if(d) { if(d) {
char *arg = zhalloc(strlen(args[n]) + 1); char *arg = zhalloc(strlen(args[n]) + 1);
sprintf(arg, "~%s%s", d->nam, sprintf(arg, "~%s%s", d->nam,
@ -2782,12 +2862,15 @@ bin_print(char *name, char **args, char *ops, int func)
args[n] = arg; args[n] = arg;
len[n] = strlen(args[n]); len[n] = strlen(args[n]);
} }
unqueue_signals();
} }
} }
/* -z option -- push the arguments onto the editing buffer stack */ /* -z option -- push the arguments onto the editing buffer stack */
if (ops['z']) { if (ops['z']) {
queue_signals();
zpushnode(bufstack, sepjoin(args, NULL, 0)); zpushnode(bufstack, sepjoin(args, NULL, 0));
unqueue_signals();
return 0; return 0;
} }
/* -s option -- add the arguments to the history list */ /* -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; int nwords = 0, nlen, iwords;
char **pargs = args; char **pargs = args;
queue_signals();
ent = prepnexthistent(); ent = prepnexthistent();
while (*pargs++) while (*pargs++)
nwords++; nwords++;
@ -2813,6 +2897,7 @@ bin_print(char *name, char **args, char *ops, int func)
ent->stim = ent->ftim = time(NULL); ent->stim = ent->ftim = time(NULL);
ent->flags = 0; ent->flags = 0;
addhistnode(histtab, ent->text, ent); addhistnode(histtab, ent->text, ent);
unqueue_signals();
return 0; return 0;
} }
/* -u and -p -- output to other than standard output */ /* -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; char **s;
/* optional argument can be either numeric or an array */ /* optional argument can be either numeric or an array */
queue_signals();
if (*argv && !getaparam(*argv)) if (*argv && !getaparam(*argv))
num = mathevali(*argv++); num = mathevali(*argv++);
if (num < 0) { if (num < 0) {
unqueue_signals();
zwarnnam(name, "argument to shift must be non-negative", NULL, 0); zwarnnam(name, "argument to shift must be non-negative", NULL, 0);
return 1; return 1;
} }
@ -2940,6 +3027,7 @@ bin_shift(char *name, char **argv, char *ops, int func)
pparams = s; pparams = s;
} }
} }
unqueue_signals();
return ret; return ret;
} }
@ -3169,7 +3257,7 @@ zexit(int val, int from_signal)
} }
} }
if (sigtrapped[SIGEXIT]) if (sigtrapped[SIGEXIT])
dotrap(SIGEXIT, 1); dotrap(SIGEXIT);
runhookdef(EXITHOOK, NULL); runhookdef(EXITHOOK, NULL);
if (mypid != getpid()) if (mypid != getpid())
_exit(val); _exit(val);
@ -3415,7 +3503,7 @@ bin_read(char *name, char **args, char *ops, int func)
*bptr = readchar; *bptr = readchar;
val = 1; val = 1;
readchar = -1; readchar = -1;
} else if ((val = ztrapread(readfd, bptr, nchars)) <= 0) } else if ((val = read(readfd, bptr, nchars)) <= 0)
break; break;
/* decrement number of characters read from number required */ /* 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']) { if (!izle && !ops['u'] && !ops['p']) {
/* dispose of result appropriately, etc. */ /* dispose of result appropriately, etc. */
if (isem) if (isem)
while (val > 0 && ztrapread(SHTTY, &d, 1) == 1 && d != '\n'); while (val > 0 && read(SHTTY, &d, 1) == 1 && d != '\n');
else else
settyinfo(&shttyinfo); settyinfo(&shttyinfo);
if (haso) { if (haso) {
@ -3686,7 +3774,7 @@ zread(int izle, int *readchar)
} }
for (;;) { for (;;) {
/* read a character from readfd */ /* read a character from readfd */
ret = ztrapread(readfd, &cc, 1); ret = read(readfd, &cc, 1);
switch (ret) { switch (ret) {
case 1: case 1:
/* return the character read */ /* 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 given no arguments, list all currently-set traps */
if (!*argv) { if (!*argv) {
queue_signals();
for (sig = 0; sig < VSIGCOUNT; sig++) { for (sig = 0; sig < VSIGCOUNT; sig++) {
if (sigtrapped[sig] & ZSIG_FUNC) { if (sigtrapped[sig] & ZSIG_FUNC) {
char fname[20]; char fname[20];
@ -3860,6 +3949,7 @@ bin_trap(char *name, char **argv, char *ops, int func)
} }
} }
} }
unqueue_signals();
return 0; return 0;
} }

View file

@ -759,8 +759,6 @@ execsimple(Estate state)
} else } else
lv = (execfuncs[code - WC_CURSH])(state, 0); lv = (execfuncs[code - WC_CURSH])(state, 0);
RUNTRAPS();
return lastval = lv; return lastval = lv;
} }
@ -892,19 +890,19 @@ sublist_done:
noerrexit = oldnoerrexit; noerrexit = oldnoerrexit;
if (sigtrapped[SIGDEBUG]) if (sigtrapped[SIGDEBUG])
dotrap(SIGDEBUG, 1); dotrap(SIGDEBUG);
/* Check whether we are suppressing traps/errexit * /* Check whether we are suppressing traps/errexit *
* (typically in init scripts) and if we haven't * * (typically in init scripts) and if we haven't *
* already performed them for this sublist. */ * already performed them for this sublist. */
if (!noerrexit && !donetrap) { if (!noerrexit && !donetrap) {
if (sigtrapped[SIGZERR] && lastval) { if (sigtrapped[SIGZERR] && lastval) {
dotrap(SIGZERR, 1); dotrap(SIGZERR);
donetrap = 1; donetrap = 1;
} }
if (lastval && isset(ERREXIT)) { if (lastval && isset(ERREXIT)) {
if (sigtrapped[SIGEXIT]) if (sigtrapped[SIGEXIT])
dotrap(SIGEXIT, 1); dotrap(SIGEXIT);
if (mypid != getpid()) if (mypid != getpid())
_exit(lastval); _exit(lastval);
else else
@ -951,9 +949,10 @@ execpline(Estate state, wordcode slcode, int how, int last1)
child_block(); child_block();
/* get free entry in job table and initialize it */ /* get free entry in job table and initialize it */
if ((thisjob = newjob = initjob()) == -1) if ((thisjob = newjob = initjob()) == -1) {
child_unblock();
return 1; return 1;
}
if (how & Z_TIMED) if (how & Z_TIMED)
jobtab[thisjob].stat |= STAT_TIMED; jobtab[thisjob].stat |= STAT_TIMED;
@ -1186,10 +1185,9 @@ execpline2(Estate state, wordcode pcode,
else else
list_pipe_text[0] = '\0'; 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); execcmd(state, input, output, how, last1 ? 1 : 2);
RUNTRAPS(); else {
} else {
int old_list_pipe = list_pipe; int old_list_pipe = list_pipe;
Wordcode next = state->pc + (*state->pc); Wordcode next = state->pc + (*state->pc);
wordcode code; wordcode code;
@ -1224,14 +1222,12 @@ execpline2(Estate state, wordcode pcode,
entersubsh(how, 2, 0); entersubsh(how, 2, 0);
close(synch[1]); close(synch[1]);
execcmd(state, input, pipes[1], how, 0); execcmd(state, input, pipes[1], how, 0);
RUNTRAPS();
_exit(lastval); _exit(lastval);
} }
} else { } else {
/* otherwise just do the pipeline normally. */ /* otherwise just do the pipeline normally. */
subsh_close = pipes[0]; subsh_close = pipes[0];
execcmd(state, input, pipes[1], how, 0); execcmd(state, input, pipes[1], how, 0);
RUNTRAPS();
} }
zclose(pipes[1]); zclose(pipes[1]);
state->pc = next; 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 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 * used in execsubst() which might be called from one of the functions
* called from execcmd() (like execfor() and so on). */ * 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) if (subsh_close >= 0)
zclose(subsh_close); zclose(subsh_close);
subsh_close = -1; subsh_close = -1;
execshfunc((Shfunc) hn, args); execshfunc((Shfunc) hn, args);
#ifdef PATH_DEV_FD #ifdef PATH_DEV_FD
for (i = 10; i <= max_zsh_fd; i++) for (i = 10; i <= max_zsh_fd; i++)

View file

@ -279,14 +279,17 @@ insert(char *s, int checked)
char *news = s; char *news = s;
int statted = 0; int statted = 0;
queue_signals();
inserts = NULL; inserts = NULL;
if (gf_listtypes || gf_markdirs) { if (gf_listtypes || gf_markdirs) {
/* Add the type marker to the end of the filename */ /* Add the type marker to the end of the filename */
mode_t mode; mode_t mode;
checked = statted = 1; checked = statted = 1;
if (statfullpath(s, &buf, 1)) if (statfullpath(s, &buf, 1)) {
unqueue_signals();
return; return;
}
mode = buf.st_mode; mode = buf.st_mode;
if (gf_follow) { if (gf_follow) {
if (!S_ISLNK(mode) || statfullpath(s, &buf2, 0)) 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 */ /* Go through the qualifiers, rejecting the file if appropriate */
struct qual *qo, *qn; struct qual *qo, *qn;
if (!statted && statfullpath(s, &buf, 1)) if (!statted && statfullpath(s, &buf, 1)) {
unqueue_signals();
return; return;
}
news = dyncat(pathbuf, news); news = dyncat(pathbuf, news);
statted = 1; statted = 1;
@ -330,16 +334,20 @@ insert(char *s, int checked)
* vice versa. */ * vice versa. */
if ((!((qn->func) (news, bp, qn->data, qn->sdata)) ^ qn->sense) & 1) { if ((!((qn->func) (news, bp, qn->data, qn->sdata)) ^ qn->sense) & 1) {
/* Try next alternative, or return if there are no more */ /* Try next alternative, or return if there are no more */
if (!(qo = qo->or)) if (!(qo = qo->or)) {
unqueue_signals();
return; return;
}
qn = qo; qn = qo;
continue; continue;
} }
qn = qn->next; qn = qn->next;
} }
} else if (!checked) { } else if (!checked) {
if (statfullpath(s, NULL, 1)) if (statfullpath(s, NULL, 1)) {
unqueue_signals();
return; return;
}
statted = 1; statted = 1;
news = dyncat(pathbuf, news); news = dyncat(pathbuf, news);
} else } else
@ -389,6 +397,7 @@ insert(char *s, int checked)
if (!inserts) if (!inserts)
break; break;
} }
unqueue_signals();
} }
/* Check to see if str is eligible for filename generation. */ /* Check to see if str is eligible for filename generation. */

View file

@ -560,11 +560,14 @@ int
bin_hashinfo(char *nam, char **args, char *ops, int func) bin_hashinfo(char *nam, char **args, char *ops, int func)
{ {
HashTable ht; HashTable ht;
printf("----------------------------------------------------\n"); printf("----------------------------------------------------\n");
queue_signals();
for(ht = firstht; ht; ht = ht->next) { for(ht = firstht; ht; ht = ht->next) {
ht->printinfo(ht); ht->printinfo(ht);
printf("----------------------------------------------------\n"); printf("----------------------------------------------------\n");
} }
unqueue_signals();
return 0; return 0;
} }

View file

@ -382,6 +382,7 @@ histsubchar(int c)
/* get event number */ /* get event number */
queue_signals();
if (c == '?') { if (c == '?') {
for (;;) { for (;;) {
c = ingetc(); c = ingetc();
@ -397,6 +398,7 @@ histsubchar(int c)
evset = 0; evset = 0;
if (ev == -1) { if (ev == -1) {
herrflush(); herrflush();
unqueue_signals();
zerr("no such event: %s", buf, 0); zerr("no such event: %s", buf, 0);
return -1; return -1;
} }
@ -450,6 +452,7 @@ histsubchar(int c)
evset = 1; evset = 1;
} else if ((ev = hcomsearch(buf)) == -1) { } else if ((ev = hcomsearch(buf)) == -1) {
herrflush(); herrflush();
unqueue_signals();
zerr("event not found: %s", buf, 0); zerr("event not found: %s", buf, 0);
return -1; return -1;
} else } else
@ -458,9 +461,10 @@ histsubchar(int c)
/* get the event */ /* get the event */
if (!(ehist = gethist(defev = ev))) if (!(ehist = gethist(defev = ev))) {
unqueue_signals();
return -1; return -1;
}
/* extract the relevant arguments */ /* extract the relevant arguments */
argc = getargc(ehist); argc = getargc(ehist);
@ -473,6 +477,7 @@ histsubchar(int c)
argc = getargc(ehist); argc = getargc(ehist);
} else { } else {
herrflush(); herrflush();
unqueue_signals();
zerr("Ambiguous history reference", NULL, 0); zerr("Ambiguous history reference", NULL, 0);
return -1; return -1;
} }
@ -486,8 +491,10 @@ histsubchar(int c)
} else { } else {
inungetc(c); inungetc(c);
larg = farg = getargspec(argc, marg, evset); larg = farg = getargspec(argc, marg, evset);
if (larg == -2) if (larg == -2) {
unqueue_signals();
return -1; return -1;
}
if (farg != -1) if (farg != -1)
cflag = 0; cflag = 0;
c = ingetc(); c = ingetc();
@ -497,8 +504,10 @@ histsubchar(int c)
} else if (c == '-') { } else if (c == '-') {
cflag = 0; cflag = 0;
larg = getargspec(argc, marg, evset); larg = getargspec(argc, marg, evset);
if (larg == -2) if (larg == -2) {
unqueue_signals();
return -1; return -1;
}
if (larg == -1) if (larg == -1)
larg = argc - 1; larg = argc - 1;
} else } else
@ -508,8 +517,11 @@ histsubchar(int c)
farg = 0; farg = 0;
if (larg == -1) if (larg == -1)
larg = argc; larg = argc;
if (!(sline = getargs(ehist, farg, larg))) if (!(sline = getargs(ehist, farg, larg))) {
unqueue_signals();
return -1; return -1;
}
unqueue_signals();
} }
/* do the modifiers */ /* do the modifiers */
@ -1000,10 +1012,12 @@ mod_export int
hend(Eprog prog) hend(Eprog prog)
{ {
int flag, save = 1; int flag, save = 1;
char *hf = getsparam("HISTFILE"); char *hf;
DPUTS(stophist != 2 && !(inbufflags & INP_ALIAS) && !chline, DPUTS(stophist != 2 && !(inbufflags & INP_ALIAS) && !chline,
"BUG: chline is NULL in hend()"); "BUG: chline is NULL in hend()");
queue_signals();
hf = getsparam("HISTFILE");
if (histdone & HISTFLAG_SETTY) if (histdone & HISTFLAG_SETTY)
settyinfo(&shttyinfo); settyinfo(&shttyinfo);
if (!(histactive & HA_NOINC)) if (!(histactive & HA_NOINC))
@ -1013,6 +1027,7 @@ hend(Eprog prog)
zfree(chwords, chwordlen*sizeof(short)); zfree(chwords, chwordlen*sizeof(short));
chline = NULL; chline = NULL;
histactive = 0; histactive = 0;
unqueue_signals();
return 1; return 1;
} }
if (hist_ignore_all_dups != isset(HISTIGNOREALLDUPS) if (hist_ignore_all_dups != isset(HISTIGNOREALLDUPS)
@ -1107,6 +1122,7 @@ hend(Eprog prog)
if (isset(SHAREHISTORY)? histfileIsLocked() : isset(INCAPPENDHISTORY)) if (isset(SHAREHISTORY)? histfileIsLocked() : isset(INCAPPENDHISTORY))
savehistfile(hf, 0, HFILE_USE_OPTIONS | HFILE_FAST); savehistfile(hf, 0, HFILE_USE_OPTIONS | HFILE_FAST);
unlockhistfile(hf); /* It's OK to call this even if we aren't locked */ unlockhistfile(hf); /* It's OK to call this even if we aren't locked */
unqueue_signals();
return !(flag & HISTFLAG_NOEXEC || errflag); return !(flag & HISTFLAG_NOEXEC || errflag);
} }

View file

@ -170,7 +170,7 @@ loop(int toplevel, int justonce)
} }
if (isset(SINGLECOMMAND) && toplevel) { if (isset(SINGLECOMMAND) && toplevel) {
if (sigtrapped[SIGEXIT]) if (sigtrapped[SIGEXIT])
dotrap(SIGEXIT, 1); dotrap(SIGEXIT);
exit(lastval); exit(lastval);
} }
if (justonce) if (justonce)
@ -1022,6 +1022,7 @@ sourcehome(char *s)
{ {
char *h; char *h;
queue_signals();
if (emulation == EMULATE_SH || emulation == EMULATE_KSH || if (emulation == EMULATE_SH || emulation == EMULATE_KSH ||
!(h = getsparam("ZDOTDIR"))) !(h = getsparam("ZDOTDIR")))
h = home; h = home;
@ -1030,6 +1031,7 @@ sourcehome(char *s)
/* Let source() complain if path is too long */ /* Let source() complain if path is too long */
VARARR(char, buf, strlen(h) + strlen(s) + 2); VARARR(char, buf, strlen(h) + strlen(s) + 2);
sprintf(buf, "%s/%s", h, s); sprintf(buf, "%s/%s", h, s);
unqueue_signals();
source(buf); source(buf);
} }
} }

View file

@ -141,9 +141,7 @@ shingetline(void)
for (;;) { for (;;) {
do { do {
errno = 0; errno = 0;
ALLOWTRAPS { c = fgetc(bshin);
c = fgetc(bshin);
} DISALLOWTRAPS;
} while (c < 0 && errno == EINTR); } while (c < 0 && errno == EINTR);
if (c < 0 || c == '\n') { if (c < 0 || c == '\n') {
if (c == '\n') if (c == '\n')

View file

@ -378,7 +378,7 @@ update_job(Job jn)
zrefresh(); zrefresh();
} }
if (sigtrapped[SIGCHLD] && job != thisjob) if (sigtrapped[SIGCHLD] && job != thisjob)
dotrap(SIGCHLD, 0); dotrap(SIGCHLD);
/* When MONITOR is set, the foreground process runs in a different * /* When MONITOR is set, the foreground process runs in a different *
* process group from the shell, so the shell will not receive * * 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 (sig == SIGINT || sig == SIGQUIT) {
if (sigtrapped[sig]) { if (sigtrapped[sig]) {
dotrap(sig, 0); dotrap(sig);
/* We keep the errflag as set or not by dotrap. /* We keep the errflag as set or not by dotrap.
* This is to fulfil the promise to carry on * This is to fulfil the promise to carry on
* with the jobs if trap returns zero. * 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) percent = 100.0 * (ti->ut + ti->st)
/ (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0); / (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0);
queue_signals();
if (!(s = getsparam("TIMEFMT"))) if (!(s = getsparam("TIMEFMT")))
s = DEFAULT_TIMEFMT; s = DEFAULT_TIMEFMT;
@ -546,6 +547,7 @@ printtime(struct timeval *real, struct timeinfo *ti, char *desc)
break; break;
} else } else
putc(*s, stderr); putc(*s, stderr);
unqueue_signals();
putc('\n', stderr); putc('\n', stderr);
fflush(stderr); fflush(stderr);
} }
@ -580,10 +582,13 @@ should_report_time(Job j)
if (j->stat & STAT_TIMED) if (j->stat & STAT_TIMED)
return 1; return 1;
queue_signals();
if (!(v = getvalue(&vbuf, &s, 0)) || if (!(v = getvalue(&vbuf, &s, 0)) ||
(reporttime = getintvalue(v)) < 0) { (reporttime = getintvalue(v)) < 0) {
unqueue_signals();
return 0; return 0;
} }
unqueue_signals();
/* can this ever happen? */ /* can this ever happen? */
if (!j->procs) if (!j->procs)
return 0; return 0;
@ -868,9 +873,10 @@ havefiles(void)
void void
waitforpid(pid_t pid) waitforpid(pid_t pid)
{ {
int first = 1; int first = 1, q = queue_signal_level();
/* child_block() around this loop in case #ifndef WNOHANG */ /* child_block() around this loop in case #ifndef WNOHANG */
dont_queue_signals();
child_block(); /* unblocked in child_suspend() */ child_block(); /* unblocked in child_suspend() */
while (!errflag && (kill(pid, 0) >= 0 || errno != ESRCH)) { while (!errflag && (kill(pid, 0) >= 0 || errno != ESRCH)) {
if (first) if (first)
@ -878,12 +884,11 @@ waitforpid(pid_t pid)
else else
kill(pid, SIGCONT); kill(pid, SIGCONT);
ALLOWTRAPS { child_suspend(SIGINT);
child_suspend(SIGINT);
} DISALLOWTRAPS;
child_block(); child_block();
} }
child_unblock(); child_unblock();
restore_queue_signals(q);
} }
/* wait for a job to finish */ /* wait for a job to finish */
@ -892,8 +897,10 @@ waitforpid(pid_t pid)
static void static void
zwaitjob(int job, int sig) zwaitjob(int job, int sig)
{ {
int q = queue_signal_level();
Job jn = jobtab + job; Job jn = jobtab + job;
dont_queue_signals();
child_block(); /* unblocked during child_suspend() */ child_block(); /* unblocked during child_suspend() */
if (jn->procs) { /* if any forks were done */ if (jn->procs) { /* if any forks were done */
jn->stat |= STAT_LOCKED; jn->stat |= STAT_LOCKED;
@ -902,9 +909,7 @@ zwaitjob(int job, int sig)
while (!errflag && jn->stat && while (!errflag && jn->stat &&
!(jn->stat & STAT_DONE) && !(jn->stat & STAT_DONE) &&
!(interact && (jn->stat & STAT_STOPPED))) { !(interact && (jn->stat & STAT_STOPPED))) {
ALLOWTRAPS { child_suspend(sig);
child_suspend(sig);
} DISALLOWTRAPS;
/* Commenting this out makes ^C-ing a job started by a function /* Commenting this out makes ^C-ing a job started by a function
stop the whole function again. But I guess it will stop stop the whole function again. But I guess it will stop
something else from working properly, we have to find out something else from working properly, we have to find out
@ -926,6 +931,7 @@ zwaitjob(int job, int sig)
numpipestats = 1; numpipestats = 1;
} }
child_unblock(); child_unblock();
restore_queue_signals(q);
} }
/* wait for running job to finish */ /* 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); zwarnnam(name, "-Z requires one argument", NULL, 0);
return 1; return 1;
} }
queue_signals();
unmetafy(*argv, &len); unmetafy(*argv, &len);
if(len > hackspace) if(len > hackspace)
len = hackspace; len = hackspace;
memcpy(hackzero, *argv, len); memcpy(hackzero, *argv, len);
memset(hackzero + len, 0, hackspace - len); memset(hackzero + len, 0, hackspace - len);
unqueue_signals();
return 0; return 0;
} }
@ -1292,6 +1300,7 @@ bin_fg(char *name, char **argv, char *ops, int func)
pid_t pid = (long)atoi(*argv); pid_t pid = (long)atoi(*argv);
Job j; Job j;
Process p; Process p;
if (findproc(pid, &j, &p)) if (findproc(pid, &j, &p))
waitforpid(pid); waitforpid(pid);
else else

View file

@ -495,10 +495,12 @@ getcvar(char *s)
mnumber mn; mnumber mn;
mn.type = MN_INTEGER; mn.type = MN_INTEGER;
queue_signals();
if (!(t = getsparam(s))) if (!(t = getsparam(s)))
mn.u.l = 0; mn.u.l = 0;
else else
mn.u.l = STOUC(*t == Meta ? t[1] ^ 32 : *t); mn.u.l = STOUC(*t == Meta ? t[1] ^ 32 : *t);
unqueue_signals();
return mn; return mn;
} }

View file

@ -115,9 +115,13 @@ static Heap fheap;
mod_export Heap mod_export Heap
new_heaps(void) new_heaps(void)
{ {
Heap h = heaps; Heap h;
queue_signals();
h = heaps;
fheap = heaps = NULL; fheap = heaps = NULL;
unqueue_signals();
return h; return h;
} }
@ -130,6 +134,7 @@ old_heaps(Heap old)
{ {
Heap h, n; Heap h, n;
queue_signals();
for (h = heaps; h; h = n) { for (h = heaps; h; h = n) {
n = h->next; n = h->next;
DPUTS(h->sp, "BUG: old_heaps() with pushed heaps"); DPUTS(h->sp, "BUG: old_heaps() with pushed heaps");
@ -141,6 +146,7 @@ old_heaps(Heap old)
} }
heaps = old; heaps = old;
fheap = NULL; fheap = NULL;
unqueue_signals();
} }
/* Temporarily switch to other heaps (or back again). */ /* Temporarily switch to other heaps (or back again). */
@ -149,10 +155,14 @@ old_heaps(Heap old)
mod_export Heap mod_export Heap
switch_heaps(Heap new) switch_heaps(Heap new)
{ {
Heap h = heaps; Heap h;
queue_signals();
h = heaps;
heaps = new; heaps = new;
fheap = NULL; fheap = NULL;
unqueue_signals();
return h; return h;
} }
@ -166,6 +176,8 @@ pushheap(void)
Heap h; Heap h;
Heapstack hs; Heapstack hs;
queue_signals();
#if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG) #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
h_push++; h_push++;
#endif #endif
@ -177,6 +189,7 @@ pushheap(void)
h->sp = hs; h->sp = hs;
hs->used = h->used; hs->used = h->used;
} }
unqueue_signals();
} }
/* reset heaps to previous state */ /* reset heaps to previous state */
@ -187,6 +200,8 @@ freeheap(void)
{ {
Heap h, hn, hl = NULL; Heap h, hn, hl = NULL;
queue_signals();
#if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG) #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
h_free++; h_free++;
#endif #endif
@ -214,6 +229,8 @@ freeheap(void)
hl->next = NULL; hl->next = NULL;
else else
heaps = NULL; heaps = NULL;
unqueue_signals();
} }
/* reset heap to previous state and destroy state information */ /* reset heap to previous state and destroy state information */
@ -225,6 +242,8 @@ popheap(void)
Heap h, hn, hl = NULL; Heap h, hn, hl = NULL;
Heapstack hs; Heapstack hs;
queue_signals();
#if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG) #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
h_pop++; h_pop++;
#endif #endif
@ -255,6 +274,8 @@ popheap(void)
hl->next = NULL; hl->next = NULL;
else else
heaps = NULL; heaps = NULL;
unqueue_signals();
} }
/* allocate memory from the current memory pool */ /* allocate memory from the current memory pool */
@ -268,6 +289,8 @@ zhalloc(size_t size)
size = (size + H_ISIZE - 1) & ~(H_ISIZE - 1); size = (size + H_ISIZE - 1) & ~(H_ISIZE - 1);
queue_signals();
#if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG) #if defined(ZSH_MEM) && defined(ZSH_MEM_DEBUG)
h_m[size < (1024 * H_ISIZE) ? (size / H_ISIZE) : 1024]++; h_m[size < (1024 * H_ISIZE) ? (size / H_ISIZE) : 1024]++;
#endif #endif
@ -276,8 +299,12 @@ zhalloc(size_t size)
for (h = (fheap ? fheap : heaps); h; h = h->next) { for (h = (fheap ? fheap : heaps); h; h = h->next) {
if (HEAP_ARENA_SIZE >= (n = size + h->used)) { if (HEAP_ARENA_SIZE >= (n = size + h->used)) {
void *ret;
h->used = n; 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 */ /* tricky, see above */
#endif #endif
queue_signals();
n = HEAP_ARENA_SIZE > size ? HEAPSIZE : size + sizeof(*h); n = HEAP_ARENA_SIZE > size ? HEAPSIZE : size + sizeof(*h);
for (hp = NULL, h = heaps; h; hp = h, h = h->next); 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 */ /* find the heap with p */
queue_signals();
for (h = heaps, ph = NULL; h; ph = h, h = h->next) for (h = heaps, ph = NULL; h; ph = h, h = h->next)
if (p >= arena(h) && p < arena(h) + HEAP_ARENA_SIZE) if (p >= arena(h) && p < arena(h) + HEAP_ARENA_SIZE)
break; break;
@ -376,9 +403,12 @@ hrealloc(char *p, size_t old, size_t new)
#ifdef ZSH_MEM_DEBUG #ifdef ZSH_MEM_DEBUG
memset(p, 0xff, old); memset(p, 0xff, old);
#endif #endif
unqueue_signals();
return ptr; return ptr;
} else } else {
unqueue_signals();
return new ? p : NULL; return new ? p : NULL;
}
} }
DPUTS(p + old != arena(h) + h->used, "BUG: hrealloc more than allocated"); 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 #else
zfree(h, HEAPSIZE); zfree(h, HEAPSIZE);
#endif #endif
unqueue_signals();
return NULL; return NULL;
} }
#ifndef USE_MMAP #ifndef USE_MMAP
@ -407,6 +438,7 @@ hrealloc(char *p, size_t old, size_t new)
heaps = h = (Heap) realloc(h, n); heaps = h = (Heap) realloc(h, n);
} }
h->used = new; h->used = new;
unqueue_signals();
return arena(h); return arena(h);
#endif #endif
} }
@ -415,6 +447,7 @@ hrealloc(char *p, size_t old, size_t new)
#endif #endif
if (h->used + (new - old) <= HEAP_ARENA_SIZE) { if (h->used + (new - old) <= HEAP_ARENA_SIZE) {
h->used += new - old; h->used += new - old;
unqueue_signals();
return p; return p;
} else { } else {
char *t = zhalloc(new); char *t = zhalloc(new);
@ -423,6 +456,7 @@ hrealloc(char *p, size_t old, size_t new)
#ifdef ZSH_MEM_DEBUG #ifdef ZSH_MEM_DEBUG
memset(p, 0xff, old); memset(p, 0xff, old);
#endif #endif
unqueue_signals();
return t; return t;
} }
} }
@ -450,10 +484,12 @@ zalloc(size_t size)
if (!size) if (!size)
size = 1; size = 1;
queue_signals();
if (!(ptr = (void *) malloc(size))) { if (!(ptr = (void *) malloc(size))) {
zerr("fatal error: out of memory", NULL, 0); zerr("fatal error: out of memory", NULL, 0);
exit(1); exit(1);
} }
unqueue_signals();
return ptr; return ptr;
} }
@ -466,10 +502,12 @@ zcalloc(size_t size)
if (!size) if (!size)
size = 1; size = 1;
queue_signals();
if (!(ptr = (void *) malloc(size))) { if (!(ptr = (void *) malloc(size))) {
zerr("fatal error: out of memory", NULL, 0); zerr("fatal error: out of memory", NULL, 0);
exit(1); exit(1);
} }
unqueue_signals();
memset(ptr, 0, size); memset(ptr, 0, size);
return ptr; return ptr;
@ -485,6 +523,7 @@ zcalloc(size_t size)
mod_export void * mod_export void *
zrealloc(void *ptr, size_t size) zrealloc(void *ptr, size_t size)
{ {
queue_signals();
if (ptr) { if (ptr) {
if (size) { if (size) {
/* Do normal realloc */ /* Do normal realloc */
@ -492,18 +531,22 @@ zrealloc(void *ptr, size_t size)
zerr("fatal error: out of memory", NULL, 0); zerr("fatal error: out of memory", NULL, 0);
exit(1); exit(1);
} }
unqueue_signals();
return ptr; return ptr;
} }
else else
/* If ptr is not NULL, but size is zero, * /* If ptr is not NULL, but size is zero, *
* then object pointed to is freed. */ * then object pointed to is freed. */
free(ptr); free(ptr);
ptr = NULL;
} else { } else {
/* If ptr is NULL, then behave like malloc */ /* 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]; char *b, *c, buf[40];
long u = 0, f = 0, to, cu; long u = 0, f = 0, to, cu;
queue_signals();
if (ops['v']) { if (ops['v']) {
printf("The lower and the upper addresses of the heap. Diff gives\n"); 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"); 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]) if (h_m[1024])
printf("big\t%d\n", h_m[1024]); printf("big\t%d\n", h_m[1024]);
unqueue_signals();
return 0; return 0;
} }

View file

@ -763,10 +763,13 @@ load_module(char const *name)
* chain of aliases. This makes sure the actual module loaded * chain of aliases. This makes sure the actual module loaded
* is the right one. * is the right one.
*/ */
queue_signals();
if (!(node = find_module(name, 1, &name))) { if (!(node = find_module(name, 1, &name))) {
if (!(linked = module_linked(name)) && if (!(linked = module_linked(name)) &&
!(handle = do_load_module(name))) !(handle = do_load_module(name))) {
unqueue_signals();
return 0; return 0;
}
m = zcalloc(sizeof(*m)); m = zcalloc(sizeof(*m));
m->nam = ztrdup(name); m->nam = ztrdup(name);
if (handle) { if (handle) {
@ -782,19 +785,25 @@ load_module(char const *name)
if (!set) if (!set)
finish_module(m); finish_module(m);
delete_module(node); delete_module(node);
unqueue_signals();
return 0; return 0;
} }
m->flags |= MOD_INIT_S | MOD_INIT_B; m->flags |= MOD_INIT_S | MOD_INIT_B;
m->flags &= ~MOD_SETUP; m->flags &= ~MOD_SETUP;
unqueue_signals();
return 1; return 1;
} }
m = (Module) getdata(node); m = (Module) getdata(node);
if (m->flags & MOD_SETUP) if (m->flags & MOD_SETUP) {
unqueue_signals();
return 1; return 1;
}
if (m->flags & MOD_UNLOAD) if (m->flags & MOD_UNLOAD)
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; return 1;
}
if (m->flags & MOD_BUSY) { if (m->flags & MOD_BUSY) {
zerr("circular dependencies for module %s", name, 0); zerr("circular dependencies for module %s", name, 0);
return 0; return 0;
@ -804,14 +813,17 @@ load_module(char const *name)
for (n = firstnode(m->deps); n; incnode(n)) for (n = firstnode(m->deps); n; incnode(n))
if (!load_module((char *) getdata(n))) { if (!load_module((char *) getdata(n))) {
m->flags &= ~MOD_BUSY; m->flags &= ~MOD_BUSY;
unqueue_signals();
return 0; return 0;
} }
m->flags &= ~MOD_BUSY; m->flags &= ~MOD_BUSY;
if (!m->u.handle) { if (!m->u.handle) {
handle = NULL; handle = NULL;
if (!(linked = module_linked(name)) && if (!(linked = module_linked(name)) &&
!(handle = do_load_module(name))) !(handle = do_load_module(name))) {
unqueue_signals();
return 0; return 0;
}
if (handle) { if (handle) {
m->u.handle = handle; m->u.handle = handle;
m->flags |= MOD_SETUP; m->flags |= MOD_SETUP;
@ -825,6 +837,7 @@ load_module(char const *name)
else else
m->u.linked = NULL; m->u.linked = NULL;
m->flags &= ~MOD_SETUP; m->flags &= ~MOD_SETUP;
unqueue_signals();
return 0; return 0;
} }
m->flags |= MOD_INIT_S; m->flags |= MOD_INIT_S;
@ -837,10 +850,12 @@ load_module(char const *name)
else else
m->u.handle = NULL; m->u.handle = NULL;
m->flags &= ~MOD_SETUP; m->flags &= ~MOD_SETUP;
unqueue_signals();
return 0; return 0;
} }
m->flags |= MOD_INIT_B; m->flags |= MOD_INIT_B;
m->flags &= ~MOD_SETUP; m->flags &= ~MOD_SETUP;
unqueue_signals();
return 1; return 1;
} }
@ -858,19 +873,23 @@ require_module(char *nam, const char *module, int res, int test)
{ {
Module m = NULL; Module m = NULL;
LinkNode node; LinkNode node;
int ret = 1;
/* Resolve aliases and actual loadable module as for load_module */ /* Resolve aliases and actual loadable module as for load_module */
queue_signals();
node = find_module(module, 1, &module); node = find_module(module, 1, &module);
if (node && (m = ((Module) getdata(node)))->u.handle && if (node && (m = ((Module) getdata(node)))->u.handle &&
!(m->flags & MOD_UNLOAD)) { !(m->flags & MOD_UNLOAD)) {
if (test) { if (test) {
unqueue_signals();
zwarnnam(nam, "module %s already loaded.", module, 0); zwarnnam(nam, "module %s already loaded.", module, 0);
return 0; return 0;
} }
} else } 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_bcpf = ops['b'] || ops['c'] || ops['p'] || ops['f'];
int ops_au = ops['a'] || ops['u']; int ops_au = ops['a'] || ops['u'];
int ret = 1;
if (ops_bcpf && !ops_au) { if (ops_bcpf && !ops_au) {
zwarnnam(nam, "-b, -c, -f, and -p must be combined with -a or -u", zwarnnam(nam, "-b, -c, -f, and -p must be combined with -a or -u",
NULL, 0); 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); zwarnnam(nam, "-e cannot be combined with other options", NULL, 0);
return 1; return 1;
} }
queue_signals();
if (ops['e']) if (ops['e'])
return bin_zmodload_exist(nam, args, ops); ret = bin_zmodload_exist(nam, args, ops);
else if (ops['d']) 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'])) 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'])) 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'])) 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'])) 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'])) 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 else
zwarnnam(nam, "use only one of -b, -c, or -p", NULL, 0); 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; Param pm;
queue_signals();
if ((pm = (Param) gethashnode2(paramtab, nam))) if ((pm = (Param) gethashnode2(paramtab, nam)))
unsetparam_pm(pm, 0, 1); unsetparam_pm(pm, 0, 1);
pm = setsparam(nam, ztrdup(module)); pm = setsparam(nam, ztrdup(module));
pm->flags |= PM_AUTOLOAD; pm->flags |= PM_AUTOLOAD;
unqueue_signals();
} }
/* List of math functions. */ /* List of math functions. */

View file

@ -1806,6 +1806,7 @@ setsparam(char *s, char *val)
errflag = 1; errflag = 1;
return NULL; return NULL;
} }
queue_signals();
if ((ss = strchr(s, '['))) { if ((ss = strchr(s, '['))) {
*ss = '\0'; *ss = '\0';
if (!(v = getvalue(&vbuf, &s, 1))) if (!(v = getvalue(&vbuf, &s, 1)))
@ -1823,10 +1824,12 @@ setsparam(char *s, char *val)
} }
} }
if (!v && !(v = getvalue(&vbuf, &t, 1))) { if (!v && !(v = getvalue(&vbuf, &t, 1))) {
unqueue_signals();
zsfree(val); zsfree(val);
return NULL; return NULL;
} }
setstrvalue(v, val); setstrvalue(v, val);
unqueue_signals();
return v->pm; return v->pm;
} }
@ -1845,12 +1848,14 @@ setaparam(char *s, char **val)
errflag = 1; errflag = 1;
return NULL; return NULL;
} }
queue_signals();
if ((ss = strchr(s, '['))) { if ((ss = strchr(s, '['))) {
*ss = '\0'; *ss = '\0';
if (!(v = getvalue(&vbuf, &s, 1))) if (!(v = getvalue(&vbuf, &s, 1)))
createparam(t, PM_ARRAY); createparam(t, PM_ARRAY);
*ss = '['; *ss = '[';
if (v && PM_TYPE(v->pm->flags) == PM_HASHED) { if (v && PM_TYPE(v->pm->flags) == PM_HASHED) {
unqueue_signals();
zerr("attempt to set slice of associative array", NULL, 0); zerr("attempt to set slice of associative array", NULL, 0);
freearray(val); freearray(val);
errflag = 1; errflag = 1;
@ -1869,9 +1874,12 @@ setaparam(char *s, char **val)
} }
} }
if (!v) if (!v)
if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING))) if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING))) {
unqueue_signals();
return NULL; return NULL;
}
setarrvalue(v, val); setarrvalue(v, val);
unqueue_signals();
return v->pm; return v->pm;
} }
@ -1894,20 +1902,23 @@ sethparam(char *s, char **val)
zerr("nested associative arrays not yet supported", NULL, 0); zerr("nested associative arrays not yet supported", NULL, 0);
errflag = 1; errflag = 1;
return NULL; return NULL;
} else { }
if (!(v = fetchvalue(&vbuf, &s, 1, SCANPM_ASSIGNING))) queue_signals();
createparam(t, PM_HASHED); if (!(v = fetchvalue(&vbuf, &s, 1, SCANPM_ASSIGNING)))
else if (!(PM_TYPE(v->pm->flags) & PM_HASHED) && createparam(t, PM_HASHED);
!(v->pm->flags & PM_SPECIAL)) { else if (!(PM_TYPE(v->pm->flags) & PM_HASHED) &&
unsetparam(t); !(v->pm->flags & PM_SPECIAL)) {
createparam(t, PM_HASHED); unsetparam(t);
v = NULL; createparam(t, PM_HASHED);
} v = NULL;
} }
if (!v) if (!v)
if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING))) if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING))) {
unqueue_signals();
return NULL; return NULL;
}
setarrvalue(v, val); setarrvalue(v, val);
unqueue_signals();
return v->pm; return v->pm;
} }
@ -1926,6 +1937,7 @@ setiparam(char *s, zlong val)
errflag = 1; errflag = 1;
return NULL; return NULL;
} }
queue_signals();
if (!(v = getvalue(&vbuf, &s, 1))) { if (!(v = getvalue(&vbuf, &s, 1))) {
if ((ss = strchr(s, '['))) if ((ss = strchr(s, '[')))
*ss = '\0'; *ss = '\0';
@ -1937,12 +1949,14 @@ setiparam(char *s, zlong val)
DPUTS(!v, "BUG: value not found for new parameter"); DPUTS(!v, "BUG: value not found for new parameter");
} else { } else {
pm->u.val = val; pm->u.val = val;
unqueue_signals();
return pm; return pm;
} }
} }
mnval.type = MN_INTEGER; mnval.type = MN_INTEGER;
mnval.u.l = val; mnval.u.l = val;
setnumvalue(v, mnval); setnumvalue(v, mnval);
unqueue_signals();
return v->pm; return v->pm;
} }
@ -1965,6 +1979,7 @@ setnparam(char *s, mnumber val)
errflag = 1; errflag = 1;
return NULL; return NULL;
} }
queue_signals();
if (!(v = getvalue(&vbuf, &s, 1))) { if (!(v = getvalue(&vbuf, &s, 1))) {
if ((ss = strchr(s, '['))) if ((ss = strchr(s, '[')))
*ss = '\0'; *ss = '\0';
@ -1981,10 +1996,12 @@ setnparam(char *s, mnumber val)
pm->u.val = val.u.l; pm->u.val = val.u.l;
} else } else
pm->u.dval = val.u.d; pm->u.dval = val.u.d;
unqueue_signals();
return pm; return pm;
} }
} }
setnumvalue(v, val); setnumvalue(v, val);
unqueue_signals();
return v->pm; return v->pm;
} }
@ -1996,10 +2013,12 @@ unsetparam(char *s)
{ {
Param pm; Param pm;
queue_signals();
if ((pm = (Param) (paramtab == realparamtab ? if ((pm = (Param) (paramtab == realparamtab ?
gethashnode2(paramtab, s) : gethashnode2(paramtab, s) :
paramtab->getnode(paramtab, s)))) paramtab->getnode(paramtab, s))))
unsetparam_pm(pm, 0, 1); unsetparam_pm(pm, 0, 1);
unqueue_signals();
} }
/* Unset a parameter */ /* Unset a parameter */
@ -2614,9 +2633,11 @@ setlang(char *x)
struct localename *ln; struct localename *ln;
setlocale(LC_ALL, x ? x : ""); setlocale(LC_ALL, x ? x : "");
queue_signals();
for (ln = lc_names; ln->name; ln++) for (ln = lc_names; ln->name; ln++)
if ((x = getsparam(ln->name))) if ((x = getsparam(ln->name)))
setlocale(ln->category, x); setlocale(ln->category, x);
unqueue_signals();
} }
/**/ /**/
@ -2624,8 +2645,11 @@ void
lc_allsetfn(Param pm, char *x) lc_allsetfn(Param pm, char *x)
{ {
strsetfn(pm, x); strsetfn(pm, x);
if (!x) if (!x) {
queue_signals();
setlang(getsparam("LANG")); setlang(getsparam("LANG"));
unqueue_signals();
}
else else
setlocale(LC_ALL, x); setlocale(LC_ALL, x);
} }
@ -2647,12 +2671,14 @@ lcsetfn(Param pm, char *x)
strsetfn(pm, x); strsetfn(pm, x);
if (getsparam("LC_ALL")) if (getsparam("LC_ALL"))
return; return;
queue_signals();
if (!x) if (!x)
x = getsparam("LANG"); x = getsparam("LANG");
for (ln = lc_names; ln->name; ln++) for (ln = lc_names; ln->name; ln++)
if (!strcmp(ln->name, pm->nam)) if (!strcmp(ln->name, pm->nam))
setlocale(ln->category, x ? x : ""); setlocale(ln->category, x ? x : "");
unqueue_signals();
} }
#endif /* USE_LOCALE */ #endif /* USE_LOCALE */

View file

@ -2312,7 +2312,7 @@ dump_find_func(Wordcode h, char *name)
int int
bin_zcompile(char *nam, char **args, char *ops, int func) bin_zcompile(char *nam, char **args, char *ops, int func)
{ {
int map, flags; int map, flags, ret;
char *dump; char *dump;
if ((ops['k'] && ops['z']) || (ops['R'] && ops['M']) || 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)); map = (ops['M'] ? 2 : (ops['R'] ? 0 : 1));
if (!args[1] && !(ops['c'] || ops['a'])) if (!args[1] && !(ops['c'] || ops['a'])) {
return build_dump(nam, dyncat(*args, FD_EXT), args, ops['U'], map, flags); 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)); dump = (strsfx(FD_EXT, *args) ? *args : dyncat(*args, FD_EXT));
return ((ops['c'] || ops['a']) ? queue_signals();
build_cur_dump(nam, dump, args + 1, ops['m'], map, ret = ((ops['c'] || ops['a']) ?
(ops['c'] ? 1 : 0) | (ops['a'] ? 2 : 0)) : build_cur_dump(nam, dump, args + 1, ops['m'], map,
build_dump(nam, dump, args + 1, ops['U'], map, flags)); (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 /* 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; int rd, rc, rn;
char *dig, *wc; char *dig, *wc;
if (strsfx(FD_EXT, path)) if (strsfx(FD_EXT, path)) {
return check_dump_file(path, NULL, name, ksh); queue_signals();
prog = check_dump_file(path, NULL, name, ksh);
unqueue_signals();
return prog;
}
dig = dyncat(path, FD_EXT); dig = dyncat(path, FD_EXT);
wc = dyncat(file, 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 * both the uncompiled function file and its compiled version (or they
* don't exist) and the digest file contains the definition for the * don't exist) and the digest file contains the definition for the
* function. */ * function. */
queue_signals();
if (!rd && if (!rd &&
(rc || std.st_mtime > stc.st_mtime) && (rc || std.st_mtime > stc.st_mtime) &&
(rn || std.st_mtime > stn.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; return prog;
}
/* No digest file. Now look for the per-function compiled file. */ /* No digest file. Now look for the per-function compiled file. */
if (!rc && if (!rc &&
(rn || stc.st_mtime > stn.st_mtime) && (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; return prog;
}
/* No compiled file for the function. The caller (getfpfunc() will /* No compiled file for the function. The caller (getfpfunc() will
* check if the directory contains the uncompiled file for it. */ * check if the directory contains the uncompiled file for it. */
unqueue_signals();
return NULL; return NULL;
} }
@ -2872,18 +2886,24 @@ try_source_file(char *file)
else else
tail = file; tail = file;
if (strsfx(FD_EXT, file)) if (strsfx(FD_EXT, file)) {
return check_dump_file(file, NULL, tail, NULL); queue_signals();
prog = check_dump_file(file, NULL, tail, NULL);
unqueue_signals();
return prog;
}
wc = dyncat(file, FD_EXT); wc = dyncat(file, FD_EXT);
rc = stat(wc, &stc); rc = stat(wc, &stc);
rn = stat(file, &stn); rn = stat(file, &stn);
queue_signals();
if (!rc && (rn || stc.st_mtime > stn.st_mtime) && 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; return prog;
}
unqueue_signals();
return NULL; return NULL;
} }

View file

@ -372,12 +372,15 @@ putpromptchar(int doprint, int endchar)
bp += strlen(bp); bp += strlen(bp);
break; break;
case 'M': case 'M':
queue_signals();
if ((hostnam = getsparam("HOST"))) if ((hostnam = getsparam("HOST")))
stradd(hostnam); stradd(hostnam);
unqueue_signals();
break; break;
case 'm': case 'm':
if (!arg) if (!arg)
arg++; arg++;
queue_signals();
if (!(hostnam = getsparam("HOST"))) if (!(hostnam = getsparam("HOST")))
break; break;
if (arg < 0) { if (arg < 0) {
@ -394,6 +397,7 @@ putpromptchar(int doprint, int endchar)
stradd(hostnam); stradd(hostnam);
*ss = t0; *ss = t0;
} }
unqueue_signals();
break; break;
case 'S': case 'S':
txtchangeset(TXTSTANDOUT, TXTNOSTANDOUT); txtchangeset(TXTSTANDOUT, TXTNOSTANDOUT);

View file

@ -497,7 +497,7 @@ handler(int sig)
case SIGHUP: case SIGHUP:
if (sigtrapped[SIGHUP]) if (sigtrapped[SIGHUP])
dotrap(SIGHUP, 0); dotrap(SIGHUP);
else { else {
stopmsg = 1; stopmsg = 1;
zexit(SIGHUP, 1); zexit(SIGHUP, 1);
@ -506,7 +506,7 @@ handler(int sig)
case SIGINT: case SIGINT:
if (sigtrapped[SIGINT]) if (sigtrapped[SIGINT])
dotrap(SIGINT, 0); dotrap(SIGINT);
else { else {
if ((isset(PRIVILEGED) || isset(RESTRICTED)) && if ((isset(PRIVILEGED) || isset(RESTRICTED)) &&
isset(INTERACTIVE) && noerrexit < 0) isset(INTERACTIVE) && noerrexit < 0)
@ -523,14 +523,14 @@ handler(int sig)
case SIGWINCH: case SIGWINCH:
adjustwinsize(1); /* check window size and adjust */ adjustwinsize(1); /* check window size and adjust */
if (sigtrapped[SIGWINCH]) if (sigtrapped[SIGWINCH])
dotrap(SIGWINCH, 0); dotrap(SIGWINCH);
break; break;
#endif #endif
case SIGALRM: case SIGALRM:
if (sigtrapped[SIGALRM]) { if (sigtrapped[SIGALRM]) {
int tmout; int tmout;
dotrap(SIGALRM, 0); dotrap(SIGALRM);
if ((tmout = getiparam("TMOUT"))) if ((tmout = getiparam("TMOUT")))
alarm(tmout); /* reset the alarm */ alarm(tmout); /* reset the alarm */
@ -549,7 +549,7 @@ handler(int sig)
break; break;
default: default:
dotrap(sig, 0); dotrap(sig);
break; break;
} /* end of switch(sig) */ } /* end of switch(sig) */
@ -703,6 +703,7 @@ settrap(int sig, Eprog l)
* Call unsettrap() unconditionally, to make sure trap is saved * Call unsettrap() unconditionally, to make sure trap is saved
* if necessary. * if necessary.
*/ */
queue_signals();
unsettrap(sig); unsettrap(sig);
sigfuncs[sig] = l; sigfuncs[sig] = l;
@ -729,6 +730,7 @@ settrap(int sig, Eprog l)
* works just the same. * works just the same.
*/ */
sigtrapped[sig] |= (locallevel << ZSIG_SHIFT); sigtrapped[sig] |= (locallevel << ZSIG_SHIFT);
unqueue_signals();
return 0; return 0;
} }
@ -736,9 +738,13 @@ settrap(int sig, Eprog l)
void void
unsettrap(int sig) unsettrap(int sig)
{ {
HashNode hn = removetrap(sig); HashNode hn;
queue_signals();
hn = removetrap(sig);
if (hn) if (hn)
shfunctab->freenode(hn); shfunctab->freenode(hn);
unqueue_signals();
} }
/**/ /**/
@ -751,6 +757,7 @@ removetrap(int sig)
(jobbing && (sig == SIGTTOU || sig == SIGTSTP || sig == SIGTTIN))) (jobbing && (sig == SIGTTOU || sig == SIGTSTP || sig == SIGTTIN)))
return NULL; return NULL;
queue_signals();
trapped = sigtrapped[sig]; trapped = sigtrapped[sig];
/* /*
* Note that we save the trap here even if there isn't an existing * 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))) (!trapped || locallevel > (sigtrapped[sig] >> ZSIG_SHIFT)))
dosavetrap(sig, locallevel); dosavetrap(sig, locallevel);
if (!trapped) if (!trapped) {
unqueue_signals();
return NULL; return NULL;
}
sigtrapped[sig] = 0; sigtrapped[sig] = 0;
if (sig == SIGINT && interact) { if (sig == SIGINT && interact) {
/* PWS 1995/05/16: added test for interactive, also noholdintr() * /* PWS 1995/05/16: added test for interactive, also noholdintr() *
@ -790,6 +798,7 @@ removetrap(int sig)
*/ */
if (trapped & ZSIG_FUNC) { if (trapped & ZSIG_FUNC) {
char func[20]; char func[20];
HashNode node;
sprintf(func, "TRAP%s", sigs[sig]); sprintf(func, "TRAP%s", sigs[sig]);
/* /*
@ -797,11 +806,15 @@ removetrap(int sig)
* that calls back into unsettrap(); * that calls back into unsettrap();
*/ */
sigfuncs[sig] = NULL; sigfuncs[sig] = NULL;
return removehashnode(shfunctab, func); node = removehashnode(shfunctab, func);
unqueue_signals();
return node;
} else if (sigfuncs[sig]) { } else if (sigfuncs[sig]) {
freeeprog(sigfuncs[sig]); freeeprog(sigfuncs[sig]);
sigfuncs[sig] = NULL; sigfuncs[sig] = NULL;
} }
unqueue_signals();
return NULL; return NULL;
} }
@ -966,56 +979,15 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
*sigtr &= ~ZSIG_IGNORED; *sigtr &= ~ZSIG_IGNORED;
} }
/* != 0 if trap handlers can be called immediately */ /* Standard call to execute a trap for a given signal. */
/**/
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. */
/**/ /**/
void void
dotrap(int sig, int now) dotrap(int sig)
{ {
/* Copied from dotrapargs(). */ /* Copied from dotrapargs(). */
if ((sigtrapped[sig] & ZSIG_IGNORED) || !sigfuncs[sig] || errflag) if ((sigtrapped[sig] & ZSIG_IGNORED) || !sigfuncs[sig] || errflag)
return; return;
if (now || trapsallowed) { dotrapargs(sig, sigtrapped+sig, sigfuncs[sig]);
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;
} }

View file

@ -73,26 +73,34 @@
* queue signals, it is probably overkill for zsh to do * * queue signals, it is probably overkill for zsh to do *
* this, but it shouldn't hurt anything to do it anyway. */ * this, but it shouldn't hurt anything to do it anyway. */
/* Right now I'm queueing all signals, but maybe we only * #define MAX_QUEUE_SIZE 128
* need to queue SIGCHLD. Anybody know? */
#define MAX_QUEUE_SIZE 16
#define queue_signals() (queueing_enabled++) #define queue_signals() (queueing_enabled++)
#define unqueue_signals() do { \ #define run_queued_signals() do { \
DPUTS(!queueing_enabled, "BUG: unqueue_signals called but not queueing"); \ while (queue_front != queue_rear) { /* while signals in queue */ \
if (!--queueing_enabled) { \ sigset_t oset; \
while (queue_front != queue_rear) { /* while signals in queue */ \ queue_front = (queue_front + 1) % MAX_QUEUE_SIZE; \
sigset_t oset; \ oset = signal_setmask(signal_mask_queue[queue_front]); \
queue_front = (queue_front + 1) % MAX_QUEUE_SIZE; \ handler(signal_queue[queue_front]); /* handle queued signal */ \
oset = signal_setmask(signal_mask_queue[queue_front]); \ signal_setmask(oset); \
handler(signal_queue[queue_front]); /* handle queued signal */ \
signal_setmask(oset); \
} \
} \ } \
} while (0) } while (0)
#define unqueue_signals() do { \
DPUTS(!queueing_enabled, "BUG: unqueue_signals called but not queueing"); \
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. */ /* Make some signal functions faster. */
@ -117,9 +125,3 @@ extern sigset_t signal_block _((sigset_t));
#else #else
extern sigset_t signal_unblock _((sigset_t)); extern sigset_t signal_unblock _((sigset_t));
#endif /* POSIX_SIGNALS */ #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)

View file

@ -51,6 +51,7 @@ prefork(LinkList list, int flags)
{ {
LinkNode node; LinkNode node;
queue_signals();
for (node = firstnode(list); node; incnode(node)) { for (node = firstnode(list); node; incnode(node)) {
char *str, c; char *str, c;
@ -61,14 +62,18 @@ prefork(LinkList list, int flags)
setdata(node, (void *) getproc(str)); /* <(...) or >(...) */ setdata(node, (void *) getproc(str)); /* <(...) or >(...) */
else else
setdata(node, (void *) getoutputfile(str)); /* =(...) */ setdata(node, (void *) getoutputfile(str)); /* =(...) */
if (!getdata(node)) if (!getdata(node)) {
unqueue_signals();
return; return;
}
} else { } else {
if (isset(SHFILEEXPANSION)) if (isset(SHFILEEXPANSION))
filesub((char **)getaddrdata(node), filesub((char **)getaddrdata(node),
flags & (PF_TYPESET|PF_ASSIGN)); flags & (PF_TYPESET|PF_ASSIGN));
if (!(node = stringsubst(list, node, flags & PF_SINGLE))) if (!(node = stringsubst(list, node, flags & PF_SINGLE))) {
unqueue_signals();
return; return;
}
} }
} }
for (node = firstnode(list); node; incnode(node)) { for (node = firstnode(list); node; incnode(node)) {
@ -82,9 +87,12 @@ prefork(LinkList list, int flags)
flags & (PF_TYPESET|PF_ASSIGN)); flags & (PF_TYPESET|PF_ASSIGN));
} else if (!(flags & PF_SINGLE)) } else if (!(flags & PF_SINGLE))
uremnode(list, node); uremnode(list, node);
if (errflag) if (errflag) {
unqueue_signals();
return; return;
}
} }
unqueue_signals();
} }
/**/ /**/

View file

@ -691,12 +691,16 @@ preprompt(void)
if (mailpath && *mailpath && **mailpath) if (mailpath && *mailpath && **mailpath)
checkmailpath(mailpath); checkmailpath(mailpath);
else if ((mailfile = getsparam("MAIL")) && *mailfile) { else {
char *x[2]; queue_signals();
if ((mailfile = getsparam("MAIL")) && *mailfile) {
char *x[2];
x[0] = mailfile; x[0] = mailfile;
x[1] = NULL; x[1] = NULL;
checkmailpath(x); checkmailpath(x);
}
unqueue_signals();
} }
lastmailcheck = time(NULL); lastmailcheck = time(NULL);
} }
@ -1091,17 +1095,21 @@ zclose(int fd)
mod_export char * mod_export char *
gettempname(void) gettempname(void)
{ {
char *s; char *s, *ret;
queue_signals();
if (!(s = getsparam("TMPPREFIX"))) if (!(s = getsparam("TMPPREFIX")))
s = DEFAULT_TMPPREFIX; s = DEFAULT_TMPPREFIX;
#ifdef HAVE__MKTEMP #ifdef HAVE__MKTEMP
/* Zsh uses mktemp() safely, so silence the warnings */ /* Zsh uses mktemp() safely, so silence the warnings */
return ((char *) _mktemp(dyncat(unmeta(s), "XXXXXX"))); ret = ((char *) _mktemp(dyncat(unmeta(s), "XXXXXX")));
#else #else
return ((char *) mktemp(dyncat(unmeta(s), "XXXXXX"))); ret = ((char *) mktemp(dyncat(unmeta(s), "XXXXXX")));
#endif #endif
unqueue_signals();
return ret;
} }
/* Check if a string contains a token */ /* Check if a string contains a token */
@ -1417,39 +1425,13 @@ checkrmall(char *s)
return (getquery("ny", 1) == 'y'); 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 int
read1char(void) read1char(void)
{ {
char c; char c;
while (ztrapread(SHTTY, &c, 1) != 1) { while (read(SHTTY, &c, 1) != 1) {
if (errno != EINTR || errflag || retflag || breaks || contflag) if (errno != EINTR || errflag || retflag || breaks || contflag)
return -1; return -1;
} }
@ -1467,7 +1449,7 @@ noquery(int purge)
ioctl(SHTTY, FIONREAD, (char *)&val); ioctl(SHTTY, FIONREAD, (char *)&val);
if (purge) { if (purge) {
for (; val; val--) for (; val; val--)
ztrapread(SHTTY, &c, 1); read(SHTTY, &c, 1);
} }
#endif #endif
@ -2122,12 +2104,14 @@ mod_export void
zbeep(void) zbeep(void)
{ {
char *vb; char *vb;
queue_signals();
if ((vb = getsparam("ZBEEP"))) { if ((vb = getsparam("ZBEEP"))) {
int len; int len;
vb = getkeystring(vb, &len, 2, NULL); vb = getkeystring(vb, &len, 2, NULL);
write(SHTTY, vb, len); write(SHTTY, vb, len);
} else if (isset(BEEP)) } else if (isset(BEEP))
write(SHTTY, "\07", 1); write(SHTTY, "\07", 1);
unqueue_signals();
} }
/**/ /**/

View file

@ -235,7 +235,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
# endif /* WATCH_UTMP_UT_HOST */ # endif /* WATCH_UTMP_UT_HOST */
while (*fmt) while (*fmt)
if (*fmt == '\\') if (*fmt == '\\') {
if (*++fmt) { if (*++fmt) {
if (prnt) if (prnt)
putchar(*fmt); putchar(*fmt);
@ -244,6 +244,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
return fmt; return fmt;
else else
break; break;
}
else if (*fmt == fini) else if (*fmt == fini)
return ++fmt; return ++fmt;
else if (*fmt != '%') { else if (*fmt != '%') {
@ -490,8 +491,6 @@ dowatch(void)
int uct, wct; int uct, wct;
s = watch; s = watch;
if (!(fmt = getsparam("WATCHFMT")))
fmt = DEFAULT_WATCHFMT;
holdintr(); holdintr();
if (!wtab) { if (!wtab) {
@ -541,6 +540,9 @@ dowatch(void)
free(utab); free(utab);
return; return;
} }
queue_signals();
if (!(fmt = getsparam("WATCHFMT")))
fmt = DEFAULT_WATCHFMT;
while ((uct || wct) && !errflag) while ((uct || wct) && !errflag)
if (!uct || (wct && ucmp(uptr, wptr) > 0)) if (!uct || (wct && ucmp(uptr, wptr) > 0))
wct--, watchlog(0, wptr++, s, fmt); wct--, watchlog(0, wptr++, s, fmt);
@ -548,6 +550,7 @@ dowatch(void)
uct--, watchlog(1, uptr++, s, fmt); uct--, watchlog(1, uptr++, s, fmt);
else else
uptr++, wptr++, wct--, uct--; uptr++, wptr++, wct--, uct--;
unqueue_signals();
free(wtab); free(wtab);
wtab = utab; wtab = utab;
wtabsz = utabsz; wtabsz = utabsz;