/[hydra]/hydra/src/signals.c
ViewVC logotype

Contents of /hydra/src/signals.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Sat Sep 21 13:53:54 2002 UTC (21 years, 7 months ago) by nmav
Branch: boas
CVS Tags: start
Changes since 1.1: +0 -0 lines
File MIME type: text/plain
Imported sources

1 /*
2 * Boa, an http server
3 * Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
4 * Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
5 * Some changes Copyright (C) 1996-99 Jon Nelson <jnelson@boa.org>
6 * Some changes Copyright (C) 1997 Alain Magloire <alain.magloire@rcsm.ee.mcgill.ca>
7 * Portions Copyright (C) 2002 Nikos Mavroyanopoulos <nmav@gnutls.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 1, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25 /* $Id: signals.c,v 1.37.2.2 2002/07/23 16:03:41 jnelson Exp $*/
26
27 #include "boa.h"
28 #ifdef HAVE_SYS_WAIT_H
29 #include <sys/wait.h> /* wait */
30 #endif
31 #include <signal.h> /* signal */
32 #include "ssl.h"
33
34 #ifdef ENABLE_SMP
35 # include <pthread.h>
36
37 extern pthread_t father_id;
38
39 #endif
40
41 extern server_params *global_server_params;
42 extern int global_server_params_size;
43
44 void sigsegv(int);
45 void sigbus(int);
46 void sigterm(int);
47 void sighup(int);
48 void sigint(int);
49 void sigchld(int);
50 void sigalrm(int);
51 void sigusr1(int);
52
53 /*
54 * Name: init_signals
55 * Description: Sets up signal handlers for all our friends.
56 */
57
58 void init_signals(void)
59 {
60 struct sigaction sa;
61
62 sa.sa_flags = 0;
63
64 sigemptyset(&sa.sa_mask);
65 sigaddset(&sa.sa_mask, SIGSEGV);
66 sigaddset(&sa.sa_mask, SIGBUS);
67 sigaddset(&sa.sa_mask, SIGTERM);
68 sigaddset(&sa.sa_mask, SIGHUP);
69 sigaddset(&sa.sa_mask, SIGINT);
70 sigaddset(&sa.sa_mask, SIGPIPE);
71 sigaddset(&sa.sa_mask, SIGCHLD);
72 sigaddset(&sa.sa_mask, SIGALRM);
73 sigaddset(&sa.sa_mask, SIGUSR1);
74 sigaddset(&sa.sa_mask, SIGUSR2);
75
76 sa.sa_handler = sigsegv;
77 sigaction(SIGSEGV, &sa, NULL);
78
79 sa.sa_handler = sigbus;
80 sigaction(SIGBUS, &sa, NULL);
81
82 sa.sa_handler = SIG_IGN;
83 sigaction(SIGPIPE, &sa, NULL);
84
85 sa.sa_handler = sigchld;
86 sigaction(SIGCHLD, &sa, NULL);
87
88 sa.sa_handler = sigterm;
89 sigaction(SIGTERM, &sa, NULL);
90
91 sa.sa_handler = sighup;
92 sigaction(SIGHUP, &sa, NULL);
93
94 sa.sa_handler = sigint;
95 sigaction(SIGINT, &sa, NULL);
96
97 sa.sa_handler = sigalrm;
98 sigaction(SIGALRM, &sa, NULL);
99
100 sa.sa_handler = sigusr1;
101 sigaction(SIGUSR1, &sa, NULL);
102
103 sa.sa_handler = SIG_IGN;
104 sigaction(SIGUSR2, &sa, NULL);
105 }
106
107 /* Blocks all signals that should be handled by
108 * the main thread, so that other threads are
109 * not annoyed.
110 */
111 void block_main_signals()
112 {
113 sigset_t sigset;
114
115 sigemptyset( &sigset);
116 sigaddset( &sigset, SIGALRM);
117 sigaddset( &sigset, SIGUSR1);
118 sigaddset( &sigset, SIGTERM);
119 sigaddset( &sigset, SIGHUP);
120 sigaddset( &sigset, SIGINT);
121
122 sigprocmask( SIG_BLOCK, &sigset, NULL);
123 }
124
125 void unblock_main_signals()
126 {
127 sigset_t sigset;
128
129 sigemptyset( &sigset);
130 sigaddset( &sigset, SIGALRM);
131 sigaddset( &sigset, SIGUSR1);
132 sigaddset( &sigset, SIGTERM);
133 sigaddset( &sigset, SIGHUP);
134 sigaddset( &sigset, SIGINT);
135
136 sigprocmask( SIG_UNBLOCK, &sigset, NULL);
137 }
138
139 void sigsegv(int dummy)
140 {
141 time(&current_time);
142 log_error_time();
143 fprintf(stderr, "caught SIGSEGV, dumping core in %s\n", tempdir);
144 fclose(stderr);
145 chdir(tempdir);
146 abort();
147 }
148
149 void sigbus(int dummy)
150 {
151 server_params* params = &global_server_params[0];
152
153 /* Note that in multithreaded cases the SIGBUS is catched
154 * by the same thread that did the violation. So the following
155 * code should be ok.
156 */
157
158 #ifdef ENABLE_SMP
159 pthread_t tid = pthread_self();
160 int i;
161
162 for (i=0;i<global_server_params_size;i++) {
163 if (pthread_equal( global_server_params[i].tid, tid)) {
164 params = &global_server_params[i];
165 break;
166 }
167 }
168 #endif
169
170 if (params->handle_sigbus) {
171 longjmp(params->env, dummy);
172 }
173 time(&current_time);
174 log_error_time();
175 fprintf(stderr, "caught SIGBUS, dumping core in %s\n", tempdir);
176 fclose(stderr);
177 chdir(tempdir);
178 abort();
179 }
180
181 #define SET_PTH_SIGFLAG( flag, val) \
182 global_server_params[0].flag = val
183
184
185 void sigterm(int dummy)
186 {
187 SET_PTH_SIGFLAG( sigterm_flag, 1);
188 }
189
190
191 void sigterm_stage1_run() /* lame duck mode */
192 {
193 #ifdef ENABLE_SMP
194 int i;
195
196 if (!pthread_equal( pthread_self(), father_id)) return;
197 #endif
198
199 time(&current_time);
200 log_error_time();
201 fputs("caught SIGTERM, starting shutdown\n", stderr);
202
203 #ifdef ENABLE_SMP
204 /* remember that the first thread is actual the main process.
205 */
206 for (i=1;i<global_server_params_size;i++) {
207 /* terminate all threads */
208 int ret;
209
210 if ((ret=pthread_cancel( global_server_params[i].tid)) != 0) {
211 log_error_time();
212 fprintf(stderr, "Could not cancel thread: %d. errno = %d.\n" , (int)global_server_params[i].tid, ret);
213 exit(1);
214 }
215 }
216 #endif
217
218 if ( global_server_params[0].server_s[0].socket != -1) {
219 FD_CLR(global_server_params[0].server_s[0].socket, &global_server_params[0].block_read_fdset);
220 close(global_server_params[0].server_s[0].socket);
221 }
222
223 if ( global_server_params[0].server_s[1].socket != -1) {
224 FD_CLR(global_server_params[0].server_s[1].socket, &global_server_params[0].block_read_fdset);
225 close(global_server_params[0].server_s[1].socket);
226 }
227
228 SET_PTH_SIGFLAG( sigterm_flag, 2);
229 }
230
231
232 void sigterm_stage2_run() /* lame duck mode */
233 {
234 int i;
235
236 #ifdef ENABLE_SMP
237 if (!pthread_equal( pthread_self(), father_id)) return;
238 #endif
239
240 log_error_time();
241 fprintf(stderr,
242 "exiting Boa normally (uptime %d seconds)\n",
243 (int) (current_time - start_time));
244 chdir(tempdir);
245 clear_common_env();
246 dump_mime();
247 dump_passwd();
248 dump_alias();
249
250 for (i=0;i<global_server_params_size;i++) {
251 free_requests( &global_server_params[i]);
252 }
253
254 exit(0);
255 }
256
257
258 void sighup(int dummy)
259 {
260 #ifdef ENABLE_SMP
261 if (!pthread_equal( pthread_self(), father_id)) return;
262 #endif
263
264 SET_PTH_SIGFLAG( sighup_flag, 1);
265 }
266
267 void sighup_run()
268 {
269 int i;
270
271 #ifdef ENABLE_SMP
272 if (!pthread_equal( pthread_self(), father_id)) return;
273 #endif
274
275 SET_PTH_SIGFLAG( sighup_flag, 0);
276
277 time(&current_time);
278 log_error_time();
279 fputs("caught SIGHUP, restarting\n", stderr);
280
281 #ifdef ENABLE_SMP
282 /* Kill all threads! */
283
284 for (i=1;i<global_server_params_size;i++) {
285 int ret;
286 if ((ret=pthread_cancel( global_server_params[i].tid)) != 0) {
287 log_error_time();
288 fprintf(stderr, "Could not cancel thread: %d. errno = %d.\n" , (int)global_server_params[i].tid, ret);
289 exit(1);
290 }
291 }
292
293 log_error_time();
294 fputs("Destroyed the pool of threads.\n", stderr);
295
296 for (i=0;i<global_server_params_size;i++) {
297 free_requests( &global_server_params[i]);
298 }
299
300 #endif
301 for (i=0;i<global_server_params_size;i++) {
302 FD_ZERO(&global_server_params[i].block_read_fdset);
303 FD_ZERO(&global_server_params[i].block_write_fdset);
304 }
305
306 /* Philosophy change for 0.92: don't close and attempt reopen of logfiles,
307 * since usual permission structure prevents such reopening.
308 */
309
310 /* clear_common_env(); NEVER DO THIS */
311 dump_mime();
312 dump_passwd();
313 dump_alias();
314
315 log_error_time();
316 fputs("re-reading configuration files\n", stderr);
317 read_config_files();
318
319 /* We now need to dispatch the threads again */
320 smp_reinit();
321
322 log_error_time();
323 fputs("successful restart\n", stderr);
324
325 }
326
327 void sigint(int dummy)
328 {
329 #ifdef ENABLE_SMP
330 if (!pthread_equal( pthread_self(), father_id)) return;
331 #endif
332
333 time(&current_time);
334 log_error_time();
335 fputs("caught SIGINT: shutting down\n", stderr);
336 fclose(stderr);
337 chdir(tempdir);
338 exit(1);
339 }
340
341 void sigchld(int dummy)
342 {
343 SET_PTH_SIGFLAG( sigchld_flag, 1);
344 }
345
346 void sigchld_run(void)
347 {
348 int status;
349 pid_t pid;
350
351 SET_PTH_SIGFLAG( sigchld_flag, 0);
352
353 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
354 if (verbose_cgi_logs) {
355 time(&current_time);
356 log_error_time();
357 fprintf(stderr, "reaping child %d: status %d\n", (int) pid, status);
358 }
359 return;
360 }
361
362 void sigalrm(int dummy)
363 {
364 #ifdef ENABLE_SMP
365 if (!pthread_equal( pthread_self(), father_id)) return;
366 #endif
367
368 SET_PTH_SIGFLAG( sigalrm_flag, 1);
369 }
370
371 void sigusr1(int dummy)
372 {
373 SET_PTH_SIGFLAG( sigusr1_flag, 1);
374 }
375
376 extern int ssl_params_refresh;
377 extern int boa_ssl;
378
379 void sigalrm_run(void)
380 {
381 #ifdef ENABLE_SMP
382 if (!pthread_equal( pthread_self(), father_id)) return;
383 #endif
384
385 SET_PTH_SIGFLAG( sigalrm_flag, 1);
386
387 #ifdef ENABLE_SSL
388 if (boa_ssl)
389 ssl_regenerate_params();
390 #endif
391
392 if (boa_ssl && ssl_params_refresh)
393 alarm( ssl_params_refresh);
394 }
395
396 void sigusr1_run(void)
397 {
398 int i;
399 #ifdef ENABLE_SMP
400 if (!pthread_equal( pthread_self(), father_id)) return;
401 #endif
402
403 SET_PTH_SIGFLAG( sigusr1_flag, 0);
404
405 time(&current_time);
406
407 for (i=0;i<global_server_params_size;i++) {
408 log_error_time();
409 fprintf(stderr, "Thread %d: %ld requests, %ld errors\n",
410 i+1, global_server_params[i].status.requests,
411 global_server_params[i].status.errors);
412 }
413
414 show_hash_stats();
415
416 }
417

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26