Index: Makefile.am
===================================================================
--- Makefile.am	(revision ce35060c0b8f538bfc2659317d8bf70e8a2adbf7)
+++ Makefile.am	(revision fafb8421a08255122a16854bec2a116e7f6863a0)
@@ -45,5 +45,5 @@
      aim.c buddy.c buddylist.c style.c errqueue.c \
      zbuddylist.c popexec.c select.c wcwidth.c \
-     glib_compat.c mainpanel.c msgwin.c sepbar.c editcontext.c
+     glib_compat.c mainpanel.c msgwin.c sepbar.c editcontext.c signal.c
 
 NORMAL_SRCS = filterproc.c window.c windowcb.c
Index: functions.c
===================================================================
--- functions.c	(revision 1a30f05a2ef68480fce47bbf3bf8f514977a95a0)
+++ functions.c	(revision fafb8421a08255122a16854bec2a116e7f6863a0)
@@ -2995,4 +2995,6 @@
       i--;
     }
+#if 0
+    /* FIXME!!! */
     owl_function_mask_sigint(NULL);
     if(owl_global_is_interrupted(&g)) {
@@ -3004,4 +3006,5 @@
     }
     owl_function_unmask_sigint(NULL);
+#endif
   }
   owl_mainwin_redisplay(owl_global_get_mainwin(&g));
@@ -3086,4 +3089,6 @@
           ret=ZLocateUser(zstr(user), &numlocs, ZAUTH);
 
+#if 0
+	  /* FIXME!! */
           owl_function_mask_sigint(NULL);
           if(owl_global_is_interrupted(&g)) {
@@ -3096,4 +3101,5 @@
 
           owl_function_unmask_sigint(NULL);
+#endif
 
           if (ret!=ZERR_NONE) {
Index: global.c
===================================================================
--- global.c	(revision b2790134e3eb3882fae1d05bdeb4e52d738a1fd6)
+++ global.c	(revision fafb8421a08255122a16854bec2a116e7f6863a0)
@@ -16,4 +16,5 @@
 
   g_type_init();
+  g_thread_init(NULL);
 
   owl_select_init();
@@ -101,5 +102,4 @@
 
   owl_errqueue_init(&(g->errqueue));
-  g->got_err_signal=0;
 
   owl_zbuddylist_create(&(g->zbuddies));
@@ -112,5 +112,4 @@
   owl_list_create(&(g->psa_list));
   g->timerlist = NULL;
-  g->interrupted = FALSE;
   g->kill_buffer = NULL;
 }
@@ -826,28 +825,4 @@
 }
 
-void owl_global_set_errsignal(owl_global *g, int signum, siginfo_t *siginfo)
-{
-  g->got_err_signal = signum;
-  if (siginfo) {
-    g->err_signal_info = *siginfo;
-  } else {
-    siginfo_t si;
-    memset(&si, 0, sizeof(si));
-    g->err_signal_info = si;
-  }
-}
-
-int owl_global_get_errsignal_and_clear(owl_global *g, siginfo_t *siginfo)
-{
-  int signum;
-  if (siginfo && g->got_err_signal) {
-    *siginfo = g->err_signal_info;
-  } 
-  signum = g->got_err_signal;
-  g->got_err_signal = 0;
-  return signum;
-}
-
-
 owl_zbuddylist *owl_global_get_zephyr_buddylist(owl_global *g)
 {
@@ -888,16 +863,4 @@
 {
   return &(g->timerlist);
-}
-
-int owl_global_is_interrupted(const owl_global *g) {
-  return g->interrupted;
-}
-
-void owl_global_set_interrupted(owl_global *g) {
-  g->interrupted = 1;
-}
-
-void owl_global_unset_interrupted(owl_global *g) {
-  g->interrupted = 0;
 }
 
Index: owl.c
===================================================================
--- owl.c	(revision 5eb392f504fc61984f3fcb2426aab332a2711ab7)
+++ owl.c	(revision fafb8421a08255122a16854bec2a116e7f6863a0)
@@ -354,53 +354,36 @@
 }
 
-void sig_handler(int sig, siginfo_t *si, void *data)
-{
-  if (sig==SIGWINCH) {
+static void sig_handler(int sig, void *data) {
+  owl_function_debugmsg("Got signal %d", sig);
+  /* TODO: These don't need to be re-entrant anymore! */
+  if (sig == SIGWINCH) {
     /* we can't inturrupt a malloc here, so it just sets a flag
      * schedulding a resize for later
      */
     owl_function_resize();
-  } else if (sig==SIGPIPE || sig==SIGCHLD) {
-    /* Set a flag and some info that we got the sigpipe
-     * so we can record that we got it and why... */
-    owl_global_set_errsignal(&g, sig, si);
-  } else if (sig==SIGTERM || sig==SIGHUP) {
+  } else if (sig == SIGPIPE || sig == SIGCHLD) {
+    owl_function_error("Got unexpected signal: %d %s",
+		       sig, (sig == SIGPIPE) ? "SIGPIPE" : "SIGCHLD");
+  } else if (sig == SIGTERM || sig == SIGHUP) {
     owl_function_quit();
-  }
-}
-
-void sigint_handler(int sig, siginfo_t *si, void *data)
-{
-  owl_global_set_interrupted(&g);
-}
-
-static int owl_errsignal_pre_select_action(owl_ps_action *a, void *data)
-{
-  siginfo_t si;
-  int signum;
-  if ((signum = owl_global_get_errsignal_and_clear(&g, &si)) > 0) {
-    owl_function_error("Got unexpected signal: %d %s  (code: %d band: %ld  errno: %d)",
-        signum, signum==SIGPIPE?"SIGPIPE":"SIG????",
-        si.si_code, si.si_band, si.si_errno);
-  }
-  return 0;
+  } else if (sig == SIGINT) {
+    owl_input in;
+    in.ch = in.uch = owl_global_get_startup_tio(&g)->c_cc[VINTR];
+    owl_process_input_char(in);
+  }
 }
 
 void owl_register_signal_handlers(void) {
-  struct sigaction sigact;
-
-  /* signal handler */
-  /*sigact.sa_handler=sig_handler;*/
-  sigact.sa_sigaction=sig_handler;
-  sigemptyset(&sigact.sa_mask);
-  sigact.sa_flags=SA_SIGINFO;
-  sigaction(SIGWINCH, &sigact, NULL);
-  sigaction(SIGALRM, &sigact, NULL);
-  sigaction(SIGPIPE, &sigact, NULL);
-  sigaction(SIGTERM, &sigact, NULL);
-  sigaction(SIGHUP, &sigact, NULL);
-
-  sigact.sa_sigaction=sigint_handler;
-  sigaction(SIGINT, &sigact, NULL);
+  sigset_t sigset;
+
+  sigemptyset(&sigset);
+  sigaddset(&sigset, SIGWINCH);
+  sigaddset(&sigset, SIGALRM);
+  sigaddset(&sigset, SIGPIPE);
+  sigaddset(&sigset, SIGTERM);
+  sigaddset(&sigset, SIGHUP);
+  sigaddset(&sigset, SIGINT);
+
+  owl_signal_init(&sigset, sig_handler, NULL);
 }
 
@@ -479,5 +462,4 @@
   g.load_initial_subs = opts.load_initial_subs;
 
-  owl_register_signal_handlers();
   owl_start_curses();
 
@@ -491,4 +473,6 @@
   g_strfreev(argv_copy);
   owl_global_set_haveaim(&g);
+
+  owl_register_signal_handlers();
 
   /* register STDIN dispatch; throw away return, we won't need it */
@@ -591,6 +575,4 @@
   g_source_unref(source);
 
-  owl_select_add_pre_select_action(owl_errsignal_pre_select_action, NULL, NULL);
-
   owl_function_debugmsg("startup: entering main loop");
   owl_select_run_loop();
Index: owl.h
===================================================================
--- owl.h	(revision b2790134e3eb3882fae1d05bdeb4e52d738a1fd6)
+++ owl.h	(revision fafb8421a08255122a16854bec2a116e7f6863a0)
@@ -629,6 +629,4 @@
   int haveaim;
   int ignoreaimlogin;
-  volatile sig_atomic_t got_err_signal; /* 1 if we got an unexpected signal */
-  volatile siginfo_t err_signal_info;
   owl_zbuddylist zbuddies;
   GList *zaldlist;
@@ -640,5 +638,4 @@
   owl_timer *aim_nop_timer;
   int load_initial_subs;
-  volatile sig_atomic_t interrupted;
   FILE *debug_file;
   char *kill_buffer;
Index: select.c
===================================================================
--- select.c	(revision b2790134e3eb3882fae1d05bdeb4e52d738a1fd6)
+++ select.c	(revision fafb8421a08255122a16854bec2a116e7f6863a0)
@@ -335,29 +335,4 @@
     owl_function_makemsg("Unable to handle keypress");
   }
-}
-
-void owl_select_mask_signals(sigset_t *oldmask) {
-  sigset_t set;
-
-  sigemptyset(&set);
-  sigaddset(&set, SIGWINCH);
-  sigaddset(&set, SIGALRM);
-  sigaddset(&set, SIGPIPE);
-  sigaddset(&set, SIGTERM);
-  sigaddset(&set, SIGHUP);
-  sigaddset(&set, SIGINT);
-  sigprocmask(SIG_BLOCK, &set, oldmask);
-}
-
-void owl_select_handle_intr(sigset_t *restore)
-{
-  owl_input in;
-
-  owl_global_unset_interrupted(&g);
-
-  sigprocmask(SIG_SETMASK, restore, NULL);
-
-  in.ch = in.uch = owl_global_get_startup_tio(&g)->c_cc[VINTR];
-  owl_process_input_char(in);
 }
 
Index: signal.c
===================================================================
--- signal.c	(revision fafb8421a08255122a16854bec2a116e7f6863a0)
+++ signal.c	(revision fafb8421a08255122a16854bec2a116e7f6863a0)
@@ -0,0 +1,59 @@
+#include <glib.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static GThread *signal_thread;
+static sigset_t signal_set;
+
+static void (*signal_cb)(int, void*);
+static void *signal_cbdata;
+
+static gpointer signal_thread_func(gpointer data);
+static gboolean signal_thunk(gpointer data);
+
+void owl_signal_init(const sigset_t *set, void (*callback)(int, void*), void *data) {
+  GError *error = NULL;
+
+  signal_set = *set;
+  signal_cb = callback;
+  signal_cbdata = data;
+  /* Block these signals in all threads, so we can get them. */
+  pthread_sigmask(SIG_BLOCK, set, NULL);
+  /* Spawn a dedicated thread to sigwait. */
+  signal_thread = g_thread_create(signal_thread_func, g_main_context_default(),
+				  FALSE, &error);
+  if (signal_thread == NULL) {
+    fprintf(stderr, "Failed to create signal thread: %s\n", error->message);
+    exit(1);
+  }
+}
+
+static gpointer signal_thread_func(gpointer data) {
+  GMainContext *context = data;
+
+  while (1) {
+    GSource *source;
+    int signal;
+    int ret;
+
+    ret = sigwait(&signal_set, &signal);
+    /* TODO: Print an error? man page claims it never errors. */
+    if (ret != 0)
+      continue;
+
+    /* Send a message to the other main. */
+    source = g_idle_source_new();
+    g_source_set_priority(source, G_PRIORITY_DEFAULT);
+    g_source_set_callback(source, signal_thunk, GINT_TO_POINTER(signal), NULL);
+    g_source_attach(source, context);
+    g_source_unref(source);
+  }
+  return NULL;
+}
+
+static gboolean signal_thunk(gpointer data) {
+  signal_cb(GPOINTER_TO_INT(data), signal_cbdata);
+  return FALSE;
+}
