1 /* ========================================================================
2 * Copyright 2006-2008 University of Washington
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * ========================================================================
16 #include "../../../c-client/c-client.h"
18 #include "../../../pith/conf.h"
19 #include "../../../pith/status.h"
20 #include "../../../pith/signal.h"
21 #include "../../../pith/debug.h"
22 #include "../../../pith/adrbklib.h"
23 #include "../../../pith/remote.h"
24 #include "../../../pith/imap.h"
30 static int cleanup_called_from_sig_handler
;
32 static RETSIGTYPE
hup_signal(int);
33 static RETSIGTYPE
term_signal(int);
34 static RETSIGTYPE
auger_in_signal(int);
35 int fast_clean_up(void);
36 void end_signals(int);
37 #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
38 static RETSIGTYPE
usr1_signal(int);
39 static RETSIGTYPE
usr2_signal(int);
43 /*----------------------------------------------------------------------
44 Install handlers for all the signals we care to catch
45 ----------------------------------------------------------------------*/
49 /* prepare for unexpected exit */
50 signal(SIGHUP
, hup_signal
);
51 signal(SIGTERM
, term_signal
);
53 /* prepare for unforeseen problems */
54 signal(SIGILL
, auger_in_signal
);
55 signal(SIGTRAP
, auger_in_signal
);
57 signal(SIGEMT
, auger_in_signal
);
59 signal(SIGBUS
, auger_in_signal
);
60 signal(SIGSEGV
, auger_in_signal
);
61 signal(SIGSYS
, auger_in_signal
);
63 #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
64 /* Set up SIGUSR2 to {in,de}crement debug level */
65 signal(SIGUSR1
, usr1_signal
);
66 signal(SIGUSR2
, usr2_signal
);
71 /*----------------------------------------------------------------------
72 handle hang up signal -- SIGHUP
74 Not much to do. Rely on periodic mail file check pointing.
75 ----------------------------------------------------------------------*/
80 cleanup_called_from_sig_handler
= 1;
82 while(!fast_clean_up())
85 if(peSocketName
) /* clean up unix domain socket */
86 (void) unlink(peSocketName
);
88 exceptional_exit("SIGHUP received", 0);
92 /*----------------------------------------------------------------------
93 handle terminate signal -- SIGTERM
95 Not much to do. Rely on periodic mail file check pointing.
96 ----------------------------------------------------------------------*/
101 cleanup_called_from_sig_handler
= 1;
103 while(!fast_clean_up())
106 if(peSocketName
) /* clean up unix domain socket */
107 (void) unlink(peSocketName
);
109 exceptional_exit("SIGTERM received", 0);
113 /*----------------------------------------------------------------------
114 Handle signals caused by aborts -- SIGSEGV, SIGILL, etc
116 Call panic which cleans up tty modes and then core dumps
117 ----------------------------------------------------------------------*/
119 auger_in_signal(int sig
)
123 if(peSocketName
) /* clean up unix domain socket */
124 (void) unlink(peSocketName
);
126 snprintf(tmp_20k_buf
, SIZEOF_20KBUF
, "Abort: signal %d", sig
);
127 alpine_panic(tmp_20k_buf
); /* clean up and get out */
128 exit(-1); /* in case panic doesn't kill us */
132 /*----------------------------------------------------------------------
133 Handle cleaning up mail streams and tty modes...
134 Not much to do. Rely on periodic mail file check pointing. Don't try
135 cleaning up screen or flushing output since stdout is likely already
136 gone. To be safe, though, we'll at least restore the original tty mode.
137 Also delete any remnant _DATAFILE_ from sending-filters.
138 ----------------------------------------------------------------------*/
145 if(ps_global
->expunge_in_progress
)
149 * This gets rid of temporary cache files for remote addrbooks.
151 completely_done_with_adrbks();
154 * This flushes out deferred changes and gets rid of temporary cache
155 * files for remote config files.
158 if(ps_global
->prc
->outstanding_pinerc_changes
)
159 write_pinerc(ps_global
, Main
,
160 cleanup_called_from_sig_handler
? WRP_NOUSER
: WRP_NONE
);
162 if(ps_global
->prc
->rd
)
163 rd_close_remdata(&ps_global
->prc
->rd
);
165 free_pinerc_s(&ps_global
->prc
);
169 if(ps_global
->post_prc
){
170 if(ps_global
->post_prc
->outstanding_pinerc_changes
)
171 write_pinerc(ps_global
, Post
,
172 cleanup_called_from_sig_handler
? WRP_NOUSER
: WRP_NONE
);
174 if(ps_global
->post_prc
->rd
)
175 rd_close_remdata(&ps_global
->post_prc
->rd
);
177 free_pinerc_s(&ps_global
->post_prc
);
181 * Can't figure out why this section is inside the ifdef, but no
182 * harm leaving it that way, I guess.
184 #if !defined(DOS) && !defined(OS2)
185 for(i
= 0; i
< ps_global
->s_pool
.nstream
; i
++){
186 m
= ps_global
->s_pool
.streams
[i
];
188 pine_mail_actually_close(m
);
192 imap_flush_passwd_cache(TRUE
);
194 if(peSocketName
) /* clean up unix domain socket */
195 (void) unlink(peSocketName
);
197 dprint((1, "done with fast_clean_up\n"));
203 /*----------------------------------------------------------------------
204 Return all signal handling back to normal
205 ----------------------------------------------------------------------*/
207 end_signals(int blockem
)
210 #define SIG_ERR (RETSIGTYPE (*)())-1
212 if(signal(SIGILL
, blockem
? SIG_IGN
: SIG_DFL
) != SIG_ERR
){
213 signal(SIGTRAP
, blockem
? SIG_IGN
: SIG_DFL
);
215 signal(SIGEMT
, blockem
? SIG_IGN
: SIG_DFL
);
217 signal(SIGBUS
, blockem
? SIG_IGN
: SIG_DFL
);
218 signal(SIGSEGV
, blockem
? SIG_IGN
: SIG_DFL
);
219 signal(SIGSYS
, blockem
? SIG_IGN
: SIG_DFL
);
220 signal(SIGHUP
, blockem
? SIG_IGN
: SIG_DFL
);
221 signal(SIGTERM
, blockem
? SIG_IGN
: SIG_DFL
);
222 signal(SIGINT
, blockem
? SIG_IGN
: SIG_DFL
);
227 #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
228 /*----------------------------------------------------------------------
231 Increment debug level
232 ----------------------------------------------------------------------*/
241 dprint((SYSDBG_INFO
, "Debug level now %d", debug
));
244 /*----------------------------------------------------------------------
247 Decrement debug level
248 ----------------------------------------------------------------------*/
257 dprint((SYSDBG_INFO
, "Debug level now %d", debug
));
264 * Command interrupt support.
267 intr_handling_on(void)
274 intr_handling_off(void)