mirror of
https://github.com/zsh-users/zsh
synced 2024-10-14 11:53:24 +00:00
31350: block SIGWINCH nearly all the time, except
when about to calculate prompts or do synchronous read, so syscalls are not interrupted by window size changes.
This commit is contained in:
parent
cbf6f144a9
commit
d19e18c68d
|
@ -567,7 +567,9 @@ raw_getbyte(long do_keytmout, char *cptr)
|
|||
gettyinfo(&ti);
|
||||
ti.tio.c_cc[VMIN] = 0;
|
||||
settyinfo(&ti);
|
||||
winch_unblock();
|
||||
ret = read(SHTTY, cptr, 1);
|
||||
winch_block();
|
||||
ti.tio.c_cc[VMIN] = 1;
|
||||
settyinfo(&ti);
|
||||
if (ret > 0)
|
||||
|
@ -597,7 +599,9 @@ raw_getbyte(long do_keytmout, char *cptr)
|
|||
else
|
||||
poll_timeout = -1;
|
||||
|
||||
winch_unblock();
|
||||
selret = poll(fds, errtry ? 1 : nfds, poll_timeout);
|
||||
winch_block();
|
||||
# else
|
||||
int fdmax = SHTTY;
|
||||
struct timeval *tvptr;
|
||||
|
@ -622,8 +626,10 @@ raw_getbyte(long do_keytmout, char *cptr)
|
|||
else
|
||||
tvptr = NULL;
|
||||
|
||||
winch_unblock();
|
||||
selret = select(fdmax+1, (SELECT_ARG_2_T) & foofd,
|
||||
NULL, NULL, tvptr);
|
||||
winch_block();
|
||||
# endif
|
||||
/*
|
||||
* Make sure a user interrupt gets passed on straight away.
|
||||
|
@ -788,7 +794,9 @@ raw_getbyte(long do_keytmout, char *cptr)
|
|||
# else
|
||||
ioctl(SHTTY, TCSETA, &ti.tio);
|
||||
# endif
|
||||
winch_unblock();
|
||||
ret = read(SHTTY, cptr, 1);
|
||||
winch_block();
|
||||
# ifdef HAVE_TERMIOS_H
|
||||
tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio);
|
||||
# else
|
||||
|
@ -799,7 +807,9 @@ raw_getbyte(long do_keytmout, char *cptr)
|
|||
#endif
|
||||
}
|
||||
|
||||
winch_unblock();
|
||||
ret = read(SHTTY, cptr, 1);
|
||||
winch_block();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1113,6 +1113,7 @@ init_signals(void)
|
|||
install_handler(SIGCHLD);
|
||||
#ifdef SIGWINCH
|
||||
install_handler(SIGWINCH);
|
||||
winch_block(); /* See utils.c:preprompt() */
|
||||
#endif
|
||||
if (interact) {
|
||||
install_handler(SIGALRM);
|
||||
|
|
|
@ -143,10 +143,12 @@ shingetline(void)
|
|||
|
||||
p = buf;
|
||||
for (;;) {
|
||||
winch_unblock();
|
||||
do {
|
||||
errno = 0;
|
||||
c = fgetc(bshin);
|
||||
} while (c < 0 && errno == EINTR);
|
||||
winch_block();
|
||||
if (c < 0 || c == '\n') {
|
||||
if (c == '\n')
|
||||
*p++ = '\n';
|
||||
|
|
|
@ -59,6 +59,14 @@
|
|||
#define child_block() signal_block(sigchld_mask)
|
||||
#define child_unblock() signal_unblock(sigchld_mask)
|
||||
|
||||
#ifdef SIGWINCH
|
||||
# define winch_block() signal_block(signal_mask(SIGWINCH))
|
||||
# define winch_unblock() signal_unblock(signal_mask(SIGWINCH))
|
||||
#else
|
||||
# define winch_block() 0
|
||||
# define winch_unblock() 0
|
||||
#endif
|
||||
|
||||
/* ignore a signal */
|
||||
#define signal_ignore(S) signal(S, SIG_IGN)
|
||||
|
||||
|
|
|
@ -1291,6 +1291,13 @@ preprompt(void)
|
|||
int period = getiparam("PERIOD");
|
||||
int mailcheck = getiparam("MAILCHECK");
|
||||
|
||||
/*
|
||||
* Handle any pending window size changes before we compute prompts,
|
||||
* then block them again to avoid interrupts during prompt display.
|
||||
*/
|
||||
winch_unblock();
|
||||
winch_block();
|
||||
|
||||
if (isset(PROMPTSP) && isset(PROMPTCR) && !use_exit_printed && shout) {
|
||||
/* The PROMPT_SP heuristic will move the prompt down to a new line
|
||||
* if there was any dangling output on the line (assuming the terminal
|
||||
|
|
Loading…
Reference in a new issue