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

Contents of /hydra/src/signals.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.17 - (show annotations)
Mon Sep 30 18:34:40 2002 UTC (21 years, 6 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_0_6, hydra_0_0_4, hydra_0_0_5
Changes since 1.16: +13 -3 lines
File MIME type: text/plain
*** empty log message ***

1 /*
2 * Hydra, 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.16 2002/09/30 17:16:54 nmav 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 extern pthread_t father_id;
36 #endif
37
38 void sigsegv(int);
39 void sigbus(int);
40 void sigterm(int);
41 void sighup(int);
42 void sigint(int);
43 void sigchld(int);
44 void sigalrm(int);
45 void sigusr1(int);
46 void sigusr2(int); /* needed in HIC thread */
47
48 /*
49 * Name: init_signals
50 * Description: Sets up signal handlers for all our friends.
51 */
52
53 void init_signals(void)
54 {
55 struct sigaction sa;
56
57 sa.sa_flags = 0;
58
59 sigemptyset(&sa.sa_mask);
60 sigaddset(&sa.sa_mask, SIGSEGV);
61 sigaddset(&sa.sa_mask, SIGBUS);
62 sigaddset(&sa.sa_mask, SIGTERM);
63 sigaddset(&sa.sa_mask, SIGHUP);
64 sigaddset(&sa.sa_mask, SIGINT);
65 sigaddset(&sa.sa_mask, SIGPIPE);
66 sigaddset(&sa.sa_mask, SIGCHLD);
67 sigaddset(&sa.sa_mask, SIGALRM);
68 sigaddset(&sa.sa_mask, SIGUSR1);
69 sigaddset(&sa.sa_mask, SIGUSR2);
70
71 sa.sa_handler = sigsegv;
72 sigaction(SIGSEGV, &sa, NULL);
73
74 sa.sa_handler = sigbus;
75 sigaction(SIGBUS, &sa, NULL);
76
77 sa.sa_handler = SIG_IGN;
78 sigaction(SIGPIPE, &sa, NULL);
79
80 sa.sa_handler = sigchld;
81 sigaction(SIGCHLD, &sa, NULL);
82
83 sa.sa_handler = sigterm;
84 sigaction(SIGTERM, &sa, NULL);
85
86 sa.sa_handler = sighup;
87 sigaction(SIGHUP, &sa, NULL);
88
89 sa.sa_handler = sigint;
90 sigaction(SIGINT, &sa, NULL);
91
92 sa.sa_handler = sigalrm;
93 sigaction(SIGALRM, &sa, NULL);
94
95 sa.sa_handler = sigusr1;
96 sigaction(SIGUSR1, &sa, NULL);
97
98 sa.sa_handler = sigusr2;
99 sigaction(SIGUSR2, &sa, NULL);
100 }
101
102 /* Blocks all signals that should be handled by
103 * the main thread, so that other threads are
104 * not annoyed.
105 */
106 void block_main_signals()
107 {
108 sigset_t sigset;
109
110 sigemptyset(&sigset);
111 sigaddset(&sigset, SIGALRM);
112 sigaddset(&sigset, SIGUSR1);
113 sigaddset(&sigset, SIGUSR2);
114 sigaddset(&sigset, SIGTERM);
115 sigaddset(&sigset, SIGHUP);
116 sigaddset(&sigset, SIGINT);
117
118 sigprocmask(SIG_BLOCK, &sigset, NULL);
119 }
120
121 void unblock_main_signals()
122 {
123 sigset_t sigset;
124
125 sigemptyset(&sigset);
126 sigaddset(&sigset, SIGALRM);
127 sigaddset(&sigset, SIGUSR1);
128 sigaddset(&sigset, SIGUSR2);
129 sigaddset(&sigset, SIGTERM);
130 sigaddset(&sigset, SIGHUP);
131 sigaddset(&sigset, SIGINT);
132
133 sigprocmask(SIG_UNBLOCK, &sigset, NULL);
134 }
135
136 void block_sigusr2()
137 {
138 sigset_t sigset;
139
140 sigemptyset(&sigset);
141 sigaddset(&sigset, SIGUSR2);
142
143 sigprocmask(SIG_BLOCK, &sigset, NULL);
144 }
145
146 void unblock_sigusr2()
147 {
148 sigset_t sigset;
149
150 sigemptyset(&sigset);
151 sigaddset(&sigset, SIGUSR2);
152
153 sigprocmask(SIG_UNBLOCK, &sigset, NULL);
154 }
155
156
157 void sigsegv(int dummy)
158 {
159 time(&current_time);
160 log_error_time();
161 fprintf(stderr, "caught SIGSEGV, dumping core in %s\n", tempdir);
162 fclose(stderr);
163 chdir(tempdir);
164 abort();
165 }
166
167 void sigbus(int dummy)
168 {
169 server_params *params = &global_server_params[0];
170
171 /* Note that in multithreaded cases the SIGBUS is catched
172 * by the same thread that did the violation. So the following
173 * code should be ok.
174 */
175
176 #ifdef ENABLE_SMP
177 pthread_t tid = pthread_self();
178 int i;
179
180 for (i = 0; i < global_server_params_size; i++) {
181 if (pthread_equal(global_server_params[i].tid, tid)) {
182 params = &global_server_params[i];
183 break;
184 }
185 }
186 #endif
187
188 if (params->handle_sigbus) {
189 longjmp(params->env, dummy);
190 }
191 time(&current_time);
192 log_error_time();
193 fprintf(stderr, "caught SIGBUS, dumping core in %s\n", tempdir);
194 fclose(stderr);
195 chdir(tempdir);
196 abort();
197 }
198
199 #define SET_PTH_SIGFLAG( flag, val) \
200 global_server_params[0].flag = val
201
202 #ifdef ENABLE_SMP
203 # define _SET_LOCAL_PTH_SIGFLAG( flag, val) \
204 { pthread_t tid = pthread_self(); int i; int set = 0; \
205 for (i=0;i<global_server_params_size;i++) { \
206 if ( pthread_equal( global_server_params[i].tid, tid)) { \
207 global_server_params[i].flag = val; \
208 set = 1; \
209 break; \
210 } \
211 }
212
213 # ifdef ENABLE_HIC
214 # define SET_LOCAL_PTH_SIGFLAG( flag, val) \
215 _SET_LOCAL_PTH_SIGFLAG( flag, val) \
216 \
217 if (!set) { /* try hic threads */ \
218 for (i=0;i<global_hic_params_size;i++) { \
219 if ( pthread_equal( global_hic_params[i].tid, tid)) { \
220 global_hic_params[i].flag = val; \
221 break; \
222 } \
223 } \
224 } \
225 }
226 # else
227
228 # define SET_LOCAL_PTH_SIGFLAG( flag, val) \
229 _SET_LOCAL_PTH_SIGFLAG( flag, val) }
230
231 # endif
232
233 #else
234 # define SET_LOCAL_PTH_SIGFLAG SET_PTH_SIGFLAG
235 #endif
236
237 void sigterm(int dummy)
238 {
239 SET_PTH_SIGFLAG(sigterm_flag, 1);
240 }
241
242
243 void sigterm_stage1_run()
244 { /* lame duck mode */
245 #ifdef ENABLE_SMP
246 int i;
247 #endif
248
249 time(&current_time);
250 log_error_time();
251 fputs("caught SIGTERM, starting shutdown\n", stderr);
252
253 #ifdef ENABLE_SMP
254 {
255 int ret;
256 /* remember that the first thread is actual the main process.
257 */
258 for (i = 1; i < global_server_params_size; i++) {
259 /* terminate all threads */
260 if ((ret = pthread_cancel(global_server_params[i].tid)) != 0) {
261 log_error_time();
262 fprintf(stderr, "Could not cancel thread: %d. errno = %d.\n",
263 (int) global_server_params[i].tid, ret);
264 exit(1);
265 }
266 }
267
268 # ifdef ENABLE_HIC
269 for (i = 0; i < global_hic_params_size; i++) {
270 if ((ret = pthread_cancel(global_hic_params[i].tid)) != 0) {
271 log_error_time();
272 fprintf(stderr, "Could not cancel thread: %d. errno = %d.\n",
273 (int) global_hic_params[i].tid, ret);
274 exit(1);
275 }
276 }
277 # endif
278 }
279 #endif
280
281 if (global_server_params[0].server_s[0].socket != -1) {
282 FD_CLR(global_server_params[0].server_s[0].socket,
283 &global_server_params[0].block_read_fdset);
284 close(global_server_params[0].server_s[0].socket);
285 }
286
287 if (global_server_params[0].server_s[1].socket != -1) {
288 FD_CLR(global_server_params[0].server_s[1].socket,
289 &global_server_params[0].block_read_fdset);
290 close(global_server_params[0].server_s[1].socket);
291 }
292
293 SET_PTH_SIGFLAG(sigterm_flag, 2);
294 }
295
296
297 void sigterm_stage2_run()
298 { /* lame duck mode */
299 int i;
300
301 log_error_time();
302 fprintf(stderr,
303 "exiting Hydra normally (uptime %d seconds)\n",
304 (int) (current_time - start_time));
305 chdir(tempdir);
306 clear_common_env();
307 dump_mime();
308 dump_passwd();
309 dump_virthost();
310 dump_directory_index();
311 dump_hic_modules();
312
313 for (i = 0; i < global_server_params_size; i++) {
314 free_requests(&global_server_params[i]);
315 }
316
317 exit(0);
318 }
319
320
321 void sighup(int dummy)
322 {
323 SET_PTH_SIGFLAG(sighup_flag, 1);
324 }
325
326 void sighup_run()
327 {
328 int i;
329
330 SET_PTH_SIGFLAG(sighup_flag, 0);
331
332 time(&current_time);
333 log_error_time();
334 fputs("caught SIGHUP, restarting\n", stderr);
335
336 #ifdef ENABLE_SMP
337 /* Kill all threads! */
338 {
339 int ret;
340
341 for (i = 1; i < global_server_params_size; i++) {
342 if ((ret = pthread_cancel(global_server_params[i].tid)) != 0) {
343 log_error_time();
344 fprintf(stderr, "Could not cancel thread: %d. errno = %d.\n",
345 (int) global_server_params[i].tid, ret);
346 exit(1);
347 }
348 }
349 log_error_time();
350 fputs("Cancelled all the threads in the pool.\n", stderr);
351
352 # ifdef ENABLE_HIC
353 for (i = 0; i < global_hic_params_size; i++) {
354 if ((ret = pthread_cancel(global_hic_params[i].tid)) != 0) {
355 log_error_time();
356 fprintf(stderr, "Could not cancel thread: %d. errno = %d.\n",
357 (int) global_hic_params[i].tid, ret);
358 exit(1);
359 }
360 }
361
362 log_error_time();
363 fputs("Cancelled all the HIC threads.\n", stderr);
364 # endif
365
366 }
367
368 for (i = 0; i < global_server_params_size; i++) {
369 free_requests(&global_server_params[i]);
370 }
371
372 #endif
373 for (i = 0; i < global_server_params_size; i++) {
374 FD_ZERO(&global_server_params[i].block_read_fdset);
375 FD_ZERO(&global_server_params[i].block_write_fdset);
376 }
377
378 /* Philosophy change for 0.92: don't close and attempt reopen of logfiles,
379 * since usual permission structure prevents such reopening.
380 */
381
382 /* clear_common_env(); NEVER DO THIS */
383 dump_mime();
384 dump_passwd();
385 dump_virthost();
386 dump_directory_index();
387 dump_hic_modules();
388
389 log_error_time();
390 fputs("re-reading configuration files\n", stderr);
391 read_config_files();
392
393 /* We now need to dispatch the threads again */
394 #ifdef ENABLE_HIC
395 hic_init();
396 #endif
397 smp_reinit();
398 mmap_reinit();
399
400 log_error_time();
401 fputs("successful restart\n", stderr);
402
403 }
404
405 void sigint(int dummy)
406 {
407 time(&current_time);
408 log_error_time();
409 fputs("caught SIGINT: shutting down\n", stderr);
410 fclose(stderr);
411 chdir(tempdir);
412 exit(1);
413 }
414
415 void sigchld(int dummy)
416 {
417 SET_LOCAL_PTH_SIGFLAG(sigchld_flag, 1);
418 }
419
420 void sigchld_run(void)
421 {
422 int status;
423 pid_t pid;
424
425 SET_LOCAL_PTH_SIGFLAG(sigchld_flag, 0);
426
427 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
428 if (verbose_cgi_logs) {
429 time(&current_time);
430 log_error_time();
431 fprintf(stderr, "reaping child %d: status %d\n", (int) pid,
432 status);
433 }
434 return;
435 }
436
437 void sigalrm(int dummy)
438 {
439 SET_PTH_SIGFLAG(sigalrm_flag, 1);
440 }
441
442 void sigusr2(int dummy)
443 {
444 return;
445 }
446
447 void sigusr1(int dummy)
448 {
449 SET_PTH_SIGFLAG(sigusr1_flag, 1);
450 }
451
452 extern int ssl_params_refresh;
453 extern int boa_ssl;
454
455 void sigalrm_run(void)
456 {
457 SET_PTH_SIGFLAG(sigalrm_flag, 0);
458
459 #ifdef ENABLE_SSL
460 if (boa_ssl)
461 ssl_regenerate_params();
462 #endif
463
464 if (boa_ssl && ssl_params_refresh)
465 alarm(ssl_params_refresh);
466 }
467
468 void sigusr1_run(void)
469 {
470 int i;
471
472 SET_PTH_SIGFLAG(sigusr1_flag, 0);
473
474 time(&current_time);
475
476 for (i = 0; i < global_server_params_size; i++) {
477 log_error_time();
478 fprintf(stderr, "Thread %d: %ld requests, %ld errors\n",
479 i + 1, global_server_params[i].status.requests,
480 global_server_params[i].status.errors);
481 }
482
483 show_hash_stats();
484
485 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26