--- ncurses/base/lib_getch.c +++ ncurses/base/lib_getch.c 2010-05-07 19:02:11.222924328 +0200 @@ -264,7 +264,14 @@ fifo_push(SCREEN *sp EVENTLIST_2nd(_nc_e ch = buf; #else unsigned char c2 = 0; +# ifdef USE_EINTR + if ((pthread_self) && (pthread_kill) && (pthread_equal)) + _nc_globals.read_thread = pthread_self(); +# endif n = read(sp->_ifd, &c2, 1); +#ifdef USE_EINTR + _nc_globals.read_thread = 0; +#endif ch = c2; #endif } @@ -279,7 +286,11 @@ fifo_push(SCREEN *sp EVENTLIST_2nd(_nc_e * We don't want this difference to show. This piece of code * tries to make it look like we always have restarting signals. */ - if (n <= 0 && errno == EINTR) + if (n <= 0 && errno == EINTR +# ifdef USE_EINTR + && (_nc_globals.have_sigwinch == 0) +# endif + ) goto again; #endif --- ncurses/base/lib_mouse.c +++ ncurses/base/lib_mouse.c 2010-05-07 19:01:35.658924370 +0200 @@ -838,6 +838,10 @@ _nc_mouse_inline(SCREEN *sp) * Wheel mice may return buttons 4 and 5 when the wheel is turned. * We encode those as button presses. */ +# ifdef USE_EINTR + if ((pthread_self) && (pthread_kill) && (pthread_equal)) + _nc_globals.read_thread = pthread_self(); +# endif for (grabbed = 0; grabbed < 3; grabbed += (size_t) res) { /* For VIO mouse we add extra bit 64 to disambiguate button-up. */ @@ -849,6 +853,9 @@ _nc_mouse_inline(SCREEN *sp) if (res == -1) break; } +#ifdef USE_EINTR + _nc_globals.read_thread = 0; +#endif kbuf[3] = '\0'; TR(TRACE_IEVENT, --- ncurses/curses.priv.h +++ ncurses/curses.priv.h 2010-05-07 18:51:15.686924218 +0200 @@ -448,8 +448,10 @@ extern NCURSES_EXPORT(int) _nc_mutex_unl #endif #ifdef USE_PTHREADS +# define USE_EINTR # if USE_WEAK_SYMBOLS weak_symbol(pthread_sigmask); +weak_symbol(pthread_kill); weak_symbol(pthread_self); weak_symbol(pthread_equal); weak_symbol(pthread_mutex_init); @@ -471,6 +473,38 @@ extern NCURSES_EXPORT(int) _nc_sigprocma #else /* !USE_PTHREADS */ +#if defined(linux) && USE_SIGWINCH +# define USE_EINTR +#endif + +#ifdef USE_EINTR +#if defined(__GNUC__) +# if defined __USE_ISOC99 +# define _cat_pragma(exp) _Pragma(#exp) +# define _weak_pragma(exp) _cat_pragma(weak name) +# else +# define _weak_pragma(exp) +# endif +# define _declare(name) __extension__ extern __typeof__(name) name +# define weak_symbol(name) _weak_pragma(name) _declare(name) __attribute__((weak)) +#endif + +#include +weak_symbol(pthread_sigmask); +weak_symbol(pthread_kill); +weak_symbol(pthread_self); +weak_symbol(pthread_equal); +static inline int _nc_sigprocmask(int how, const sigset_t *newmask, sigset_t *oldmask) +{ + if ((pthread_sigmask)) + return pthread_sigmask(how, newmask, oldmask); + else + return sigprocmask(how, newmask, oldmask); +} +# undef sigprocmask +# define sigprocmask _nc_sigprocmask +#endif /* USE_EINTR */ + #define _nc_init_pthreads() /* nothing */ #define _nc_mutex_init(obj) /* nothing */ @@ -798,6 +832,9 @@ typedef struct { int use_pthreads; #define _nc_use_pthreads _nc_globals.use_pthreads #endif +#ifdef USE_EINTR + pthread_t read_thread; /* The reading thread */ +#endif } NCURSES_GLOBALS; extern NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals; --- ncurses/tinfo/lib_data.c +++ ncurses/tinfo/lib_data.c 2010-05-07 18:46:59.706924518 +0200 @@ -193,6 +193,9 @@ NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_ 0, /* nested_tracef */ 0, /* use_pthreads */ #endif +#ifdef USE_EINTR + 0, /* read_thread */ +#endif }; #define STACK_FRAME_0 { { 0 }, 0 } --- ncurses/tinfo/tinfo_driver.c 2009-10-31 21:32:01.000000000 +0100 +++ ncurses/tinfo/tinfo_driver.c 2010-05-07 19:01:44.686924794 +0200 @@ -1248,7 +1248,14 @@ drv_read(TERMINAL_CONTROL_BLOCK * TCB, i assert(buf); SetSP(); +# ifdef USE_EINTR + if ((pthread_self) && (pthread_kill) && (pthread_equal)) + _nc_globals.read_thread = pthread_self(); +# endif n = read(sp->_ifd, &c2, 1); +#ifdef USE_EINTR + _nc_globals.read_thread = 0; +#endif *buf = (int) c2; return n; } --- ncurses/tty/lib_tstp.c +++ ncurses/tty/lib_tstp.c 2010-05-07 18:55:04.326924859 +0200 @@ -286,6 +286,13 @@ static void sigwinch(int sig GCC_UNUSED) { _nc_globals.have_sigwinch = 1; +# ifdef USE_EINTR + if (_nc_globals.read_thread) { + if (!pthread_equal(pthread_self(), _nc_globals.read_thread)) + pthread_kill(_nc_globals.read_thread, SIGWINCH); + _nc_globals.read_thread = 0; + } +# endif } #endif /* USE_SIGWINCH */