forked from pool/ncurses
206 lines
5.2 KiB
Plaintext
206 lines
5.2 KiB
Plaintext
--- ncurses/SigAction.h
|
|
+++ ncurses/SigAction.h 2006-05-18 14:31:29.000000000 +0200
|
|
@@ -55,6 +55,36 @@
|
|
typedef struct sigaction sigaction_t;
|
|
#endif
|
|
|
|
+#if defined _REENTRANT || defined _THREAD_SAFE
|
|
+# include <pthread.h>
|
|
+extern int pthread_sigmask(int, const sigset_t*, sigset_t*) __attribute__((weak));
|
|
+extern int pthread_kill(pthread_t, int) __attribute__((weak));
|
|
+extern pthread_t pthread_self(void) __attribute__((weak));
|
|
+extern int pthread_equal(pthread_t, pthread_t) __attribute__((weak));
|
|
+
|
|
+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);
|
|
+}
|
|
+#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 2006-05-18 14:31:29.000000000 +0200
|
|
@@ -48,6 +48,10 @@
|
|
|
|
#include <ncurses_dll.h>
|
|
|
|
+#if defined _REENTRANT || defined _THREAD_SAFE
|
|
+# include <pthread.h>
|
|
+#endif
|
|
+
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
@@ -538,6 +542,12 @@
|
|
#define _nc_windows SP->_nc_sp_windows
|
|
|
|
bool _sig_winch;
|
|
+#if USE_SIGWINCH
|
|
+ bool _unblock_sigwinch;
|
|
+#if defined _REENTRANT || defined _THREAD_SAFE
|
|
+ pthread_t _read_thread;
|
|
+#endif
|
|
+#endif
|
|
SCREEN *_next_screen;
|
|
|
|
/* hashes for old and new lines */
|
|
@@ -1143,6 +1153,9 @@
|
|
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_unblock (SCREEN *, int);
|
|
+#endif
|
|
extern NCURSES_EXPORT(void) _nc_synchook (WINDOW *);
|
|
extern NCURSES_EXPORT(void) _nc_trace_tries (struct tries *);
|
|
|
|
--- ncurses/base/lib_getch.c
|
|
+++ ncurses/base/lib_getch.c 2006-05-18 14:31:29.000000000 +0200
|
|
@@ -237,6 +237,10 @@
|
|
if (win == 0 || SP == 0)
|
|
returnCode(ERR);
|
|
|
|
+#if USE_SIGWINCH
|
|
+ _nc_unblock(SP, SIGWINCH);
|
|
+#endif
|
|
+
|
|
if (cooked_key_in_fifo()) {
|
|
if (wgetch_should_refresh(win))
|
|
wrefresh(win);
|
|
--- ncurses/tinfo/lib_setup.c
|
|
+++ ncurses/tinfo/lib_setup.c 2006-05-18 15:24:54.000000000 +0200
|
|
@@ -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 @@
|
|
default:
|
|
/* record a SIGWINCH */
|
|
have_sigwinch = 1;
|
|
+# if 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 2006-05-18 15:53:04.000000000 +0200
|
|
@@ -142,6 +142,9 @@
|
|
#ifdef SIGTTOU
|
|
int sigttou_blocked;
|
|
#endif
|
|
+#if defined _REENTRANT || defined _THREAD_SAFE
|
|
+ pthread_t reader = (pthread_t)0;
|
|
+#endif
|
|
|
|
T(("tstp() called"));
|
|
|
|
@@ -169,6 +172,10 @@
|
|
(void) sigaddset(&mask, SIGALRM);
|
|
#if USE_SIGWINCH
|
|
(void) sigaddset(&mask, SIGWINCH);
|
|
+#if 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 +221,10 @@
|
|
sigaction(SIGTSTP, &oact, NULL);
|
|
flushinp();
|
|
|
|
+#if defined _REENTRANT || defined _THREAD_SAFE
|
|
+ SP->_read_thread = reader;
|
|
+#endif
|
|
+
|
|
/*
|
|
* If the user modified the tty state while suspended, he wants
|
|
* those changes to stick. So save the new "default" terminal state.
|
|
@@ -332,6 +343,17 @@
|
|
result = FALSE;
|
|
}
|
|
#endif
|
|
+
|
|
+#if USE_SIGWINCH
|
|
+ if (result && sig == SIGWINCH) {
|
|
+ sigset_t sigset;
|
|
+
|
|
+ sigemptyset(&sigset);
|
|
+ sigaddset(&sigset, SIGWINCH);
|
|
+ sigprocmask(SIG_BLOCK, &sigset, NULL);
|
|
+ }
|
|
+#endif
|
|
+
|
|
T(("CatchIfDefault - will %scatch %s",
|
|
result ? "" : "not ", signal_name(sig)));
|
|
return result;
|
|
@@ -386,6 +408,10 @@
|
|
CatchIfDefault(SIGINT, cleanup);
|
|
CatchIfDefault(SIGTERM, cleanup);
|
|
#if USE_SIGWINCH
|
|
+ SP->_unblock_sigwinch = false;
|
|
+# if defined _REENTRANT || defined _THREAD_SAFE
|
|
+ SP->_read_thread = (pthread_t)0;
|
|
+# endif
|
|
CatchIfDefault(SIGWINCH, sigwinch);
|
|
#endif
|
|
initialized = TRUE;
|
|
@@ -393,3 +419,29 @@
|
|
}
|
|
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_unblock(SCREEN *scan, int signal)
|
|
+{
|
|
+ sigset_t sigset;
|
|
+
|
|
+ if (scan->_unblock_sigwinch)
|
|
+ return;
|
|
+ sigemptyset(&sigset);
|
|
+ sigaddset(&sigset, signal);
|
|
+ sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
|
+# if defined _REENTRANT || defined _THREAD_SAFE
|
|
+ /* Remember the terminal reading thread */
|
|
+ if (&pthread_self)
|
|
+ scan->_read_thread = pthread_self();
|
|
+# endif
|
|
+ scan->_unblock_sigwinch = true;
|
|
+}
|
|
+#endif
|