--- ncurses/SigAction.h
+++ ncurses/SigAction.h	2007-01-31 12:39:37.000000000 +0100
@@ -55,6 +55,53 @@
 typedef struct sigaction sigaction_t;
 #endif
 
+#if defined(__GNUC__) && defined(linux)
+#  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))
+#else
+#  if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+#    error The ncurses library has to be NPTL thread safe (requires the GCC)
+#  endif
+#endif
+
+#if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+# include <pthread.h>
+
+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
+
+static inline void _nc_kill(SCREEN *scan, int signal)
+{
+    if (!scan || !scan->_read_thread)
+	goto out;
+    if (!&pthread_kill || !&pthread_equal || !&pthread_self)
+	goto out;
+    if (pthread_equal(scan->_read_thread, pthread_self()))
+	goto out;
+    pthread_kill(scan->_read_thread, signal);
+out:
+    return;
+}
+#endif
+
 #else	/* !HAVE_SIGACTION */
 
 #if HAVE_SIGVEC
--- ncurses/curses.priv.h
+++ ncurses/curses.priv.h	2007-01-31 12:40:37.000000000 +0100
@@ -48,6 +48,10 @@
 
 #include <ncurses_dll.h>
 
+#if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+# include <pthread.h>
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -594,6 +598,11 @@ struct screen {
 #define _nc_windows SP->_nc_sp_windows
 
 	bool		_sig_winch;
+#if USE_SIGWINCH
+# if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+	pthread_t	_read_thread;
+# endif
+#endif
 	SCREEN		*_next_screen;
 
 	/* hashes for old and new lines */
@@ -1214,6 +1223,9 @@ extern NCURSES_EXPORT(void) _nc_scroll_o
 extern NCURSES_EXPORT(void) _nc_scroll_optimize (void);
 extern NCURSES_EXPORT(void) _nc_set_buffer (FILE *, bool);
 extern NCURSES_EXPORT(void) _nc_signal_handler (bool);
+#if USE_SIGWINCH
+extern NCURSES_EXPORT(void) _nc_thread(SCREEN *);
+#endif
 extern NCURSES_EXPORT(void) _nc_synchook (WINDOW *);
 extern NCURSES_EXPORT(void) _nc_trace_tries (TRIES *);
 
--- ncurses/base/lib_getch.c
+++ ncurses/base/lib_getch.c	2007-01-31 12:41:27.000000000 +0100
@@ -237,6 +237,10 @@ _nc_wgetch(WINDOW *win,
     if (win == 0 || SP == 0)
 	returnCode(ERR);
 
+#if USE_SIGWINCH
+    _nc_thread(SP);
+#endif
+
     if (cooked_key_in_fifo()) {
 	if (wgetch_should_refresh(win))
 	    wrefresh(win);
--- ncurses/base/lib_set_term.c
+++ ncurses/base/lib_set_term.c	2007-01-31 13:08:37.000000000 +0100
@@ -144,6 +144,12 @@ delscreen(SCREEN *sp)
 	free(sp->_setbuf);
     }
 
+#if USE_SIGWINCH
+# if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+    sp->_read_thread = (pthread_t)0;
+# endif
+#endif
+
     free(sp);
 
     /*
@@ -559,6 +565,15 @@ _nc_setupscreen(int slines,
 	returnCode(ERR);
     SP->_stdscr = stdscr;
 
+#if USE_SIGWINCH
+# if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+    if (&pthread_self)
+	SP->_read_thread = pthread_self();
+    else
+	SP->_read_thread = (pthread_t)0;
+# endif
+#endif
+
     returnCode(OK);
 }
 
--- ncurses/tinfo/lib_setup.c
+++ ncurses/tinfo/lib_setup.c	2007-01-31 11:46:17.000000000 +0100
@@ -42,6 +42,7 @@
 #include <curses.priv.h>
 #include <tic.h>		/* for MAX_NAME_SIZE */
 #include <term_entry.h>
+#include <SigAction.h>
 
 #if SVR4_TERMIO && !defined(_POSIX_SOURCE)
 #define _POSIX_SOURCE
@@ -119,6 +120,13 @@ _nc_handle_sigwinch(int enable)
     default:
 	/* record a SIGWINCH */
 	have_sigwinch = 1;
+# if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+	scan = _nc_screen_chain;
+	while (scan) {
+	    _nc_kill(scan, SIGWINCH);
+	    scan = scan->_next_screen;
+	}
+# endif
 	break;
     case 0:
 	/* temporarily disable the next block */
--- ncurses/tty/lib_tstp.c
+++ ncurses/tty/lib_tstp.c	2007-01-31 13:14:40.000000000 +0100
@@ -142,6 +142,11 @@ tstp(int dummy GCC_UNUSED)
 #ifdef SIGTTOU
     int sigttou_blocked;
 #endif
+#if USE_SIGWINCH
+# if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+    pthread_t reader = (pthread_t)0;
+# endif
+#endif
 
     T(("tstp() called"));
 
@@ -169,6 +174,10 @@ tstp(int dummy GCC_UNUSED)
     (void) sigaddset(&mask, SIGALRM);
 #if USE_SIGWINCH
     (void) sigaddset(&mask, SIGWINCH);
+# if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+    reader = SP->_read_thread;
+    SP->_read_thread = (pthread_t)0;
+# endif
 #endif
     (void) sigprocmask(SIG_BLOCK, &mask, &omask);
 
@@ -214,6 +223,12 @@ tstp(int dummy GCC_UNUSED)
     sigaction(SIGTSTP, &oact, NULL);
     flushinp();
 
+#if USE_SIGWINCH
+# if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+    SP->_read_thread = reader;
+# endif
+#endif
+
     /*
      * If the user modified the tty state while suspended, he wants
      * those changes to stick.  So save the new "default" terminal state.
@@ -386,6 +401,13 @@ _nc_signal_handler(bool enable)
 	    CatchIfDefault(SIGINT, cleanup);
 	    CatchIfDefault(SIGTERM, cleanup);
 #if USE_SIGWINCH
+# if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+    	    if (&pthread_self && &pthread_equal) {
+		pthread_t current = pthread_self();
+		if (!pthread_equal(SP->_read_thread, current))
+		    SP->_read_thread = current;
+	    }
+# endif
 	    CatchIfDefault(SIGWINCH, sigwinch);
 #endif
 	    initialized = TRUE;
@@ -393,3 +415,25 @@ _nc_signal_handler(bool enable)
     }
     returnVoid;
 }
+
+#if USE_SIGWINCH
+/*
+ * This is invoked once at the beginning of reading, to remember
+ * which thread should be interrupted if the SIGWINCH handler is
+ * called.
+ */
+
+NCURSES_EXPORT(void)
+_nc_thread(SCREEN *scan)
+{
+# if defined(linux) && (defined(_REENTRANT) || defined(_THREAD_SAFE))
+    if (&pthread_self && &pthread_equal) {
+	pthread_t current = pthread_self();
+	if (pthread_equal(SP->_read_thread, current))
+	    return;
+	/* Remember the terminal reading thread */
+	scan->_read_thread = current;
+    }
+# endif
+}
+#endif