NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
signal.c File Reference

Signal handling. More...

#include "config.h"
#include <stddef.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "message.h"
#include "signal2.h"
+ Include dependency graph for signal.c:

Go to the source code of this file.

Functions

void mutt_sig_empty_handler (int sig)
 Dummy signal handler.
 
void mutt_sig_exit_handler (int sig)
 Notify the user and shutdown gracefully.
 
void mutt_sig_init (sig_handler_t sig_fn, sig_handler_t exit_fn, sig_handler_t segv_fn)
 Initialise the signal handling.
 
void mutt_sig_block (void)
 Block signals during critical operations.
 
void mutt_sig_unblock (void)
 Restore previously blocked signals.
 
void mutt_sig_block_system (void)
 Block signals before calling exec()
 
void mutt_sig_unblock_system (bool restore)
 Restore previously blocked signals.
 
void mutt_sig_allow_interrupt (bool allow)
 Allow/disallow Ctrl-C (SIGINT)
 

Variables

static sigset_t Sigset
 A set of signals used by mutt_sig_block(), mutt_sig_unblock()
 
static sigset_t SigsetSys
 A set of signals used by mutt_sig_block_system(), mutt_sig_unblock_system()
 
static struct sigaction SysOldInt
 Backup of SIGINT handler, when mutt_sig_block_system() is called.
 
static struct sigaction SysOldQuit
 Backup of SIGQUIT handler, when mutt_sig_block_system() is called.
 
static bool SignalsBlocked
 true when signals are blocked, e.g.
 
static bool SysSignalsBlocked
 true when system signals are blocked, e.g.
 
static sig_handler_t SigHandler = mutt_sig_empty_handler
 Function to handle other signals, e.g. SIGINT (2)
 
static sig_handler_t ExitHandler = mutt_sig_exit_handler
 Function to handle SIGTERM (15), SIGHUP (1), SIGQUIT (3) signals.
 
static sig_handler_t SegvHandler = mutt_sig_exit_handler
 Function to handle SIGSEGV (11) signals.
 

Detailed Description

Signal handling.

Authors
  • Richard Russon

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/.

Definition in file signal.c.

Function Documentation

◆ mutt_sig_empty_handler()

void mutt_sig_empty_handler ( int  sig)

Dummy signal handler.

Parameters
sigSignal number, e.g. SIGINT

Useful for signals that we can't ignore, or don't want to do anything with.

Definition at line 70 of file signal.c.

71{
72}
+ Here is the caller graph for this function:

◆ mutt_sig_exit_handler()

void mutt_sig_exit_handler ( int  sig)

Notify the user and shutdown gracefully.

Parameters
sigSignal number, e.g. SIGINT

Definition at line 78 of file signal.c.

79{
80#ifdef HAVE_DECL_SYS_SIGLIST
81 printf(_("Caught signal %d (%s) ... Exiting\n"), sig, sys_siglist[sig]);
82#elif (defined(__sun__) && defined(__svr4__))
83 printf(_("Caught signal %d (%s) ... Exiting\n"), sig, _sys_siglist[sig]);
84#elif (defined(__alpha) && defined(__osf__))
85 printf(_("Caught signal %d (%s) ... Exiting\n"), sig, __sys_siglist[sig]);
86#else
87 printf(_("Caught signal %d ... Exiting\n"), sig);
88#endif
89 exit(0);
90}
#define _(a)
Definition: message.h:28
+ Here is the caller graph for this function:

◆ mutt_sig_init()

void mutt_sig_init ( sig_handler_t  sig_fn,
sig_handler_t  exit_fn,
sig_handler_t  segv_fn 
)

Initialise the signal handling.

Parameters
sig_fnFunction to handle signals
exit_fnFunction to call on uncaught signals
segv_fnFunction to call on a segfault (Segmentation Violation)

Set up handlers to ignore or catch signals of interest. We use three handlers for the signals we want to catch, ignore, or exit.

Definition at line 101 of file signal.c.

102{
103 if (sig_fn)
104 SigHandler = sig_fn;
105
106 if (exit_fn)
107 ExitHandler = exit_fn;
108
109 if (segv_fn)
110 SegvHandler = segv_fn;
111
112 struct sigaction act = { 0 };
113
114 sigemptyset(&act.sa_mask);
115 act.sa_flags = 0;
116 act.sa_handler = SIG_IGN;
117 sigaction(SIGPIPE, &act, NULL);
118
119 act.sa_handler = SegvHandler;
120 sigaction(SIGSEGV, &act, NULL);
121
122 act.sa_handler = ExitHandler;
123 sigaction(SIGTERM, &act, NULL);
124 sigaction(SIGHUP, &act, NULL);
125 sigaction(SIGQUIT, &act, NULL);
126
127 /* we want to avoid race conditions */
128 sigaddset(&act.sa_mask, SIGTSTP);
129
130 act.sa_handler = SigHandler;
131
132 /* we want SIGALRM to abort the current syscall, so we do this before
133 * setting the SA_RESTART flag below. currently this is only used to
134 * timeout on a connect() call in a reasonable amount of time. */
135 sigaction(SIGALRM, &act, NULL);
136
137/* we also don't want to mess with interrupted system calls */
138#ifdef SA_RESTART
139 act.sa_flags = SA_RESTART;
140#endif
141
142 sigaction(SIGCONT, &act, NULL);
143 sigaction(SIGTSTP, &act, NULL);
144 sigaction(SIGINT, &act, NULL);
145 sigaction(SIGWINCH, &act, NULL);
146
147 /* POSIX doesn't allow us to ignore SIGCHLD,
148 * so we just install a dummy handler for it */
149 act.sa_handler = mutt_sig_empty_handler;
150 /* don't need to block any other signals here */
151 sigemptyset(&act.sa_mask);
152 /* we don't want to mess with stopped children */
153 act.sa_flags |= SA_NOCLDSTOP;
154 sigaction(SIGCHLD, &act, NULL);
155}
static sig_handler_t ExitHandler
Function to handle SIGTERM (15), SIGHUP (1), SIGQUIT (3) signals.
Definition: signal.c:59
static sig_handler_t SigHandler
Function to handle other signals, e.g. SIGINT (2)
Definition: signal.c:57
void mutt_sig_empty_handler(int sig)
Dummy signal handler.
Definition: signal.c:70
static sig_handler_t SegvHandler
Function to handle SIGSEGV (11) signals.
Definition: signal.c:61
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sig_block()

void mutt_sig_block ( void  )

Block signals during critical operations.

It's important that certain signals don't interfere with critical operations. Call mutt_sig_unblock() to restore the signals' behaviour.

Definition at line 163 of file signal.c.

164{
165 if (SignalsBlocked)
166 return;
167
168 sigemptyset(&Sigset);
169 sigaddset(&Sigset, SIGTERM);
170 sigaddset(&Sigset, SIGHUP);
171 sigaddset(&Sigset, SIGTSTP);
172 sigaddset(&Sigset, SIGINT);
173 sigaddset(&Sigset, SIGWINCH);
174 sigprocmask(SIG_BLOCK, &Sigset, 0);
175 SignalsBlocked = true;
176}
static sigset_t Sigset
A set of signals used by mutt_sig_block(), mutt_sig_unblock()
Definition: signal.c:39
static bool SignalsBlocked
true when signals are blocked, e.g.
Definition: signal.c:50
+ Here is the caller graph for this function:

◆ mutt_sig_unblock()

void mutt_sig_unblock ( void  )

Restore previously blocked signals.

Definition at line 181 of file signal.c.

182{
183 if (!SignalsBlocked)
184 return;
185
186 sigprocmask(SIG_UNBLOCK, &Sigset, 0);
187 SignalsBlocked = false;
188}
+ Here is the caller graph for this function:

◆ mutt_sig_block_system()

void mutt_sig_block_system ( void  )

Block signals before calling exec()

It's important that certain signals don't interfere with the child process. Call mutt_sig_unblock_system() to restore the signals' behaviour.

Definition at line 196 of file signal.c.

197{
199 return;
200
201 struct sigaction sa = { 0 };
202
203 /* POSIX: ignore SIGINT and SIGQUIT & block SIGCHLD before exec */
204 sa.sa_handler = SIG_IGN;
205 sa.sa_flags = 0;
206 sigemptyset(&sa.sa_mask);
207 sigaction(SIGINT, &sa, &SysOldInt);
208 sigaction(SIGQUIT, &sa, &SysOldQuit);
209
210 sigemptyset(&SigsetSys);
211 sigaddset(&SigsetSys, SIGCHLD);
212 sigprocmask(SIG_BLOCK, &SigsetSys, 0);
213 SysSignalsBlocked = true;
214}
static bool SysSignalsBlocked
true when system signals are blocked, e.g.
Definition: signal.c:54
static struct sigaction SysOldQuit
Backup of SIGQUIT handler, when mutt_sig_block_system() is called.
Definition: signal.c:46
static sigset_t SigsetSys
A set of signals used by mutt_sig_block_system(), mutt_sig_unblock_system()
Definition: signal.c:41
static struct sigaction SysOldInt
Backup of SIGINT handler, when mutt_sig_block_system() is called.
Definition: signal.c:44
+ Here is the caller graph for this function:

◆ mutt_sig_unblock_system()

void mutt_sig_unblock_system ( bool  restore)

Restore previously blocked signals.

Parameters
restoreIf true, restore previous SIGINT, SIGQUIT behaviour

Definition at line 220 of file signal.c.

221{
223 return;
224
225 sigprocmask(SIG_UNBLOCK, &SigsetSys, NULL);
226 if (restore)
227 {
228 sigaction(SIGQUIT, &SysOldQuit, NULL);
229 sigaction(SIGINT, &SysOldInt, NULL);
230 }
231 else
232 {
233 struct sigaction sa = { 0 };
234
235 sa.sa_handler = SIG_DFL;
236 sigemptyset(&sa.sa_mask);
237 sa.sa_flags = 0;
238 sigaction(SIGQUIT, &sa, NULL);
239 sigaction(SIGINT, &sa, NULL);
240 }
241
242 SysSignalsBlocked = false;
243}
+ Here is the caller graph for this function:

◆ mutt_sig_allow_interrupt()

void mutt_sig_allow_interrupt ( bool  allow)

Allow/disallow Ctrl-C (SIGINT)

Parameters
allowTrue to allow Ctrl-C to interrupt signals

Allow the user to interrupt some long operations.

Definition at line 251 of file signal.c.

252{
253 struct sigaction sa = { 0 };
254
255 sa.sa_handler = SigHandler;
256#ifdef SA_RESTART
257 if (!allow)
258 sa.sa_flags |= SA_RESTART;
259#endif
260 sigaction(SIGINT, &sa, NULL);
261}
+ Here is the caller graph for this function:

Variable Documentation

◆ Sigset

sigset_t Sigset
static

A set of signals used by mutt_sig_block(), mutt_sig_unblock()

Definition at line 39 of file signal.c.

◆ SigsetSys

sigset_t SigsetSys
static

A set of signals used by mutt_sig_block_system(), mutt_sig_unblock_system()

Definition at line 41 of file signal.c.

◆ SysOldInt

struct sigaction SysOldInt
static

Backup of SIGINT handler, when mutt_sig_block_system() is called.

Definition at line 44 of file signal.c.

◆ SysOldQuit

struct sigaction SysOldQuit
static

Backup of SIGQUIT handler, when mutt_sig_block_system() is called.

Definition at line 46 of file signal.c.

◆ SignalsBlocked

bool SignalsBlocked
static

true when signals are blocked, e.g.

SIGTERM, SIGHUP

See also
mutt_sig_block(), mutt_sig_unblock()

Definition at line 50 of file signal.c.

◆ SysSignalsBlocked

bool SysSignalsBlocked
static

true when system signals are blocked, e.g.

SIGINT, SIGQUIT

See also
mutt_sig_block_system(), mutt_sig_unblock_system()

Definition at line 54 of file signal.c.

◆ SigHandler

Function to handle other signals, e.g. SIGINT (2)

Definition at line 57 of file signal.c.

◆ ExitHandler

sig_handler_t ExitHandler = mutt_sig_exit_handler
static

Function to handle SIGTERM (15), SIGHUP (1), SIGQUIT (3) signals.

Definition at line 59 of file signal.c.

◆ SegvHandler

sig_handler_t SegvHandler = mutt_sig_exit_handler
static

Function to handle SIGSEGV (11) signals.

Definition at line 61 of file signal.c.