]> granicus.if.org Git - neomutt/commitdiff
move signal functions to libmutt
authorRichard Russon <rich@flatcap.org>
Thu, 23 Nov 2017 02:32:06 +0000 (02:32 +0000)
committerRichard Russon <rich@flatcap.org>
Mon, 27 Nov 2017 00:04:28 +0000 (00:04 +0000)
14 files changed:
Makefile.am
Makefile.autosetup
conn/tunnel.c
imap/util.c
mutt/Makefile.am
mutt/mutt.h
mutt/signal.c [new file with mode: 0644]
mutt/signal2.h [new file with mode: 0644]
mutt_signal.c [new file with mode: 0644]
options.h
po/POTFILES.in
protos.h
signal.c [deleted file]
system.c

index d4aba214ae0da9a38029d296404037db067f6c14..0a4376b8f12e3b2ecf15c84c5d15a5563796af24 100644 (file)
@@ -53,7 +53,7 @@ neomutt_SOURCES = mutt_account.c addrbook.c address.h alias.c alias.h attach.c \
        mx.c newsrc.c nntp.c options.h pager.c parameter.c parameter.h \
        parse.c pattern.c pattern.h pop.c pop_auth.c pop_lib.c postpone.c \
        query.c recvattach.c recvcmd.c rfc1524.c rfc2047.c rfc2231.c rfc3676.c \
-       rfc822.c safe_asprintf.c score.c send.c sendlib.c sidebar.c signal.c \
+       rfc822.c safe_asprintf.c score.c send.c sendlib.c sidebar.c mutt_signal.c \
        smtp.c sort.c state.c state.h status.c system.c thread.c thread.h url.c \
        version.c where.h mutt_tags.c
 
index 65d6f2a23786cfc520b6edcdebb9d6fed65b6a78..f54dbce13d126f96f76c00ce169299009e788bb6 100644 (file)
@@ -64,7 +64,7 @@ NEOMUTTOBJS=  mutt_account.o addrbook.o alias.o attach.o bcache.o body.o \
                newsrc.o nntp.o pager.o parameter.o parse.o pattern.o pop.o \
                pop_auth.o pop_lib.o postpone.o query.o recvattach.o recvcmd.o \
                rfc1524.o rfc2047.o rfc2231.o rfc3676.o rfc822.o \
-               safe_asprintf.o score.o send.o sendlib.o sidebar.o signal.o \
+               safe_asprintf.o score.o send.o sendlib.o sidebar.o mutt_signal.o \
                smtp.o sort.o state.o status.o system.o thread.o url.o \
                version.o
 
@@ -92,7 +92,7 @@ ALLOBJS+=     $(NEOMUTTOBJS)
 LIBMUTT=       libmutt.a
 LIBMUTTOBJS=   mutt/base64.o mutt/buffer.o mutt/date.o mutt/debug.o mutt/exit.o \
                mutt/file.o mutt/hash.o mutt/list.o mutt/mapping.o mutt/mbyte.o mutt/md5.o \
-               mutt/memory.o mutt/message.o mutt/sha1.o mutt/string.o
+               mutt/memory.o mutt/message.o mutt/sha1.o mutt/signal.o mutt/string.o
 CLEANFILES+=   $(LIBMUTT) $(LIBMUTTOBJS)
 MUTTLIBS+=     $(LIBMUTT)
 ALLOBJS+=      $(LIBMUTTOBJS)
index 26b481a311576c2c7c4372c07b7a4af92633797b..99a2f550a2bcb63d5c5324eaf8da8dd2dcbcfdef 100644 (file)
@@ -43,6 +43,7 @@
 #include <unistd.h>
 #include "mutt/memory.h"
 #include "mutt/message.h"
+#include "mutt/signal2.h"
 #include "mutt/string2.h"
 #include "mutt.h"
 #include "tunnel.h"
index b35f6bc8229de213567db0977fe5f94c2dab95fb..aed0f85c5b570573cd30e2ed2cfa6e98b408369c 100644 (file)
@@ -939,15 +939,6 @@ void imap_unmunge_mbox_name(struct ImapData *idata, char *s)
   FREE(&buf);
 }
 
-/**
- * alrm_handler - Dummy signal handler (ignore a signal)
- * @param sig Signal number
- */
-static void alrm_handler(int sig)
-{
-  /* empty */
-}
-
 /**
  * imap_keepalive - poll the current folder to keep the connection alive
  */
@@ -990,7 +981,7 @@ int imap_wait_keepalive(pid_t pid)
   sigprocmask(SIG_SETMASK, NULL, &oldmask);
 
   sigemptyset(&act.sa_mask);
-  act.sa_handler = alrm_handler;
+  act.sa_handler = empty_signal_handler;
 #ifdef SA_INTERRUPT
   act.sa_flags = SA_INTERRUPT;
 #else
index 2da60748fdcaa4d59ad465a9c465b5d3f9e0c320..b52068d370c123c54ee2872c9bd22fe8f63973e5 100644 (file)
@@ -3,11 +3,11 @@ include $(top_srcdir)/flymake.am
 
 AUTOMAKE_OPTIONS = 1.6 foreign
 
-EXTRA_DIST = mutt.h base64.h buffer.h date.h debug.h exit.h file.h hash.h list.h mapping.h mbyte.h md5.h memory.h message.h queue.h sha1.h string2.h
+EXTRA_DIST = mutt.h base64.h buffer.h date.h debug.h exit.h file.h hash.h list.h mapping.h mbyte.h md5.h memory.h message.h queue.h sha1.h signal2.h string2.h
 
 AM_CPPFLAGS = -I$(top_srcdir)
 
 noinst_LIBRARIES = libmutt.a
 
-libmutt_a_SOURCES = base64.c buffer.c date.c debug.c exit.c file.c hash.c list.c mapping.c mbyte.c md5.c memory.c message.c sha1.c string.c
+libmutt_a_SOURCES = base64.c buffer.c date.c debug.c exit.c file.c hash.c list.c mapping.c mbyte.c md5.c memory.c message.c sha1.c signal.c string.c
 
index ee1f64fbe29a86c87e353da933a37172b2bfd0af..e63cea9ca118ec5d93df260f031656006dcd2bc8 100644 (file)
@@ -42,6 +42,7 @@
  * -# @subpage memory
  * -# @subpage message
  * -# @subpage sha1
+ * -# @subpage signal
  * -# @subpage string
  */
 
@@ -62,6 +63,7 @@
 #include "memory.h"
 #include "message.h"
 #include "sha1.h"
+#include "signal2.h"
 #include "string2.h"
 
 #endif /* _MUTT_MUTT_H */
diff --git a/mutt/signal.c b/mutt/signal.c
new file mode 100644 (file)
index 0000000..29cddc2
--- /dev/null
@@ -0,0 +1,258 @@
+/**
+ * @file
+ * Signal handling
+ *
+ * @authors
+ * Copyright (C) 2017 Richard Russon <rich@flatcap.org>
+ *
+ * @copyright
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @page signal Signal handling
+ *
+ * Signal handling
+ *
+ * | Function                      | Description
+ * | :---------------------------- | :---------------------------------------------------------
+ * | default_exit_handler          | Notify the user and shutdown gracefully
+ * | empty_signal_handler          | Dummy signal handler
+ * | mutt_allow_interrupt          | Allow/disallow Ctrl-C (SIGINT)
+ * | mutt_block_signals            | Block signals during critical operations
+ * | mutt_block_signals_system     | Block signals before calling exec()
+ * | mutt_sig_init                 | Initialise the signal handling
+ * | mutt_unblock_signals          | Restore previously blocked signals
+ * | mutt_unblock_signals_system   | Restore previously blocked signals
+ */
+
+#include "config.h"
+#include <stddef.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "debug.h"
+#include "message.h"
+#include "signal2.h"
+
+static sigset_t Sigset;
+static sigset_t SigsetSys;
+static struct sigaction SysOldInt;
+static struct sigaction SysOldQuit;
+static bool SignalsBlocked;
+static bool SysSignalsBlocked;
+
+static sig_handler_t sig_handler = empty_signal_handler;
+static sig_handler_t exit_handler = default_exit_handler;
+
+/**
+ * empty_signal_handler - Dummy signal handler
+ * @param sig Signal number, e.g. SIGINT
+ *
+ * Useful for signals that we can't ignore,
+ * or don't want to do anything with.
+ */
+void empty_signal_handler(int sig)
+{
+  mutt_debug(2, "Received signal %d\n", sig);
+}
+
+/**
+ * default_exit_handler - Notify the user and shutdown gracefully
+ * @param sig Signal number, e.g. SIGINT
+ */
+void default_exit_handler(int sig)
+{
+#if HAVE_DECL_SYS_SIGLIST
+  printf(_("%s...  Exiting.\n"), sys_siglist[sig]);
+#elif (defined(__sun__) && defined(__svr4__))
+  printf(_("Caught %s...  Exiting.\n"), _sys_siglist[sig]);
+#elif (defined(__alpha) && defined(__osf__))
+  printf(_("Caught %s...  Exiting.\n"), __sys_siglist[sig]);
+#else
+  printf(_("Caught signal %d...  Exiting.\n"), sig);
+#endif
+  exit(0);
+}
+
+/**
+ * mutt_sig_init - Initialise the signal handling
+ * @param sig_fn  Function to handle signals
+ * @param exit_fn Function to call on uncaught signals
+ *
+ * Set up handlers to ignore or catch signals of interest.
+ * We use three handlers for the signals we want to catch, ignore, or exit.
+ */
+void mutt_sig_init(sig_handler_t sig_fn, sig_handler_t exit_fn)
+{
+  if (sig_fn)
+    sig_handler = sig_fn;
+
+  if (exit_fn)
+    exit_handler = exit_fn;
+
+  struct sigaction act;
+
+  sigemptyset(&act.sa_mask);
+  act.sa_flags = 0;
+  act.sa_handler = SIG_IGN;
+  sigaction(SIGPIPE, &act, NULL);
+
+  act.sa_handler = exit_handler;
+  sigaction(SIGTERM, &act, NULL);
+  sigaction(SIGHUP, &act, NULL);
+  sigaction(SIGQUIT, &act, NULL);
+
+  /* we want to avoid race conditions */
+  sigaddset(&act.sa_mask, SIGTSTP);
+
+  act.sa_handler = sig_handler;
+
+  /* we want SIGALRM to abort the current syscall, so we do this before
+   * setting the SA_RESTART flag below.  currently this is only used to
+   * timeout on a connect() call in a reasonable amount of time. */
+  sigaction(SIGALRM, &act, NULL);
+
+/* we also don't want to mess with interrupted system calls */
+#ifdef SA_RESTART
+  act.sa_flags = SA_RESTART;
+#endif
+
+  sigaction(SIGCONT, &act, NULL);
+  sigaction(SIGTSTP, &act, NULL);
+  sigaction(SIGINT, &act, NULL);
+#if defined(USE_SLANG_CURSES) || defined(HAVE_RESIZETERM)
+  sigaction(SIGWINCH, &act, NULL);
+#endif
+
+  /* POSIX doesn't allow us to ignore SIGCHLD,
+   * so we just install a dummy handler for it */
+  act.sa_handler = empty_signal_handler;
+  /* don't need to block any other signals here */
+  sigemptyset(&act.sa_mask);
+  /* we don't want to mess with stopped children */
+  act.sa_flags |= SA_NOCLDSTOP;
+  sigaction(SIGCHLD, &act, NULL);
+}
+
+/**
+ * mutt_block_signals - Block signals during critical operations
+ *
+ * It's important that certain signals don't interfere with critical operations.
+ * Call mutt_unblock_signals() to restore the signals' behaviour.
+ */
+void mutt_block_signals(void)
+{
+  if (SignalsBlocked)
+    return;
+
+  sigemptyset(&Sigset);
+  sigaddset(&Sigset, SIGTERM);
+  sigaddset(&Sigset, SIGHUP);
+  sigaddset(&Sigset, SIGTSTP);
+  sigaddset(&Sigset, SIGINT);
+#if defined(USE_SLANG_CURSES) || defined(HAVE_RESIZETERM)
+  sigaddset(&Sigset, SIGWINCH);
+#endif
+  sigprocmask(SIG_BLOCK, &Sigset, 0);
+  SignalsBlocked = true;
+}
+
+/**
+ * mutt_unblock_signals - Restore previously blocked signals
+ */
+void mutt_unblock_signals(void)
+{
+  if (!SignalsBlocked)
+    return;
+
+  sigprocmask(SIG_UNBLOCK, &Sigset, 0);
+  SignalsBlocked = false;
+}
+
+/**
+ * mutt_block_signals_system - Block signals before calling exec()
+ *
+ * It's important that certain signals don't interfere with the child process.
+ * Call mutt_unblock_signals_system() to restore the signals' behaviour.
+ */
+void mutt_block_signals_system(void)
+{
+  if (SysSignalsBlocked)
+    return;
+
+  struct sigaction sa;
+
+  /* POSIX: ignore SIGINT and SIGQUIT & block SIGCHLD before exec */
+  sa.sa_handler = SIG_IGN;
+  sa.sa_flags = 0;
+  sigemptyset(&sa.sa_mask);
+  sigaction(SIGINT, &sa, &SysOldInt);
+  sigaction(SIGQUIT, &sa, &SysOldQuit);
+
+  sigemptyset(&SigsetSys);
+  sigaddset(&SigsetSys, SIGCHLD);
+  sigprocmask(SIG_BLOCK, &SigsetSys, 0);
+  SysSignalsBlocked = true;
+}
+
+/**
+ * mutt_unblock_signals_system - Restore previously blocked signals
+ * @param catch If true, restore previous SIGINT, SIGQUIT behaviour
+ */
+void mutt_unblock_signals_system(int catch)
+{
+  if (!SysSignalsBlocked)
+    return;
+
+  sigprocmask(SIG_UNBLOCK, &SigsetSys, NULL);
+  if (catch)
+  {
+    sigaction(SIGQUIT, &SysOldQuit, NULL);
+    sigaction(SIGINT, &SysOldInt, NULL);
+  }
+  else
+  {
+    struct sigaction sa;
+
+    sa.sa_handler = SIG_DFL;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;
+    sigaction(SIGQUIT, &sa, NULL);
+    sigaction(SIGINT, &sa, NULL);
+  }
+
+  SysSignalsBlocked = false;
+}
+
+/**
+ * mutt_allow_interrupt - Allow/disallow Ctrl-C (SIGINT)
+ * @param disposition True to allow Ctrl-C to interrupt signals
+ *
+ * Allow the user to interrupt some long operations.
+ */
+void mutt_allow_interrupt(int disposition)
+{
+  struct sigaction sa;
+
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_handler = sig_handler;
+#ifdef SA_RESTART
+  if (disposition == 0)
+    sa.sa_flags |= SA_RESTART;
+#endif
+  sigaction(SIGINT, &sa, NULL);
+}
diff --git a/mutt/signal2.h b/mutt/signal2.h
new file mode 100644 (file)
index 0000000..c368d76
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * @file
+ * Signal handling
+ *
+ * @authors
+ * Copyright (C) 2017 Richard Russon <rich@flatcap.org>
+ *
+ * @copyright
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MUTT_SIGNAL_H
+#define _MUTT_SIGNAL_H
+
+typedef void (*sig_handler_t)(int sig);
+
+void mutt_block_signals(void);
+void mutt_unblock_signals(void);
+void mutt_block_signals_system(void);
+void mutt_unblock_signals_system(int catch);
+void default_exit_handler(int sig);
+void empty_signal_handler(int sig);
+void mutt_sig_init(sig_handler_t sig_fn, sig_handler_t exit_fn);
+void mutt_allow_interrupt(int disposition);
+
+#endif /* _MUTT_SIGNAL_H */
diff --git a/mutt_signal.c b/mutt_signal.c
new file mode 100644 (file)
index 0000000..a1a522f
--- /dev/null
@@ -0,0 +1,115 @@
+/**
+ * @file
+ * Signal handling
+ *
+ * @authors
+ * Copyright (C) 1996-2000,2012 Michael R. Elkins <me@mutt.org>
+ *
+ * @copyright
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include <errno.h>
+#include <signal.h>
+#include "mutt/mutt.h"
+#include "globals.h"
+#include "mutt_curses.h"
+#include "options.h"
+
+static int IsEndwin = 0;
+
+/**
+ * curses_signal_handler - Catch signals and relay the info to the main program
+ * @param sig Signal number, e.g. SIGINT
+ */
+static void curses_signal_handler(int sig)
+{
+  int save_errno = errno;
+
+  switch (sig)
+  {
+    case SIGTSTP: /* user requested a suspend */
+      if (!option(OPT_SUSPEND))
+        break;
+      IsEndwin = isendwin();
+      curs_set(1);
+      if (!IsEndwin)
+        endwin();
+      kill(0, SIGSTOP);
+    /* fallthrough */
+
+    case SIGCONT:
+      if (!IsEndwin)
+        refresh();
+      mutt_curs_set(-1);
+#if defined(USE_SLANG_CURSES) || defined(HAVE_RESIZETERM)
+      /* We don't receive SIGWINCH when suspended; however, no harm is done by
+       * just assuming we received one, and triggering the 'resize' anyway. */
+      SigWinch = 1;
+#endif
+      break;
+
+#if defined(USE_SLANG_CURSES) || defined(HAVE_RESIZETERM)
+    case SIGWINCH:
+      SigWinch = 1;
+      break;
+#endif
+
+    case SIGINT:
+      SigInt = 1;
+      break;
+  }
+  errno = save_errno;
+}
+
+/**
+ * curses_exit_handler - Notify the user and shutdown gracefully
+ * @param sig Signal number, e.g. SIGINT
+ */
+static void curses_exit_handler(int sig)
+{
+  curs_set(1);
+  endwin();                   /* just to be safe */
+  mutt_sig_exit_handler(sig); /* DOES NOT RETURN */
+}
+
+#ifdef USE_SLANG_CURSES
+/**
+ * mutt_intr_hook - Workaround handler for slang
+ */
+static int mutt_intr_hook(void)
+{
+  return -1;
+}
+#endif /* USE_SLANG_CURSES */
+
+/**
+ * mutt_signal_init - Initialise the signal handling
+ */
+void mutt_signal_init(void)
+{
+  mutt_sig_init(curses_signal_handler, curses_exit_handler);
+
+#ifdef USE_SLANG_CURSES
+  /* This bit of code is required because of the implementation of
+   * SLcurses_wgetch().  If a signal is received (like SIGWINCH) when we
+   * are in blocking mode, SLsys_getkey() will not return an error unless
+   * a handler function is defined and it returns -1.  This is needed so
+   * that if the user resizes the screen while at a prompt, it will just
+   * abort and go back to the main-menu.
+   */
+  SLang_getkey_intr_hook = mutt_intr_hook;
+#endif
+}
index b97a8e03b431003bf67a0dac3095d67c9460f726..74cb3c741b73e794e16832641c0624e8cfbd69fd 100644 (file)
--- a/options.h
+++ b/options.h
@@ -249,8 +249,6 @@ enum GlobalBool
   OPT_SEARCH_REVERSE,     /**< (pseudo) used by ci_search_command */
   OPT_MSG_ERR,            /**< (pseudo) used by mutt_error/mutt_message */
   OPT_SEARCH_INVALID,     /**< (pseudo) used to invalidate the search pat */
-  OPT_SIGNALS_BLOCKED,    /**< (pseudo) using by mutt_block_signals () */
-  OPT_SYS_SIGNALS_BLOCKED, /**< (pseudo) using by mutt_block_signals_system () */
   OPT_NEED_RESORT,        /**< (pseudo) used to force a re-sort */
   OPT_RESORT_INIT,        /**< (pseudo) used to force the next resort to be from scratch */
   OPT_VIEW_ATTACH,        /**< (pseudo) signals that we are viewing attachments */
index 49f5b464f46e1d5a7472ca2aedeb836c5b860611..3d2a7d12d77eebe3e2533d8b8f71699a6499b15b 100644 (file)
@@ -59,6 +59,11 @@ imap/utf7.c
 imap/util.c
 init.c
 keymap.c
+main.c
+mbox.c
+mbyte.c
+menu.c
+mh.c
 mutt/base64.c
 mutt/buffer.c
 mutt/date.c
@@ -73,17 +78,14 @@ mutt/md5.c
 mutt/memory.c
 mutt/message.c
 mutt/sha1.c
+mutt/signal.c
 mutt/string.c
-main.c
-mbox.c
-mbyte.c
-menu.c
-mh.c
 muttlib.c
 mutt_account.c
 mutt_idna.c
 mutt_lua.c
 mutt_notmuch.c
+mutt_signal.c
 mutt_socket.c
 mutt_tags.c
 mx.c
@@ -131,7 +133,6 @@ score.c
 send.c
 sendlib.c
 sidebar.c
-signal.c
 smtp.c
 sort.c
 state.c
index 367bb4bdb69d5567f0b6504df48d9434419c6296..39ddfdcc3c640a61384f6b1d3e11c91401cf1e44 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -148,8 +148,6 @@ void mutt_add_to_reference_headers(struct Envelope *env, struct Envelope *curenv
 void mutt_adv_mktemp(char *s, size_t l);
 void mutt_alias_menu(char *buf, size_t buflen, struct Alias *aliases);
 void mutt_allow_interrupt(int disposition);
-void mutt_block_signals(void);
-void mutt_block_signals_system(void);
 int mutt_body_handler(struct Body *b, struct State *s);
 int mutt_bounce_message(FILE *fp, struct Header *h, struct Address *to);
 void mutt_buffy(char *s, size_t slen);
@@ -230,8 +228,6 @@ void mutt_show_error(void);
 void mutt_signal_init(void);
 void mutt_stamp_attachment(struct Body *a);
 void mutt_tag_set_flag(int flag, int bf);
-void mutt_unblock_signals(void);
-void mutt_unblock_signals_system(int catch);
 void mutt_update_encoding(struct Body *a);
 void mutt_version(void);
 void mutt_view_attachments(struct Header *hdr);
diff --git a/signal.c b/signal.c
deleted file mode 100644 (file)
index 0e3b8d1..0000000
--- a/signal.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/**
- * @file
- * Signal handling
- *
- * @authors
- * Copyright (C) 1996-2000,2012 Michael R. Elkins <me@mutt.org>
- *
- * @copyright
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "mutt/mutt.h"
-#include "globals.h"
-#include "mutt_curses.h"
-#include "options.h"
-
-static sigset_t Sigset;
-static sigset_t SigsetSys;
-static struct sigaction SysOldInt;
-static struct sigaction SysOldQuit;
-static int IsEndwin = 0;
-
-/**
- * exit_handler - Attempt to catch "ordinary" signals and shut down gracefully
- */
-static void exit_handler(int sig)
-{
-  curs_set(1);
-  endwin(); /* just to be safe */
-
-/*
-   * if sys_siglist is not defined, HAVE_DECL_SYS_SIGLIST will be set to 0
-   * so we must check it with #if and not #ifdef
-   */
-#if HAVE_DECL_SYS_SIGLIST
-  printf(_("%s...  Exiting.\n"), sys_siglist[sig]);
-#elif (defined(__sun__) && defined(__svr4__))
-  printf(_("Caught %s...  Exiting.\n"), _sys_siglist[sig]);
-#elif (defined(__alpha) && defined(__osf__))
-  printf(_("Caught %s...  Exiting.\n"), __sys_siglist[sig]);
-#else
-  printf(_("Caught signal %d...  Exiting.\n"), sig);
-#endif
-  exit(0);
-}
-
-static void chld_handler(int sig)
-{
-  /* empty */
-}
-
-static void sighandler(int sig)
-{
-  int save_errno = errno;
-
-  switch (sig)
-  {
-    case SIGTSTP: /* user requested a suspend */
-      if (!option(OPT_SUSPEND))
-        break;
-      IsEndwin = isendwin();
-      curs_set(1);
-      if (!IsEndwin)
-        endwin();
-      kill(0, SIGSTOP);
-    /* fallthrough */
-
-    case SIGCONT:
-      if (!IsEndwin)
-        refresh();
-      mutt_curs_set(-1);
-#if defined(USE_SLANG_CURSES) || defined(HAVE_RESIZETERM)
-      /* We don't receive SIGWINCH when suspended; however, no harm is done by
-       * just assuming we received one, and triggering the 'resize' anyway. */
-      SigWinch = 1;
-#endif
-      break;
-
-#if defined(USE_SLANG_CURSES) || defined(HAVE_RESIZETERM)
-    case SIGWINCH:
-      SigWinch = 1;
-      break;
-#endif
-
-    case SIGINT:
-      SigInt = 1;
-      break;
-  }
-  errno = save_errno;
-}
-
-#ifdef USE_SLANG_CURSES
-static int mutt_intr_hook(void)
-{
-  return -1;
-}
-#endif /* USE_SLANG_CURSES */
-
-void mutt_signal_init(void)
-{
-  struct sigaction act;
-
-  sigemptyset(&act.sa_mask);
-  act.sa_flags = 0;
-  act.sa_handler = SIG_IGN;
-  sigaction(SIGPIPE, &act, NULL);
-
-  act.sa_handler = exit_handler;
-  sigaction(SIGTERM, &act, NULL);
-  sigaction(SIGHUP, &act, NULL);
-  sigaction(SIGQUIT, &act, NULL);
-
-  /* we want to avoid race conditions */
-  sigaddset(&act.sa_mask, SIGTSTP);
-
-  act.sa_handler = sighandler;
-
-  /* we want SIGALRM to abort the current syscall, so we do this before
-   * setting the SA_RESTART flag below.  currently this is only used to
-   * timeout on a connect() call in a reasonable amount of time.
-   */
-  sigaction(SIGALRM, &act, NULL);
-
-/* we also don't want to mess with interrupted system calls */
-#ifdef SA_RESTART
-  act.sa_flags = SA_RESTART;
-#endif
-
-  sigaction(SIGCONT, &act, NULL);
-  sigaction(SIGTSTP, &act, NULL);
-  sigaction(SIGINT, &act, NULL);
-#if defined(USE_SLANG_CURSES) || defined(HAVE_RESIZETERM)
-  sigaction(SIGWINCH, &act, NULL);
-#endif
-
-  /* POSIX doesn't allow us to ignore SIGCHLD,
-   * so we just install a dummy handler for it
-   */
-  act.sa_handler = chld_handler;
-  /* don't need to block any other signals here */
-  sigemptyset(&act.sa_mask);
-  /* we don't want to mess with stopped children */
-  act.sa_flags |= SA_NOCLDSTOP;
-  sigaction(SIGCHLD, &act, NULL);
-
-#ifdef USE_SLANG_CURSES
-  /* This bit of code is required because of the implementation of
-   * SLcurses_wgetch().  If a signal is received (like SIGWINCH) when we
-   * are in blocking mode, SLsys_getkey() will not return an error unless
-   * a handler function is defined and it returns -1.  This is needed so
-   * that if the user resizes the screen while at a prompt, it will just
-   * abort and go back to the main-menu.
-   */
-  SLang_getkey_intr_hook = mutt_intr_hook;
-#endif
-}
-
-/**
- * mutt_block_signals - Block signals during critical ops
- *
- * signals which are important to block while doing critical ops
- */
-void mutt_block_signals(void)
-{
-  if (!option(OPT_SIGNALS_BLOCKED))
-  {
-    sigemptyset(&Sigset);
-    sigaddset(&Sigset, SIGTERM);
-    sigaddset(&Sigset, SIGHUP);
-    sigaddset(&Sigset, SIGTSTP);
-    sigaddset(&Sigset, SIGINT);
-#if defined(USE_SLANG_CURSES) || defined(HAVE_RESIZETERM)
-    sigaddset(&Sigset, SIGWINCH);
-#endif
-    sigprocmask(SIG_BLOCK, &Sigset, 0);
-    set_option(OPT_SIGNALS_BLOCKED);
-  }
-}
-
-/**
- * mutt_unblock_signals - restore the previous signal mask
- */
-void mutt_unblock_signals(void)
-{
-  if (option(OPT_SIGNALS_BLOCKED))
-  {
-    sigprocmask(SIG_UNBLOCK, &Sigset, 0);
-    unset_option(OPT_SIGNALS_BLOCKED);
-  }
-}
-
-void mutt_block_signals_system(void)
-{
-  struct sigaction sa;
-
-  if (!option(OPT_SYS_SIGNALS_BLOCKED))
-  {
-    /* POSIX: ignore SIGINT and SIGQUIT & block SIGCHLD  before exec */
-    sa.sa_handler = SIG_IGN;
-    sa.sa_flags = 0;
-    sigemptyset(&sa.sa_mask);
-    sigaction(SIGINT, &sa, &SysOldInt);
-    sigaction(SIGQUIT, &sa, &SysOldQuit);
-
-    sigemptyset(&SigsetSys);
-    sigaddset(&SigsetSys, SIGCHLD);
-    sigprocmask(SIG_BLOCK, &SigsetSys, 0);
-    set_option(OPT_SYS_SIGNALS_BLOCKED);
-  }
-}
-
-void mutt_unblock_signals_system(int catch)
-{
-  if (option(OPT_SYS_SIGNALS_BLOCKED))
-  {
-    sigprocmask(SIG_UNBLOCK, &SigsetSys, NULL);
-    if (catch)
-    {
-      sigaction(SIGQUIT, &SysOldQuit, NULL);
-      sigaction(SIGINT, &SysOldInt, NULL);
-    }
-    else
-    {
-      struct sigaction sa;
-
-      sa.sa_handler = SIG_DFL;
-      sigemptyset(&sa.sa_mask);
-      sa.sa_flags = 0;
-      sigaction(SIGQUIT, &sa, NULL);
-      sigaction(SIGINT, &sa, NULL);
-    }
-
-    unset_option(OPT_SYS_SIGNALS_BLOCKED);
-  }
-}
-
-void mutt_allow_interrupt(int disposition)
-{
-  struct sigaction sa;
-
-  memset(&sa, 0, sizeof(sa));
-  sa.sa_handler = sighandler;
-#ifdef SA_RESTART
-  if (disposition == 0)
-    sa.sa_flags |= SA_RESTART;
-#endif
-  sigaction(SIGINT, &sa, NULL);
-}
index 7f153bc06d7defe939079b9361a65bbdc237b670..1d4ee79b08f78e6185667a34559c0d5f2e6cd259 100644 (file)
--- a/system.c
+++ b/system.c
@@ -25,6 +25,7 @@
 #include <signal.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include "mutt/mutt.h"
 #include "mutt.h"
 #include "protos.h"
 #ifdef USE_IMAP