* new version 2.19.9993
[alpine.git] / web / src / alpined.d / signal.c
blob52d8e600fa47a79bea46c73c7ebbf4fee30b6de2
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: signal.c 91 2006-07-28 19:02:07Z mikes@u.washington.edu $";
3 #endif
5 /* ========================================================================
6 * Copyright 2006-2008 University of Washington
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * ========================================================================
17 #include <system.h>
18 #include <general.h>
20 #include "../../../c-client/c-client.h"
22 #include "../../../pith/conf.h"
23 #include "../../../pith/status.h"
24 #include "../../../pith/signal.h"
25 #include "../../../pith/debug.h"
26 #include "../../../pith/adrbklib.h"
27 #include "../../../pith/remote.h"
28 #include "../../../pith/imap.h"
30 #include "alpined.h"
31 #include "debug.h"
34 static int cleanup_called_from_sig_handler;
36 static RETSIGTYPE hup_signal(int);
37 static RETSIGTYPE term_signal(int);
38 static RETSIGTYPE auger_in_signal(int);
39 int fast_clean_up();
40 void end_signals(int);
41 #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
42 static RETSIGTYPE usr1_signal(int);
43 static RETSIGTYPE usr2_signal(int);
44 #endif
47 /*----------------------------------------------------------------------
48 Install handlers for all the signals we care to catch
49 ----------------------------------------------------------------------*/
50 void
51 init_signals(void)
53 /* prepare for unexpected exit */
54 signal(SIGHUP, hup_signal);
55 signal(SIGTERM, term_signal);
57 /* prepare for unforseen problems */
58 signal(SIGILL, auger_in_signal);
59 signal(SIGTRAP, auger_in_signal);
60 #ifdef SIGEMT
61 signal(SIGEMT, auger_in_signal);
62 #endif
63 signal(SIGBUS, auger_in_signal);
64 signal(SIGSEGV, auger_in_signal);
65 signal(SIGSYS, auger_in_signal);
67 #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
68 /* Set up SIGUSR2 to {in,de}crement debug level */
69 signal(SIGUSR1, usr1_signal);
70 signal(SIGUSR2, usr2_signal);
71 #endif
75 /*----------------------------------------------------------------------
76 handle hang up signal -- SIGHUP
78 Not much to do. Rely on periodic mail file check pointing.
79 ----------------------------------------------------------------------*/
80 static RETSIGTYPE
81 hup_signal(int sig)
83 end_signals(1);
84 cleanup_called_from_sig_handler = 1;
86 while(!fast_clean_up())
87 sleep(1);
89 if(peSocketName) /* clean up unix domain socket */
90 (void) unlink(peSocketName);
92 exceptional_exit("SIGHUP received", 0);
96 /*----------------------------------------------------------------------
97 handle terminate signal -- SIGTERM
99 Not much to do. Rely on periodic mail file check pointing.
100 ----------------------------------------------------------------------*/
101 static RETSIGTYPE
102 term_signal(int sig)
104 end_signals(1);
105 cleanup_called_from_sig_handler = 1;
107 while(!fast_clean_up())
108 sleep(1);
110 if(peSocketName) /* clean up unix domain socket */
111 (void) unlink(peSocketName);
113 exceptional_exit("SIGTERM received", 0);
117 /*----------------------------------------------------------------------
118 Handle signals caused by aborts -- SIGSEGV, SIGILL, etc
120 Call panic which cleans up tty modes and then core dumps
121 ----------------------------------------------------------------------*/
122 static RETSIGTYPE
123 auger_in_signal(int sig)
125 end_signals(1);
127 if(peSocketName) /* clean up unix domain socket */
128 (void) unlink(peSocketName);
130 snprintf(tmp_20k_buf, SIZEOF_20KBUF, "Abort: signal %d", sig);
131 alpine_panic(tmp_20k_buf); /* clean up and get out */
132 exit(-1); /* in case panic doesn't kill us */
136 /*----------------------------------------------------------------------
137 Handle cleaning up mail streams and tty modes...
138 Not much to do. Rely on periodic mail file check pointing. Don't try
139 cleaning up screen or flushing output since stdout is likely already
140 gone. To be safe, though, we'll at least restore the original tty mode.
141 Also delete any remnant _DATAFILE_ from sending-filters.
142 ----------------------------------------------------------------------*/
144 fast_clean_up(void)
146 int i;
147 MAILSTREAM *m;
149 if(ps_global->expunge_in_progress)
150 return(0);
153 * This gets rid of temporary cache files for remote addrbooks.
155 completely_done_with_adrbks();
158 * This flushes out deferred changes and gets rid of temporary cache
159 * files for remote config files.
161 if(ps_global->prc){
162 if(ps_global->prc->outstanding_pinerc_changes)
163 write_pinerc(ps_global, Main,
164 cleanup_called_from_sig_handler ? WRP_NOUSER : WRP_NONE);
166 if(ps_global->prc->rd)
167 rd_close_remdata(&ps_global->prc->rd);
169 free_pinerc_s(&ps_global->prc);
172 /* as does this */
173 if(ps_global->post_prc){
174 if(ps_global->post_prc->outstanding_pinerc_changes)
175 write_pinerc(ps_global, Post,
176 cleanup_called_from_sig_handler ? WRP_NOUSER : WRP_NONE);
178 if(ps_global->post_prc->rd)
179 rd_close_remdata(&ps_global->post_prc->rd);
181 free_pinerc_s(&ps_global->post_prc);
185 * Can't figure out why this section is inside the ifdef, but no
186 * harm leaving it that way, I guess.
188 #if !defined(DOS) && !defined(OS2)
189 for(i = 0; i < ps_global->s_pool.nstream; i++){
190 m = ps_global->s_pool.streams[i];
191 if(m && !m->lock)
192 pine_mail_actually_close(m);
194 #endif /* !DOS */
196 imap_flush_passwd_cache(TRUE);
198 if(peSocketName) /* clean up unix domain socket */
199 (void) unlink(peSocketName);
201 dprint((1, "done with fast_clean_up\n"));
202 return(1);
207 /*----------------------------------------------------------------------
208 Return all signal handling back to normal
209 ----------------------------------------------------------------------*/
210 void
211 end_signals(int blockem)
213 #ifndef SIG_ERR
214 #define SIG_ERR (RETSIGTYPE (*)())-1
215 #endif
216 if(signal(SIGILL, blockem ? SIG_IGN : SIG_DFL) != SIG_ERR){
217 signal(SIGTRAP, blockem ? SIG_IGN : SIG_DFL);
218 #ifdef SIGEMT
219 signal(SIGEMT, blockem ? SIG_IGN : SIG_DFL);
220 #endif
221 signal(SIGBUS, blockem ? SIG_IGN : SIG_DFL);
222 signal(SIGSEGV, blockem ? SIG_IGN : SIG_DFL);
223 signal(SIGSYS, blockem ? SIG_IGN : SIG_DFL);
224 signal(SIGHUP, blockem ? SIG_IGN : SIG_DFL);
225 signal(SIGTERM, blockem ? SIG_IGN : SIG_DFL);
226 signal(SIGINT, blockem ? SIG_IGN : SIG_DFL);
231 #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
232 /*----------------------------------------------------------------------
233 handle -- SIGUSR1
235 Increment debug level
236 ----------------------------------------------------------------------*/
237 static RETSIGTYPE
238 usr1_signal(int sig)
240 if(debug < 11)
241 debug++;
243 setup_imap_debug();
245 dprint((SYSDBG_INFO, "Debug level now %d", debug));
248 /*----------------------------------------------------------------------
249 handle -- SIGUSR2
251 Decrement debug level
252 ----------------------------------------------------------------------*/
253 static RETSIGTYPE
254 usr2_signal(int sig)
256 if(debug > 0)
257 debug--;
259 setup_imap_debug();
261 dprint((SYSDBG_INFO, "Debug level now %d", debug));
264 #endif
268 * Command interrupt support.
271 intr_handling_on(void)
273 return 0;
277 void
278 intr_handling_off(void)