From: Richard Russon Date: Thu, 23 Nov 2017 02:32:06 +0000 (+0000) Subject: move signal functions to libmutt X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bf57508770d778bce4a54e627dd86f562537c83f;p=neomutt move signal functions to libmutt --- diff --git a/Makefile.am b/Makefile.am index d4aba214a..0a4376b8f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/Makefile.autosetup b/Makefile.autosetup index 65d6f2a23..f54dbce13 100644 --- a/Makefile.autosetup +++ b/Makefile.autosetup @@ -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) diff --git a/conn/tunnel.c b/conn/tunnel.c index 26b481a31..99a2f550a 100644 --- a/conn/tunnel.c +++ b/conn/tunnel.c @@ -43,6 +43,7 @@ #include #include "mutt/memory.h" #include "mutt/message.h" +#include "mutt/signal2.h" #include "mutt/string2.h" #include "mutt.h" #include "tunnel.h" diff --git a/imap/util.c b/imap/util.c index b35f6bc82..aed0f85c5 100644 --- a/imap/util.c +++ b/imap/util.c @@ -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 diff --git a/mutt/Makefile.am b/mutt/Makefile.am index 2da60748f..b52068d37 100644 --- a/mutt/Makefile.am +++ b/mutt/Makefile.am @@ -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 diff --git a/mutt/mutt.h b/mutt/mutt.h index ee1f64fbe..e63cea9ca 100644 --- a/mutt/mutt.h +++ b/mutt/mutt.h @@ -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 index 000000000..29cddc230 --- /dev/null +++ b/mutt/signal.c @@ -0,0 +1,258 @@ +/** + * @file + * Signal handling + * + * @authors + * Copyright (C) 2017 Richard Russon + * + * @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 . + */ + +/** + * @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 +#include +#include +#include +#include +#include +#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 index 000000000..c368d76ad --- /dev/null +++ b/mutt/signal2.h @@ -0,0 +1,37 @@ +/** + * @file + * Signal handling + * + * @authors + * Copyright (C) 2017 Richard Russon + * + * @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 . + */ + +#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 index 000000000..a1a522f20 --- /dev/null +++ b/mutt_signal.c @@ -0,0 +1,115 @@ +/** + * @file + * Signal handling + * + * @authors + * Copyright (C) 1996-2000,2012 Michael R. Elkins + * + * @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 . + */ + +#include "config.h" +#include +#include +#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 +} diff --git a/options.h b/options.h index b97a8e03b..74cb3c741 100644 --- 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 */ diff --git a/po/POTFILES.in b/po/POTFILES.in index 49f5b464f..3d2a7d12d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -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 diff --git a/protos.h b/protos.h index 367bb4bdb..39ddfdcc3 100644 --- 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 index 0e3b8d1c2..000000000 --- a/signal.c +++ /dev/null @@ -1,265 +0,0 @@ -/** - * @file - * Signal handling - * - * @authors - * Copyright (C) 1996-2000,2012 Michael R. Elkins - * - * @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 . - */ - -#include "config.h" -#include -#include -#include -#include -#include -#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); -} diff --git a/system.c b/system.c index 7f153bc06..1d4ee79b0 100644 --- a/system.c +++ b/system.c @@ -25,6 +25,7 @@ #include #include #include +#include "mutt/mutt.h" #include "mutt.h" #include "protos.h" #ifdef USE_IMAP