1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: signal.c 91 2006-07-28 19:02:07Z mikes@u.washington.edu $";
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 * ========================================================================
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"
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);
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);
47 /*----------------------------------------------------------------------
48 Install handlers for all the signals we care to catch
49 ----------------------------------------------------------------------*/
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
);
61 signal(SIGEMT
, auger_in_signal
);
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
);
75 /*----------------------------------------------------------------------
76 handle hang up signal -- SIGHUP
78 Not much to do. Rely on periodic mail file check pointing.
79 ----------------------------------------------------------------------*/
84 cleanup_called_from_sig_handler
= 1;
86 while(!fast_clean_up())
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 ----------------------------------------------------------------------*/
105 cleanup_called_from_sig_handler
= 1;
107 while(!fast_clean_up())
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 ----------------------------------------------------------------------*/
123 auger_in_signal(int sig
)
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 ----------------------------------------------------------------------*/
149 if(ps_global
->expunge_in_progress
)
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.
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
);
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
];
192 pine_mail_actually_close(m
);
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"));
207 /*----------------------------------------------------------------------
208 Return all signal handling back to normal
209 ----------------------------------------------------------------------*/
211 end_signals(int blockem
)
214 #define SIG_ERR (RETSIGTYPE (*)())-1
216 if(signal(SIGILL
, blockem
? SIG_IGN
: SIG_DFL
) != SIG_ERR
){
217 signal(SIGTRAP
, blockem
? SIG_IGN
: SIG_DFL
);
219 signal(SIGEMT
, blockem
? SIG_IGN
: SIG_DFL
);
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 /*----------------------------------------------------------------------
235 Increment debug level
236 ----------------------------------------------------------------------*/
245 dprint((SYSDBG_INFO
, "Debug level now %d", debug
));
248 /*----------------------------------------------------------------------
251 Decrement debug level
252 ----------------------------------------------------------------------*/
261 dprint((SYSDBG_INFO
, "Debug level now %d", debug
));
268 * Command interrupt support.
271 intr_handling_on(void)
278 intr_handling_off(void)