ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/ircservices-5.1.24/signals.c
Revision: 1171
Committed: Fri Aug 12 20:00:46 2011 UTC (12 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 6664 byte(s)
Log Message:
- Import ircservices-5.1.24. Don't ever think about modifying anything in this
  folder!
  Since Andrew Church has discontinued his services project in April 2011, the
  ircd-hybrid team has been given permissions to officially continue and
  maintain the already mentioned project.
  The name of this project will be changed for the reason being that the current
  name "IRC Services" is way too generic these days.

  Remember: Don't ever modify anything in here. This folder is kept for reference.

File Contents

# Content
1 /* Signal handling routines.
2 *
3 * IRC Services is copyright (c) 1996-2009 Andrew Church.
4 * E-mail: <achurch@achurch.org>
5 * Parts written by Andrew Kempe and others.
6 * This program is free but copyrighted software; see the file GPL.txt for
7 * details.
8 */
9
10 #include "services.h"
11 #include <setjmp.h>
12
13 /*************************************************************************/
14
15 /* If we get a signal, use this to jump out of the main loop. */
16 static sigjmp_buf *panic_ptr = NULL;
17
18 /*************************************************************************/
19 /*************************************************************************/
20
21 /* Various signal handlers. */
22
23 /*************************************************************************/
24
25 /* SIGHUP = save databases and rehash configuration files */
26 static void sighup_handler(int sig_unused)
27 {
28 signal(SIGHUP, SIG_IGN); /* in case we get double signalled */
29 log("Received SIGHUP, saving data and rehashing.");
30 wallops(NULL,
31 "Received SIGHUP, saving data and rehashing configuration files");
32 save_data_now();
33 reconfigure();
34 signal(SIGHUP, sighup_handler);
35 }
36
37 /*************************************************************************/
38
39 /* SIGTERM = save databases and shut down */
40 static void sigterm_handler(int sig_unused)
41 {
42 save_data = 1;
43 delayed_quit = 1;
44 signal(SIGTERM, SIG_IGN);
45 signal(SIGHUP, SIG_IGN);
46 log("Received SIGTERM, exiting.");
47 strbcpy(quitmsg, "Shutting down on SIGTERM");
48 siglongjmp(*panic_ptr, 1);
49 }
50
51 /*************************************************************************/
52
53 /* SIGUSR2 = close and reopen log file */
54 static void sigusr2_handler(int sig_unused)
55 {
56 log("Received SIGUSR2, cycling log file.");
57 if (log_is_open()) {
58 close_log();
59 open_log();
60 }
61 signal(SIGUSR2, sigusr2_handler);
62 }
63
64 /*************************************************************************/
65
66 /* If we get a weird signal, come here. */
67 static void weirdsig_handler(int signum)
68 {
69 static int dying = 0; /* Flag to avoid infinite recursion */
70
71 if (dying++) {
72 /* Double signal, give up. Set `servsock' to NULL to avoid a
73 * message going out that way, just in case the socket code is
74 * confused/broken */
75 servsock = NULL;
76 if (signum == SIGUSR2) {
77 fatal("Out of memory while shutting down");
78 } else {
79 #if HAVE_STRSIGNAL
80 fatal("Caught signal %d (%s) while shutting down", signum,
81 strsignal(signum));
82 #else
83 fatal("Caught signal %d while shutting down", signum);
84 #endif
85 }
86 }
87
88 /* Avoid spurious keyboard signals killing us while shutting down */
89 signal(SIGINT, SIG_IGN);
90 signal(SIGQUIT, SIG_IGN);
91 signal(SIGTSTP, SIG_IGN);
92
93 /* If we died processing a message, let people know about it */
94 if (signum != SIGINT && signum != SIGQUIT) {
95 if (*inbuf) {
96 log("PANIC! signal %d, buffer = %s", signum, inbuf);
97 /* Cut off if this would make IRC command >510 characters. */
98 if (strlen(inbuf) > 448) {
99 inbuf[446] = '>';
100 inbuf[447] = '>';
101 inbuf[448] = 0;
102 }
103 wallops(NULL, "PANIC! buffer = %s\r\n", inbuf);
104 } else {
105 log("PANIC! signal %d (no buffer)", signum);
106 wallops(NULL, "PANIC! signal %d (no buffer)", signum);
107 }
108 }
109
110 /* Pick an appropriate quit message */
111 if (signum == SIGUSR1) {
112 strbcpy(quitmsg, "Out of memory!");
113 quitting = 1;
114 } else {
115 #if HAVE_STRSIGNAL
116 snprintf(quitmsg, sizeof(quitmsg),
117 "Services terminating: %s", strsignal(signum));
118 #else
119 snprintf(quitmsg, sizeof(quitmsg),
120 "Services terminating on signal %d", signum);
121 #endif
122 quitting = 1;
123 }
124
125 /* Actually quit */
126 if (panic_ptr) {
127 siglongjmp(*panic_ptr, 1);
128 } else {
129 log("%s", quitmsg);
130 if (isatty(2))
131 fprintf(stderr, "%s\n", quitmsg);
132 exit(1);
133 }
134 }
135
136 /*************************************************************************/
137 /*************************************************************************/
138
139 /* Set up signal handlers. Catch certain signals to let us do things or
140 * panic as necessary, and ignore all others.
141 */
142
143 void init_signals(void)
144 {
145 int i;
146
147 /* Start out with special signals disabled */
148 disable_signals();
149
150 /* Set all signals to "ignore" */
151 for (i = 1; i <= NSIG; i++) {
152 #if DUMPCORE
153 if (i != SIGSEGV)
154 #endif
155 if (i != SIGPROF && i != SIGCHLD)
156 signal(i, SIG_IGN);
157 }
158
159 /* Specify particular signals we want to catch */
160
161 /* Signals that probably mean bad things have happened */
162 #if !DUMPCORE
163 signal(SIGSEGV, weirdsig_handler);
164 #endif
165 signal(SIGBUS, weirdsig_handler);
166 signal(SIGILL, weirdsig_handler);
167 signal(SIGTRAP, weirdsig_handler);
168 signal(SIGFPE, weirdsig_handler);
169 #ifdef SIGIOT
170 signal(SIGIOT, weirdsig_handler);
171 #endif
172
173 /* This is our "out-of-memory" panic switch */
174 signal(SIGUSR1, weirdsig_handler);
175
176 /* Other special handlers */
177 signal(SIGTERM, sigterm_handler);
178 signal(SIGINT, weirdsig_handler);
179 signal(SIGQUIT, weirdsig_handler);
180 signal(SIGHUP, sighup_handler);
181 signal(SIGUSR2, sigusr2_handler);
182
183 }
184
185 /*************************************************************************/
186
187 /* Helper routine for main.c's DO_SIGSETJMP() macro; saves a pointer to the
188 * environment buffer locally.
189 */
190
191 void do_sigsetjmp(void *bufptr)
192 {
193 panic_ptr = bufptr;
194 }
195
196 /*************************************************************************/
197
198 /* Enable or disable receipt of certain signals (in particular, those which
199 * cause us to take actions other than simply terminating the program, to
200 * avoid such signals happening at inopportune times and causing things to
201 * break).
202 */
203
204 void enable_signals(void)
205 {
206 sigset_t sigs;
207 sigemptyset(&sigs);
208 sigaddset(&sigs, SIGHUP);
209 sigaddset(&sigs, SIGTERM);
210 sigaddset(&sigs, SIGUSR2);
211 sigprocmask(SIG_UNBLOCK, &sigs, NULL);
212 }
213
214
215 void disable_signals(void)
216 {
217 sigset_t sigs;
218 sigemptyset(&sigs);
219 sigaddset(&sigs, SIGHUP);
220 sigaddset(&sigs, SIGTERM);
221 sigaddset(&sigs, SIGUSR2);
222 sigprocmask(SIG_BLOCK, &sigs, NULL);
223 }
224
225 /*************************************************************************/
226
227 /*
228 * Local variables:
229 * c-file-style: "stroustrup"
230 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
231 * indent-tabs-mode: nil
232 * End:
233 *
234 * vim: expandtab shiftwidth=4:
235 */