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:
Bart Schaefer 2013-04-28 17:47:43 -07:00
parent cbf6f144a9
commit d19e18c68d
5 changed files with 28 additions and 0 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -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';

View file

@ -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)

View file

@ -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