1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-28 17:10:59 +01:00

Sven: 13108: Handle traps synchronously

pws: 13109, 13111: clear up zle display when output produced in trap.
This commit is contained in:
Peter Stephenson 2000-11-11 19:50:27 +00:00
parent 89d480f57d
commit c292a3ae50
15 changed files with 387 additions and 202 deletions

View file

@ -1,3 +1,15 @@
2000-11-11 Peter Stephenson <pws@pwstephenson.fsnet.co.uk>
* 13109, 13111: Doc/Zsh/mod_zle.yo, Src/Zle/zle_main.c,
Src/Zle/zle_thingy.c, Src/signals.c: `zle -I' allows trap code
to clear up display when output occurs in a trap.
* Sven: 13108: Src/Modules/zftp.c, Src/Modules/zpty.c,
Src/Zle/zle_main.c, Src/builtin.c, Src/exec.c, Src/init.c,
Src/input.c, Src/jobs.c, Src/signals.c, Src/signals.h,
Src/utils.c, Src/zsh.h: Execute user traps synchronously if it is
unsafe to execute it directly from the signal handler.
2000-11-09 Clint Adams <schizo@debian.org> 2000-11-09 Clint Adams <schizo@debian.org>
* 13125: Completion/User/_mailboxes: evaluate the mailboxes * 13125: Completion/User/_mailboxes: evaluate the mailboxes

View file

@ -198,6 +198,7 @@ xitem(tt(zle) tt(-C) var(widget) var(completion-widget) var(function))
xitem(tt(zle) tt(-R) [ tt(-c) ] [ var(display-string) ] [ var(string) ... ]) xitem(tt(zle) tt(-R) [ tt(-c) ] [ var(display-string) ] [ var(string) ... ])
xitem(tt(zle) tt(-M) var(string)) xitem(tt(zle) tt(-M) var(string))
xitem(tt(zle) tt(-U) var(string)) xitem(tt(zle) tt(-U) var(string))
xitem(tt(zle) tt(-I))
xitem(tt(zle) var(widget) tt([ -n) var(num) tt(]) tt([ -N ]) var(args) ...) xitem(tt(zle) var(widget) tt([ -n) var(num) tt(]) tt([ -N ]) var(args) ...)
item(tt(zle))( item(tt(zle))(
The tt(zle) builtin performs a number of different actions concerning The tt(zle) builtin performs a number of different actions concerning
@ -263,6 +264,11 @@ cleared.
Note that this option is only useful for widgets that do not exit Note that this option is only useful for widgets that do not exit
immediately after using it because the strings displayed will be erased immediately after using it because the strings displayed will be erased
immediately after return from the widget. immediately after return from the widget.
This command can safely be called outside user defined widgets; if zle is
active, the display will be refreshed, while if zle is not active, the
command has no effect. In this case there will usually be no other
arguments. The status is zero if zle was active, else one.
) )
item(tt(-M) var(string))( item(tt(-M) var(string))(
As with the tt(-R) option, the var(string) will be displayed below the As with the tt(-R) option, the var(string) will be displayed below the
@ -281,6 +287,28 @@ the last string pushed onto the stack will be processed first. However,
the characters in each var(string) will be processed in the order in which the characters in each var(string) will be processed in the order in which
they appear in the string. they appear in the string.
) )
item(tt(-I))(
Unusually, this option is only useful em(outside) ordinary widget functions.
It invalidates the current zle display in preparation for output; usually
this will be from a trap function. It has no effect if zle is not
active. When a trap exits, the shell checks to see if the display needs
restoring, hence the following will print output in such a way as not to
disturb the line being edited:
example(TRAPUSR1() {
# Invalidate zle display
zle -I
# Show output
print Hello
})
Note that there are better ways of manipulating the display from within zle
widgets. In general, the trap function may need to test whether zle is
loaded before using this method; if it is not, there is no point in loading
it specially since the line editor will not be active.
The status is zero if zle was active, else one.
)
item(var(widget) tt([ -n) var(num) tt(]) tt([ -N ]) var(args) ...)( item(var(widget) tt([ -n) var(num) tt(]) tt([ -N ]) var(args) ...)(
Invoke the specified widget. This can only be done when ZLE is Invoke the specified widget. This can only be done when ZLE is
active; normally this will be within a user-defined widget. active; normally this will be within a user-defined widget.

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;
write(zfsess->cfd, cmdbuf, 3); ztrapwrite(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;
write(zfsess->cfd, cmdbuf, 3); ztrapwrite(zfsess->cfd, cmdbuf, 3);
continue; continue;
case EOF: case EOF:
@ -996,7 +996,7 @@ zfsendcmd(char *cmd)
return 6; return 6;
} }
zfalarm(tmout); zfalarm(tmout);
ret = write(zfsess->cfd, cmd, strlen(cmd)); ret = ztrapwrite(zfsess->cfd, cmd, strlen(cmd));
alarm(0); alarm(0);
if (ret <= 0) { if (ret <= 0) {
@ -1470,7 +1470,7 @@ zfread(int fd, char *bf, off_t sz, int tmout)
int ret; int ret;
if (!tmout) if (!tmout)
return read(fd, bf, sz); return ztrapread(fd, bf, sz);
if (setjmp(zfalrmbuf)) { if (setjmp(zfalrmbuf)) {
alarm(0); alarm(0);
@ -1479,7 +1479,7 @@ zfread(int fd, char *bf, off_t sz, int tmout)
} }
zfalarm(tmout); zfalarm(tmout);
ret = read(fd, bf, sz); ret = ztrapread(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 +1495,7 @@ zfwrite(int fd, char *bf, off_t sz, int tmout)
int ret; int ret;
if (!tmout) if (!tmout)
return write(fd, bf, sz); return ztrapwrite(fd, bf, sz);
if (setjmp(zfalrmbuf)) { if (setjmp(zfalrmbuf)) {
alarm(0); alarm(0);
@ -1504,7 +1504,7 @@ zfwrite(int fd, char *bf, off_t sz, int tmout)
} }
zfalarm(tmout); zfalarm(tmout);
ret = write(fd, bf, sz); ret = ztrapwrite(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);
@ -2846,7 +2846,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);
write(zfstatfd, zfstatusp+zfsessno, sizeof(int)); ztrapwrite(zfstatfd, zfstatusp+zfsessno, sizeof(int));
close(zfstatfd); close(zfstatfd);
zfstatfd = -1; zfstatfd = -1;
@ -3123,7 +3123,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);
read(zfstatfd, zfstatusp, sizeof(int)*zfsesscnt); ztrapread(zfstatfd, 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;
@ -3212,7 +3212,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);
write(zfstatfd, zfstatusp+zfsessno, sizeof(int)); ztrapwrite(zfstatfd, zfstatusp+zfsessno, sizeof(int));
} }
return ret; return ret;
} }

View file

@ -536,7 +536,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 = write(cmd->fd, s, len)) < 0 && cmd->nblock && if ((written = ztrapwrite(cmd->fd, s, len)) < 0 && cmd->nblock &&
#ifdef EWOULDBLOCK #ifdef EWOULDBLOCK
errno == EWOULDBLOCK errno == EWOULDBLOCK
#else #else
@ -578,7 +578,7 @@ ptywrite(Ptycmd cmd, char **args, int nonl)
int n; int n;
char buf[BUFSIZ]; char buf[BUFSIZ];
while ((n = read(0, buf, BUFSIZ)) > 0) while ((n = ztrapread(0, buf, BUFSIZ)) > 0)
if (ptywritestr(cmd, buf, n)) if (ptywritestr(cmd, buf, n))
return 1; return 1;
} }

View file

@ -313,11 +313,17 @@ 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);
return (select(fd + 1, (SELECT_ARG_2_T) & f, NULL, NULL, NULL) == -1 ?
ALLOWTRAPS {
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
@ -388,7 +394,7 @@ getkey(int keytmout)
# else # else
ioctl(SHTTY, TCSETA, &ti.tio); ioctl(SHTTY, TCSETA, &ti.tio);
# endif # endif
r = read(SHTTY, &cc, 1); r = ztrapread(SHTTY, &cc, 1);
# ifdef HAVE_TERMIOS_H # ifdef HAVE_TERMIOS_H
tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio); tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio);
# else # else
@ -398,7 +404,10 @@ getkey(int keytmout)
# endif # endif
#endif #endif
} }
while ((r = read(SHTTY, &cc, 1)) != 1) { for (;;) {
r = ztrapread(SHTTY, &cc, 1);
if (r == 1)
break;
if (r == 0) { if (r == 0) {
/* The test for IGNOREEOF was added to make zsh ignore ^Ds /* The test for IGNOREEOF was added to make zsh ignore ^Ds
that were typed while commands are running. Unfortuantely that were typed while commands are running. Unfortuantely
@ -1083,7 +1092,7 @@ zleaftertrap(Hookdef dummy, void *dat)
static struct builtin bintab[] = { static struct builtin bintab[] = {
BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", NULL), BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", NULL),
BUILTIN("vared", 0, bin_vared, 1, 7, 0, NULL, NULL), BUILTIN("vared", 0, bin_vared, 1, 7, 0, NULL, NULL),
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGcRaU", NULL), BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGcRaUI", NULL),
}; };
/* The order of the entries in this table has to match the *HOOK /* The order of the entries in this table has to match the *HOOK

View file

@ -339,6 +339,7 @@ bin_zle(char *name, char **args, char *ops, int func)
{ 'R', bin_zle_refresh, 0, -1 }, { 'R', bin_zle_refresh, 0, -1 },
{ 'M', bin_zle_mesg, 1, 1 }, { 'M', bin_zle_mesg, 1, 1 },
{ 'U', bin_zle_unget, 1, 1 }, { 'U', bin_zle_unget, 1, 1 },
{ 'I', bin_zle_invalidate, 0, 0 },
{ 0, bin_zle_call, 0, -1 }, { 0, bin_zle_call, 0, -1 },
}; };
struct opn const *op, *opp; struct opn const *op, *opp;
@ -396,10 +397,8 @@ bin_zle_refresh(char *name, char **args, char *ops, char func)
char *s = statusline; char *s = statusline;
int sl = statusll, ocl = clearlist; int sl = statusll, ocl = clearlist;
if (!zleactive) { if (!zleactive)
zwarnnam(name, "can only be called from widget function", NULL, 0);
return 1; return 1;
}
statusline = NULL; statusline = NULL;
statusll = 0; statusll = 0;
if (*args) { if (*args) {
@ -656,6 +655,17 @@ bin_zle_call(char *name, char **args, char *ops, char func)
return ret; return ret;
} }
/**/
static int
bin_zle_invalidate(char *name, char **args, char *ops, char func)
{
if (zleactive) {
trashzle();
return 0;
} else
return 1;
}
/*******************/ /*******************/
/* initialiasation */ /* initialiasation */
/*******************/ /*******************/

View file

@ -3218,7 +3218,7 @@ zexit(int val, int from_signal)
checkjobs(); /* check if any jobs are running/stopped */ checkjobs(); /* check if any jobs are running/stopped */
if (stopmsg) { if (stopmsg) {
stopmsg = 2; stopmsg = 2;
LASTALLOC_RETURN; return;
} }
} }
if (in_exit++ && from_signal) if (in_exit++ && from_signal)
@ -3240,7 +3240,7 @@ zexit(int val, int from_signal)
} }
} }
if (sigtrapped[SIGEXIT]) if (sigtrapped[SIGEXIT])
dotrap(SIGEXIT); dotrap(SIGEXIT, 1);
runhookdef(EXITHOOK, NULL); runhookdef(EXITHOOK, NULL);
if (mypid != getpid()) if (mypid != getpid())
_exit(val); _exit(val);
@ -3486,7 +3486,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 = read(readfd, bptr, nchars)) <= 0) } else if ((val = ztrapread(readfd, bptr, nchars)) <= 0)
break; break;
/* decrement number of characters read from number required */ /* decrement number of characters read from number required */
@ -3500,7 +3500,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 && read(SHTTY, &d, 1) == 1 && d != '\n'); while (val > 0 && ztrapread(SHTTY, &d, 1) == 1 && d != '\n');
else else
settyinfo(&shttyinfo); settyinfo(&shttyinfo);
if (haso) { if (haso) {
@ -3733,6 +3733,7 @@ static int
zread(int izle, int *readchar) zread(int izle, int *readchar)
{ {
char cc, retry = 0; char cc, retry = 0;
int ret;
if (izle) { if (izle) {
int c = getkeyptr(0); int c = getkeyptr(0);
@ -3756,7 +3757,8 @@ zread(int izle, int *readchar)
} }
for (;;) { for (;;) {
/* read a character from readfd */ /* read a character from readfd */
switch (read(readfd, &cc, 1)) { ret = ztrapread(readfd, &cc, 1);
switch (ret) {
case 1: case 1:
/* return the character read */ /* return the character read */
return STOUC(cc); return STOUC(cc);

View file

@ -738,6 +738,7 @@ static int
execsimple(Estate state) execsimple(Estate state)
{ {
wordcode code = *state->pc++; wordcode code = *state->pc++;
int lv;
if (errflag) if (errflag)
return (lastval = 1); return (lastval = 1);
@ -754,9 +755,13 @@ execsimple(Estate state)
fputc('\n', xtrerr); fputc('\n', xtrerr);
fflush(xtrerr); fflush(xtrerr);
} }
return (lastval = (errflag ? errflag : cmdoutval)); lv = (errflag ? errflag : cmdoutval);
} else } else
return (lastval = (execfuncs[code - WC_CURSH])(state, 0)); lv = (execfuncs[code - WC_CURSH])(state, 0);
RUNTRAPS();
return lastval = lv;
} }
/* Main routine for executing a list. * /* Main routine for executing a list. *
@ -887,19 +892,19 @@ sublist_done:
noerrexit = oldnoerrexit; noerrexit = oldnoerrexit;
if (sigtrapped[SIGDEBUG]) if (sigtrapped[SIGDEBUG])
dotrap(SIGDEBUG); dotrap(SIGDEBUG, 1);
/* 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); dotrap(SIGZERR, 1);
donetrap = 1; donetrap = 1;
} }
if (lastval && isset(ERREXIT)) { if (lastval && isset(ERREXIT)) {
if (sigtrapped[SIGEXIT]) if (sigtrapped[SIGEXIT])
dotrap(SIGEXIT); dotrap(SIGEXIT, 1);
if (mypid != getpid()) if (mypid != getpid())
_exit(lastval); _exit(lastval);
else else
@ -1181,9 +1186,10 @@ 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);
else { RUNTRAPS();
} 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;
@ -1218,12 +1224,14 @@ 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;

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); dotrap(SIGEXIT, 1);
exit(lastval); exit(lastval);
} }
if (justonce) if (justonce)
@ -1107,6 +1107,7 @@ fallback_zleread(char *lp, char *rp, int ha)
pptbuf = unmetafy(promptexpand(lp, 0, NULL, NULL), &pptlen); pptbuf = unmetafy(promptexpand(lp, 0, NULL, NULL), &pptlen);
write(2, (WRITE_ARG_2_T)pptbuf, pptlen); write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
free(pptbuf); free(pptbuf);
return (unsigned char *)shingetline(); return (unsigned char *)shingetline();
} }

View file

@ -141,7 +141,9 @@ 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); dotrap(SIGCHLD, 0);
/* 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); dotrap(sig, 0);
/* 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.
@ -878,7 +878,9 @@ 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();
@ -900,7 +902,9 @@ waitjob(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

View file

@ -497,7 +497,7 @@ handler(int sig)
case SIGHUP: case SIGHUP:
if (sigtrapped[SIGHUP]) if (sigtrapped[SIGHUP])
dotrap(SIGHUP); dotrap(SIGHUP, 0);
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); dotrap(SIGINT, 0);
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); dotrap(SIGWINCH, 0);
break; break;
#endif #endif
case SIGALRM: case SIGALRM:
if (sigtrapped[SIGALRM]) { if (sigtrapped[SIGALRM]) {
int tmout; int tmout;
dotrap(SIGALRM); dotrap(SIGALRM, 0);
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); dotrap(sig, 0);
break; break;
} /* end of switch(sig) */ } /* end of switch(sig) */
@ -907,7 +907,9 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
* function will test for this, but this way we keep status flags * * function will test for this, but this way we keep status flags *
* intact without working too hard. Special cases (e.g. calling * * intact without working too hard. Special cases (e.g. calling *
* a trap for SIGINT after the error flag was set) are handled * * a trap for SIGINT after the error flag was set) are handled *
* by the calling code. (PWS 1995/06/08). */ * by the calling code. (PWS 1995/06/08). *
* *
* This test is now replicated in dotrap(). */
if ((*sigtr & ZSIG_IGNORED) || !sigfn || errflag) if ((*sigtr & ZSIG_IGNORED) || !sigfn || errflag)
return; return;
@ -953,15 +955,67 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
breaks = loops; breaks = loops;
} }
/*
* If zle was running while the trap was executed, see if we
* need to restore the display.
*/
if (zleactive && resetneeded)
zrefresh();
if (*sigtr != ZSIG_IGNORED) if (*sigtr != ZSIG_IGNORED)
*sigtr &= ~ZSIG_IGNORED; *sigtr &= ~ZSIG_IGNORED;
} }
/* Standard call to execute a trap for a given signal */ /* != 0 if trap handlers can be called immediately */
/**/
mod_export int trapsallowed;
/* Queued traps and allocated length of queue. */
static int *trapqueue, trapqlen;
/* Number of used slots in trap queue. */
/**/
mod_export int trapqused;
/* Standard call to execute a trap for a given signal. The second
* argument should be zero if we may need to put the trap on the queue
* and 1 if it may be called immediately. It should never be set to
* anything less than zero, that's used internally. */
/**/ /**/
void void
dotrap(int sig) dotrap(int sig, int now)
{ {
/* Copied from dotrapargs(). */
if ((sigtrapped[sig] & ZSIG_IGNORED) || !sigfuncs[sig] || errflag)
return;
if (now || trapsallowed) {
if (now < 0)
RUNTRAPS();
dotrapargs(sig, sigtrapped+sig, sigfuncs[sig]); 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

@ -56,8 +56,8 @@
# define sigismember(s,n) ((*(s) & (1 << ((n) - 1))) != 0) # define sigismember(s,n) ((*(s) & (1 << ((n) - 1))) != 0)
#endif /* ifndef POSIX_SIGNALS */ #endif /* ifndef POSIX_SIGNALS */
#define child_block() signal_block(signal_mask(SIGCHLD)) #define child_block() signal_block(sigchld_mask)
#define child_unblock() signal_unblock(signal_mask(SIGCHLD)) #define child_unblock() signal_unblock(sigchld_mask)
#define child_suspend(S) signal_suspend(SIGCHLD, S) #define child_suspend(S) signal_suspend(SIGCHLD, S)
/* ignore a signal */ /* ignore a signal */
@ -92,3 +92,34 @@
} \ } \
} \ } \
} while (0) } while (0)
/* Make some signal functions faster. */
#ifdef POSIX_SIGNALS
#define signal_block(S) \
((dummy_sigset1 = (S)), \
sigprocmask(SIG_BLOCK, &dummy_sigset1, &dummy_sigset2), \
dummy_sigset2)
#else
# ifdef BSD_SIGNALS
#define signal_block(S) sigblock(S)
# else
extern sigset_t signal_block _((sigset_t));
# endif /* BSD_SIGNALS */
#endif /* POSIX_SIGNALS */
#ifdef POSIX_SIGNALS
#define signal_unblock(S) \
((dummy_sigset1 = (S)), \
sigprocmask(SIG_UNBLOCK, &dummy_sigset1, &dummy_sigset2), \
dummy_sigset2)
#else
extern sigset_t signal_unblock _((sigset_t));
#endif /* POSIX_SIGNALS */
#define RUNTRAPS() do { if (trapqused) doqueuedtraps(); } while (0)
#define ALLOWTRAPS do { RUNTRAPS(); trapsallowed++; do
#define DISALLOWTRAPS while (0); RUNTRAPS(); trapsallowed--; } while (0)
#define ALLOWTRAPS_RETURN(V) \
do { RUNTRAPS(); trapsallowed--; return (V); } while (0)

View file

@ -1417,13 +1417,39 @@ 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 (read(SHTTY, &c, 1) != 1) { while (ztrapread(SHTTY, &c, 1) != 1) {
if (errno != EINTR || errflag || retflag || breaks || contflag) if (errno != EINTR || errflag || retflag || breaks || contflag)
return -1; return -1;
} }
@ -1440,7 +1466,7 @@ noquery(int purge)
ioctl(SHTTY, FIONREAD, (char *)&val); ioctl(SHTTY, FIONREAD, (char *)&val);
if (purge) { if (purge) {
for (; val; val--) for (; val; val--)
read(SHTTY, &c, 1); ztrapread(SHTTY, &c, 1);
} }
#endif #endif

View file

@ -1627,8 +1627,6 @@ struct heap {
#endif #endif
; ;
# define LASTALLOC_RETURN return
# define NEWHEAPS(h) do { Heap _switch_oldheaps = h = new_heaps(); do # define NEWHEAPS(h) do { Heap _switch_oldheaps = h = new_heaps(); do
# define OLDHEAPS while (0); old_heaps(_switch_oldheaps); } while (0); # define OLDHEAPS while (0); old_heaps(_switch_oldheaps); } while (0);