mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-28 05:00: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:
parent
89d480f57d
commit
c292a3ae50
15 changed files with 387 additions and 202 deletions
12
ChangeLog
12
ChangeLog
|
|
@ -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>
|
||||
|
||||
* 13125: Completion/User/_mailboxes: evaluate the mailboxes
|
||||
|
|
|
|||
|
|
@ -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(-M) 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) ...)
|
||||
item(tt(zle))(
|
||||
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
|
||||
immediately after using it because the strings displayed will be erased
|
||||
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))(
|
||||
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
|
||||
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) ...)(
|
||||
Invoke the specified widget. This can only be done when ZLE is
|
||||
active; normally this will be within a user-defined widget.
|
||||
|
|
|
|||
|
|
@ -801,7 +801,7 @@ zfgetline(char *ln, int lnsize, int tmout)
|
|||
cmdbuf[0] = (char)IAC;
|
||||
cmdbuf[1] = (char)DONT;
|
||||
cmdbuf[2] = ch;
|
||||
write(zfsess->cfd, cmdbuf, 3);
|
||||
ztrapwrite(zfsess->cfd, cmdbuf, 3);
|
||||
continue;
|
||||
|
||||
case DO:
|
||||
|
|
@ -811,7 +811,7 @@ zfgetline(char *ln, int lnsize, int tmout)
|
|||
cmdbuf[0] = (char)IAC;
|
||||
cmdbuf[1] = (char)WONT;
|
||||
cmdbuf[2] = ch;
|
||||
write(zfsess->cfd, cmdbuf, 3);
|
||||
ztrapwrite(zfsess->cfd, cmdbuf, 3);
|
||||
continue;
|
||||
|
||||
case EOF:
|
||||
|
|
@ -996,7 +996,7 @@ zfsendcmd(char *cmd)
|
|||
return 6;
|
||||
}
|
||||
zfalarm(tmout);
|
||||
ret = write(zfsess->cfd, cmd, strlen(cmd));
|
||||
ret = ztrapwrite(zfsess->cfd, cmd, strlen(cmd));
|
||||
alarm(0);
|
||||
|
||||
if (ret <= 0) {
|
||||
|
|
@ -1470,7 +1470,7 @@ zfread(int fd, char *bf, off_t sz, int tmout)
|
|||
int ret;
|
||||
|
||||
if (!tmout)
|
||||
return read(fd, bf, sz);
|
||||
return ztrapread(fd, bf, sz);
|
||||
|
||||
if (setjmp(zfalrmbuf)) {
|
||||
alarm(0);
|
||||
|
|
@ -1479,7 +1479,7 @@ zfread(int fd, char *bf, off_t sz, int tmout)
|
|||
}
|
||||
zfalarm(tmout);
|
||||
|
||||
ret = read(fd, bf, sz);
|
||||
ret = ztrapread(fd, bf, sz);
|
||||
|
||||
/* we don't bother turning off the whole alarm mechanism here */
|
||||
alarm(0);
|
||||
|
|
@ -1495,7 +1495,7 @@ zfwrite(int fd, char *bf, off_t sz, int tmout)
|
|||
int ret;
|
||||
|
||||
if (!tmout)
|
||||
return write(fd, bf, sz);
|
||||
return ztrapwrite(fd, bf, sz);
|
||||
|
||||
if (setjmp(zfalrmbuf)) {
|
||||
alarm(0);
|
||||
|
|
@ -1504,7 +1504,7 @@ zfwrite(int fd, char *bf, off_t sz, int tmout)
|
|||
}
|
||||
zfalarm(tmout);
|
||||
|
||||
ret = write(fd, bf, sz);
|
||||
ret = ztrapwrite(fd, bf, sz);
|
||||
|
||||
/* we don't bother turning off the whole alarm mechanism here */
|
||||
alarm(0);
|
||||
|
|
@ -2846,7 +2846,7 @@ zfclose(int leaveparams)
|
|||
if (!zfnopen) {
|
||||
/* Write the final status in case this is a subshell */
|
||||
lseek(zfstatfd, zfsessno*sizeof(int), 0);
|
||||
write(zfstatfd, zfstatusp+zfsessno, sizeof(int));
|
||||
ztrapwrite(zfstatfd, zfstatusp+zfsessno, sizeof(int));
|
||||
|
||||
close(zfstatfd);
|
||||
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 */
|
||||
int oldstatus = zfstatusp[zfsessno];
|
||||
lseek(zfstatfd, 0, 0);
|
||||
read(zfstatfd, zfstatusp, sizeof(int)*zfsesscnt);
|
||||
ztrapread(zfstatfd, zfstatusp, sizeof(int)*zfsesscnt);
|
||||
if (zfsess->cfd != -1 && (zfstatusp[zfsessno] & ZFST_CLOS)) {
|
||||
/* got closed in subshell without us knowing */
|
||||
zcfinish = 2;
|
||||
|
|
@ -3212,7 +3212,7 @@ bin_zftp(char *name, char **args, char *ops, int func)
|
|||
* but only for the active session.
|
||||
*/
|
||||
lseek(zfstatfd, zfsessno*sizeof(int), 0);
|
||||
write(zfstatfd, zfstatusp+zfsessno, sizeof(int));
|
||||
ztrapwrite(zfstatfd, zfstatusp+zfsessno, sizeof(int));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ ptywritestr(Ptycmd cmd, char *s, int len)
|
|||
|
||||
for (; !errflag && !breaks && !retflag && !contflag && len;
|
||||
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
|
||||
errno == EWOULDBLOCK
|
||||
#else
|
||||
|
|
@ -578,7 +578,7 @@ ptywrite(Ptycmd cmd, char **args, int nonl)
|
|||
int n;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
while ((n = read(0, buf, BUFSIZ)) > 0)
|
||||
while ((n = ztrapread(0, buf, BUFSIZ)) > 0)
|
||||
if (ptywritestr(cmd, buf, n))
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -313,11 +313,17 @@ static int
|
|||
breakread(int fd, char *buf, int n)
|
||||
{
|
||||
fd_set f;
|
||||
int ret;
|
||||
|
||||
FD_ZERO(&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));
|
||||
} DISALLOWTRAPS;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
# define read breakread
|
||||
|
|
@ -388,7 +394,7 @@ getkey(int keytmout)
|
|||
# else
|
||||
ioctl(SHTTY, TCSETA, &ti.tio);
|
||||
# endif
|
||||
r = read(SHTTY, &cc, 1);
|
||||
r = ztrapread(SHTTY, &cc, 1);
|
||||
# ifdef HAVE_TERMIOS_H
|
||||
tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio);
|
||||
# else
|
||||
|
|
@ -398,7 +404,10 @@ getkey(int keytmout)
|
|||
# endif
|
||||
#endif
|
||||
}
|
||||
while ((r = read(SHTTY, &cc, 1)) != 1) {
|
||||
for (;;) {
|
||||
r = ztrapread(SHTTY, &cc, 1);
|
||||
if (r == 1)
|
||||
break;
|
||||
if (r == 0) {
|
||||
/* The test for IGNOREEOF was added to make zsh ignore ^Ds
|
||||
that were typed while commands are running. Unfortuantely
|
||||
|
|
@ -1083,7 +1092,7 @@ zleaftertrap(Hookdef dummy, void *dat)
|
|||
static struct builtin bintab[] = {
|
||||
BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", 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
|
||||
|
|
|
|||
|
|
@ -339,6 +339,7 @@ bin_zle(char *name, char **args, char *ops, int func)
|
|||
{ 'R', bin_zle_refresh, 0, -1 },
|
||||
{ 'M', bin_zle_mesg, 1, 1 },
|
||||
{ 'U', bin_zle_unget, 1, 1 },
|
||||
{ 'I', bin_zle_invalidate, 0, 0 },
|
||||
{ 0, bin_zle_call, 0, -1 },
|
||||
};
|
||||
struct opn const *op, *opp;
|
||||
|
|
@ -396,10 +397,8 @@ bin_zle_refresh(char *name, char **args, char *ops, char func)
|
|||
char *s = statusline;
|
||||
int sl = statusll, ocl = clearlist;
|
||||
|
||||
if (!zleactive) {
|
||||
zwarnnam(name, "can only be called from widget function", NULL, 0);
|
||||
if (!zleactive)
|
||||
return 1;
|
||||
}
|
||||
statusline = NULL;
|
||||
statusll = 0;
|
||||
if (*args) {
|
||||
|
|
@ -656,6 +655,17 @@ bin_zle_call(char *name, char **args, char *ops, char func)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zle_invalidate(char *name, char **args, char *ops, char func)
|
||||
{
|
||||
if (zleactive) {
|
||||
trashzle();
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*******************/
|
||||
/* initialiasation */
|
||||
/*******************/
|
||||
|
|
|
|||
|
|
@ -3218,7 +3218,7 @@ zexit(int val, int from_signal)
|
|||
checkjobs(); /* check if any jobs are running/stopped */
|
||||
if (stopmsg) {
|
||||
stopmsg = 2;
|
||||
LASTALLOC_RETURN;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (in_exit++ && from_signal)
|
||||
|
|
@ -3240,7 +3240,7 @@ zexit(int val, int from_signal)
|
|||
}
|
||||
}
|
||||
if (sigtrapped[SIGEXIT])
|
||||
dotrap(SIGEXIT);
|
||||
dotrap(SIGEXIT, 1);
|
||||
runhookdef(EXITHOOK, NULL);
|
||||
if (mypid != getpid())
|
||||
_exit(val);
|
||||
|
|
@ -3486,7 +3486,7 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
*bptr = readchar;
|
||||
val = 1;
|
||||
readchar = -1;
|
||||
} else if ((val = read(readfd, bptr, nchars)) <= 0)
|
||||
} else if ((val = ztrapread(readfd, bptr, nchars)) <= 0)
|
||||
break;
|
||||
|
||||
/* 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']) {
|
||||
/* dispose of result appropriately, etc. */
|
||||
if (isem)
|
||||
while (val > 0 && read(SHTTY, &d, 1) == 1 && d != '\n');
|
||||
while (val > 0 && ztrapread(SHTTY, &d, 1) == 1 && d != '\n');
|
||||
else
|
||||
settyinfo(&shttyinfo);
|
||||
if (haso) {
|
||||
|
|
@ -3733,6 +3733,7 @@ static int
|
|||
zread(int izle, int *readchar)
|
||||
{
|
||||
char cc, retry = 0;
|
||||
int ret;
|
||||
|
||||
if (izle) {
|
||||
int c = getkeyptr(0);
|
||||
|
|
@ -3756,7 +3757,8 @@ zread(int izle, int *readchar)
|
|||
}
|
||||
for (;;) {
|
||||
/* read a character from readfd */
|
||||
switch (read(readfd, &cc, 1)) {
|
||||
ret = ztrapread(readfd, &cc, 1);
|
||||
switch (ret) {
|
||||
case 1:
|
||||
/* return the character read */
|
||||
return STOUC(cc);
|
||||
|
|
|
|||
22
Src/exec.c
22
Src/exec.c
|
|
@ -738,6 +738,7 @@ static int
|
|||
execsimple(Estate state)
|
||||
{
|
||||
wordcode code = *state->pc++;
|
||||
int lv;
|
||||
|
||||
if (errflag)
|
||||
return (lastval = 1);
|
||||
|
|
@ -754,9 +755,13 @@ execsimple(Estate state)
|
|||
fputc('\n', xtrerr);
|
||||
fflush(xtrerr);
|
||||
}
|
||||
return (lastval = (errflag ? errflag : cmdoutval));
|
||||
lv = (errflag ? errflag : cmdoutval);
|
||||
} 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. *
|
||||
|
|
@ -887,19 +892,19 @@ sublist_done:
|
|||
noerrexit = oldnoerrexit;
|
||||
|
||||
if (sigtrapped[SIGDEBUG])
|
||||
dotrap(SIGDEBUG);
|
||||
dotrap(SIGDEBUG, 1);
|
||||
|
||||
/* Check whether we are suppressing traps/errexit *
|
||||
* (typically in init scripts) and if we haven't *
|
||||
* already performed them for this sublist. */
|
||||
if (!noerrexit && !donetrap) {
|
||||
if (sigtrapped[SIGZERR] && lastval) {
|
||||
dotrap(SIGZERR);
|
||||
dotrap(SIGZERR, 1);
|
||||
donetrap = 1;
|
||||
}
|
||||
if (lastval && isset(ERREXIT)) {
|
||||
if (sigtrapped[SIGEXIT])
|
||||
dotrap(SIGEXIT);
|
||||
dotrap(SIGEXIT, 1);
|
||||
if (mypid != getpid())
|
||||
_exit(lastval);
|
||||
else
|
||||
|
|
@ -1181,9 +1186,10 @@ execpline2(Estate state, wordcode pcode,
|
|||
else
|
||||
list_pipe_text[0] = '\0';
|
||||
}
|
||||
if (WC_PIPE_TYPE(pcode) == WC_PIPE_END)
|
||||
if (WC_PIPE_TYPE(pcode) == WC_PIPE_END) {
|
||||
execcmd(state, input, output, how, last1 ? 1 : 2);
|
||||
else {
|
||||
RUNTRAPS();
|
||||
} else {
|
||||
int old_list_pipe = list_pipe;
|
||||
Wordcode next = state->pc + (*state->pc);
|
||||
wordcode code;
|
||||
|
|
@ -1218,12 +1224,14 @@ execpline2(Estate state, wordcode pcode,
|
|||
entersubsh(how, 2, 0);
|
||||
close(synch[1]);
|
||||
execcmd(state, input, pipes[1], how, 0);
|
||||
RUNTRAPS();
|
||||
_exit(lastval);
|
||||
}
|
||||
} else {
|
||||
/* otherwise just do the pipeline normally. */
|
||||
subsh_close = pipes[0];
|
||||
execcmd(state, input, pipes[1], how, 0);
|
||||
RUNTRAPS();
|
||||
}
|
||||
zclose(pipes[1]);
|
||||
state->pc = next;
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ loop(int toplevel, int justonce)
|
|||
}
|
||||
if (isset(SINGLECOMMAND) && toplevel) {
|
||||
if (sigtrapped[SIGEXIT])
|
||||
dotrap(SIGEXIT);
|
||||
dotrap(SIGEXIT, 1);
|
||||
exit(lastval);
|
||||
}
|
||||
if (justonce)
|
||||
|
|
@ -1107,6 +1107,7 @@ fallback_zleread(char *lp, char *rp, int ha)
|
|||
pptbuf = unmetafy(promptexpand(lp, 0, NULL, NULL), &pptlen);
|
||||
write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
|
||||
free(pptbuf);
|
||||
|
||||
return (unsigned char *)shingetline();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,9 @@ shingetline(void)
|
|||
for (;;) {
|
||||
do {
|
||||
errno = 0;
|
||||
ALLOWTRAPS {
|
||||
c = fgetc(bshin);
|
||||
} DISALLOWTRAPS;
|
||||
} while (c < 0 && errno == EINTR);
|
||||
if (c < 0 || c == '\n') {
|
||||
if (c == '\n')
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ update_job(Job jn)
|
|||
zrefresh();
|
||||
}
|
||||
if (sigtrapped[SIGCHLD] && job != thisjob)
|
||||
dotrap(SIGCHLD);
|
||||
dotrap(SIGCHLD, 0);
|
||||
|
||||
/* When MONITOR is set, the foreground process runs in a different *
|
||||
* process group from the shell, so the shell will not receive *
|
||||
|
|
@ -389,7 +389,7 @@ update_job(Job jn)
|
|||
|
||||
if (sig == SIGINT || sig == SIGQUIT) {
|
||||
if (sigtrapped[sig]) {
|
||||
dotrap(sig);
|
||||
dotrap(sig, 0);
|
||||
/* We keep the errflag as set or not by dotrap.
|
||||
* This is to fulfil the promise to carry on
|
||||
* with the jobs if trap returns zero.
|
||||
|
|
@ -878,7 +878,9 @@ waitforpid(pid_t pid)
|
|||
else
|
||||
kill(pid, SIGCONT);
|
||||
|
||||
ALLOWTRAPS {
|
||||
child_suspend(SIGINT);
|
||||
} DISALLOWTRAPS;
|
||||
child_block();
|
||||
}
|
||||
child_unblock();
|
||||
|
|
@ -900,7 +902,9 @@ waitjob(int job, int sig)
|
|||
while (!errflag && jn->stat &&
|
||||
!(jn->stat & STAT_DONE) &&
|
||||
!(interact && (jn->stat & STAT_STOPPED))) {
|
||||
ALLOWTRAPS {
|
||||
child_suspend(sig);
|
||||
} DISALLOWTRAPS;
|
||||
/* Commenting this out makes ^C-ing a job started by a function
|
||||
stop the whole function again. But I guess it will stop
|
||||
something else from working properly, we have to find out
|
||||
|
|
|
|||
|
|
@ -497,7 +497,7 @@ handler(int sig)
|
|||
|
||||
case SIGHUP:
|
||||
if (sigtrapped[SIGHUP])
|
||||
dotrap(SIGHUP);
|
||||
dotrap(SIGHUP, 0);
|
||||
else {
|
||||
stopmsg = 1;
|
||||
zexit(SIGHUP, 1);
|
||||
|
|
@ -506,7 +506,7 @@ handler(int sig)
|
|||
|
||||
case SIGINT:
|
||||
if (sigtrapped[SIGINT])
|
||||
dotrap(SIGINT);
|
||||
dotrap(SIGINT, 0);
|
||||
else {
|
||||
if ((isset(PRIVILEGED) || isset(RESTRICTED)) &&
|
||||
isset(INTERACTIVE) && noerrexit < 0)
|
||||
|
|
@ -523,14 +523,14 @@ handler(int sig)
|
|||
case SIGWINCH:
|
||||
adjustwinsize(1); /* check window size and adjust */
|
||||
if (sigtrapped[SIGWINCH])
|
||||
dotrap(SIGWINCH);
|
||||
dotrap(SIGWINCH, 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SIGALRM:
|
||||
if (sigtrapped[SIGALRM]) {
|
||||
int tmout;
|
||||
dotrap(SIGALRM);
|
||||
dotrap(SIGALRM, 0);
|
||||
|
||||
if ((tmout = getiparam("TMOUT")))
|
||||
alarm(tmout); /* reset the alarm */
|
||||
|
|
@ -549,7 +549,7 @@ handler(int sig)
|
|||
break;
|
||||
|
||||
default:
|
||||
dotrap(sig);
|
||||
dotrap(sig, 0);
|
||||
break;
|
||||
} /* 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 *
|
||||
* intact without working too hard. Special cases (e.g. calling *
|
||||
* 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)
|
||||
return;
|
||||
|
||||
|
|
@ -953,15 +955,67 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
|
|||
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)
|
||||
*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
|
||||
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]);
|
||||
} 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@
|
|||
# define sigismember(s,n) ((*(s) & (1 << ((n) - 1))) != 0)
|
||||
#endif /* ifndef POSIX_SIGNALS */
|
||||
|
||||
#define child_block() signal_block(signal_mask(SIGCHLD))
|
||||
#define child_unblock() signal_unblock(signal_mask(SIGCHLD))
|
||||
#define child_block() signal_block(sigchld_mask)
|
||||
#define child_unblock() signal_unblock(sigchld_mask)
|
||||
#define child_suspend(S) signal_suspend(SIGCHLD, S)
|
||||
|
||||
/* ignore a signal */
|
||||
|
|
@ -92,3 +92,34 @@
|
|||
} \
|
||||
} \
|
||||
} 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)
|
||||
|
|
|
|||
30
Src/utils.c
30
Src/utils.c
|
|
@ -1417,13 +1417,39 @@ checkrmall(char *s)
|
|||
return (getquery("ny", 1) == 'y');
|
||||
}
|
||||
|
||||
/**/
|
||||
mod_export int
|
||||
ztrapread(int fd, char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ALLOWTRAPS {
|
||||
ret = read(fd, buf, len);
|
||||
} DISALLOWTRAPS;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
mod_export int
|
||||
ztrapwrite(int fd, char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ALLOWTRAPS {
|
||||
ret = write(fd, buf, len);
|
||||
} DISALLOWTRAPS;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
read1char(void)
|
||||
{
|
||||
char c;
|
||||
|
||||
while (read(SHTTY, &c, 1) != 1) {
|
||||
while (ztrapread(SHTTY, &c, 1) != 1) {
|
||||
if (errno != EINTR || errflag || retflag || breaks || contflag)
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1440,7 +1466,7 @@ noquery(int purge)
|
|||
ioctl(SHTTY, FIONREAD, (char *)&val);
|
||||
if (purge) {
|
||||
for (; val; val--)
|
||||
read(SHTTY, &c, 1);
|
||||
ztrapread(SHTTY, &c, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1627,8 +1627,6 @@ struct heap {
|
|||
#endif
|
||||
;
|
||||
|
||||
# define LASTALLOC_RETURN return
|
||||
|
||||
# define NEWHEAPS(h) do { Heap _switch_oldheaps = h = new_heaps(); do
|
||||
# define OLDHEAPS while (0); old_heaps(_switch_oldheaps); } while (0);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue