remove useless ssl options
[apps/madmutt.git] / lib-sys / mutt_signal.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
4  *
5  * This file is part of mutt-ng, see http://www.muttng.org/.
6  * It's licensed under the GNU General Public License,
7  * please see the file GPL in the top level source directory.
8  */
9
10 #include <lib-lib/lib-lib.h>
11
12 #include <lib-ui/lib-ui.h>
13
14 #include "mutt_signal.h"
15
16 static sigset_t Sigset;
17 static sigset_t SigsetSys;
18 static struct sigaction SysOldInt;
19 static struct sigaction SysOldQuit;
20 static int IsEndwin = 0;
21
22 /* Attempt to catch "ordinary" signals and shut down gracefully. */
23 static void exit_handler (int sig)
24 {
25     curs_set(1);
26     endwin();                    /* just to be safe */
27     printf(_("Caught %s...  Exiting.\n"), strsignal(sig));
28     exit(0);
29 }
30
31 static void sighandler (int sig)
32 {
33   int save_errno = errno;
34
35   switch (sig) {
36   case SIGTSTP:                /* user requested a suspend */
37     IsEndwin = isendwin ();
38     curs_set (1);
39     if (!IsEndwin)
40       endwin ();
41     kill (0, SIGSTOP);
42
43   case SIGCONT:
44     if (!IsEndwin)
45       refresh();
46     mutt_curs_set (-1);
47     /* We don't receive SIGWINCH when suspended; however, no harm is done by
48      * just assuming we received one, and triggering the 'resize' anyway. */
49   case SIGWINCH:
50     SigWinch = 1;
51     break;
52
53   case SIGCHLD:
54     SigChild = 1;
55     break;
56
57   case SIGINT:
58     SigInt = 1;
59     break;
60   }
61   errno = save_errno;
62 }
63
64 void mutt_signal_initialize (void)
65 {
66   struct sigaction act;
67
68   sigemptyset (&act.sa_mask);
69   act.sa_flags = 0;
70   act.sa_handler = SIG_IGN;
71   sigaction (SIGPIPE, &act, NULL);
72
73   act.sa_handler = exit_handler;
74   sigaction (SIGTERM, &act, NULL);
75   sigaction (SIGHUP, &act, NULL);
76   sigaction (SIGQUIT, &act, NULL);
77
78   /* we want to avoid race conditions */
79   sigaddset (&act.sa_mask, SIGTSTP);
80
81   act.sa_handler = sighandler;
82
83   /* we want SIGALRM to abort the current syscall, so we do this before
84    * setting the SA_RESTART flag below.  currently this is only used to
85    * timeout on a connect() call in a reasonable amout of time.
86    */
87   sigaction (SIGALRM, &act, NULL);
88
89   /* we also don't want to mess with interrupted system calls */
90 #ifdef SA_RESTART
91   act.sa_flags = SA_RESTART;
92 #endif
93
94   sigaction (SIGCONT, &act, NULL);
95   sigaction (SIGTSTP, &act, NULL);
96   sigaction (SIGINT, &act, NULL);
97   sigaction (SIGWINCH, &act, NULL);
98
99   /* POSIX doesn't allow us to ignore SIGCHLD,
100    * so we just install a dummy handler for it
101    */
102   /* don't need to block any other signals here */
103   sigemptyset (&act.sa_mask);
104   /* we don't want to mess with stopped children */
105   act.sa_flags |= SA_NOCLDSTOP;
106   sigaction (SIGCHLD, &act, NULL);
107 }
108
109 /* signals which are important to block while doing critical ops */
110 void mutt_block_signals (void)
111 {
112   if (!option (OPTSIGNALSBLOCKED)) {
113     sigemptyset (&Sigset);
114     sigaddset (&Sigset, SIGTERM);
115     sigaddset (&Sigset, SIGHUP);
116     sigaddset (&Sigset, SIGTSTP);
117     sigaddset (&Sigset, SIGINT);
118     sigaddset (&Sigset, SIGWINCH);
119     sigprocmask (SIG_BLOCK, &Sigset, 0);
120     set_option (OPTSIGNALSBLOCKED);
121   }
122 }
123
124 /* restore the previous signal mask */
125 void mutt_unblock_signals (void)
126 {
127   if (option (OPTSIGNALSBLOCKED)) {
128     sigprocmask (SIG_UNBLOCK, &Sigset, 0);
129     unset_option (OPTSIGNALSBLOCKED);
130   }
131 }
132
133 void mutt_block_signals_system (void)
134 {
135   struct sigaction sa;
136
137   if (!option (OPTSYSSIGNALSBLOCKED)) {
138     /* POSIX: ignore SIGINT and SIGQUIT & block SIGCHLD  before exec */
139     sa.sa_handler = SIG_IGN;
140     sa.sa_flags = 0;
141     sigemptyset (&sa.sa_mask);
142     sigaction (SIGINT, &sa, &SysOldInt);
143     sigaction (SIGQUIT, &sa, &SysOldQuit);
144
145     sigemptyset (&SigsetSys);
146     sigaddset (&SigsetSys, SIGCHLD);
147     sigprocmask (SIG_BLOCK, &SigsetSys, 0);
148     set_option (OPTSYSSIGNALSBLOCKED);
149   }
150 }
151
152 void mutt_unblock_signals_system (int catch)
153 {
154   if (option (OPTSYSSIGNALSBLOCKED)) {
155     sigprocmask (SIG_UNBLOCK, &SigsetSys, NULL);
156     if (catch) {
157       sigaction (SIGQUIT, &SysOldQuit, NULL);
158       sigaction (SIGINT, &SysOldInt, NULL);
159     }
160     else {
161       struct sigaction sa;
162
163       sa.sa_handler = SIG_DFL;
164       sigemptyset (&sa.sa_mask);
165       sa.sa_flags = 0;
166       sigaction (SIGQUIT, &sa, NULL);
167       sigaction (SIGINT, &sa, NULL);
168     }
169
170     unset_option (OPTSYSSIGNALSBLOCKED);
171   }
172 }
173
174 void mutt_allow_interrupt (int disposition)
175 {
176   struct sigaction sa;
177
178   p_clear(&sa, 1);
179   sa.sa_handler = sighandler;
180 #ifdef SA_RESTART
181   if (disposition == 0)
182     sa.sa_flags |= SA_RESTART;
183 #endif
184   sigaction (SIGINT, &sa, NULL);
185 }