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

Contents of /hydra/src/signals.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (show annotations)
Wed Sep 25 19:55:53 2002 UTC (21 years, 6 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_0_2
Changes since 1.7: +4 -2 lines
File MIME type: text/plain
Added support for multiple directory indexes. Droped support for uncompressing gziped files.

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.7 2002/09/25 10:33:19 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 # 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 #ifdef ENABLE_SMP
185 # define SET_LOCAL_PTH_SIGFLAG( flag, val) \
186 { pthread_t tid = pthread_self(); int i; \
187 for (i=0;i<global_server_params_size;i++) { \
188 if ( pthread_equal( global_server_params[i].tid, tid)) { \
189 global_server_params[i].flag = val; \
190 break; \
191 } \
192 } \
193 }
194
195 #else
196 # define SET_LOCAL_PTH_SIGFLAG SET_PTH_SIGFLAG
197 #endif
198
199 void sigterm(int dummy)
200 {
201 SET_PTH_SIGFLAG( sigterm_flag, 1);
202 }
203
204
205 void sigterm_stage1_run() /* lame duck mode */
206 {
207 #ifdef ENABLE_SMP
208 int i;
209 #endif
210
211 time(&current_time);
212 log_error_time();
213 fputs("caught SIGTERM, starting shutdown\n", stderr);
214
215 #ifdef ENABLE_SMP
216 /* remember that the first thread is actual the main process.
217 */
218 for (i=1;i<global_server_params_size;i++) {
219 /* terminate all threads */
220 int ret;
221
222 if ((ret=pthread_cancel( global_server_params[i].tid)) != 0) {
223 log_error_time();
224 fprintf(stderr, "Could not cancel thread: %d. errno = %d.\n" , (int)global_server_params[i].tid, ret);
225 exit(1);
226 }
227 }
228 #endif
229
230 if ( global_server_params[0].server_s[0].socket != -1) {
231 FD_CLR(global_server_params[0].server_s[0].socket, &global_server_params[0].block_read_fdset);
232 close(global_server_params[0].server_s[0].socket);
233 }
234
235 if ( global_server_params[0].server_s[1].socket != -1) {
236 FD_CLR(global_server_params[0].server_s[1].socket, &global_server_params[0].block_read_fdset);
237 close(global_server_params[0].server_s[1].socket);
238 }
239
240 SET_PTH_SIGFLAG( sigterm_flag, 2);
241 }
242
243
244 void sigterm_stage2_run() /* lame duck mode */
245 {
246 int i;
247
248 log_error_time();
249 fprintf(stderr,
250 "exiting Boa normally (uptime %d seconds)\n",
251 (int) (current_time - start_time));
252 chdir(tempdir);
253 clear_common_env();
254 dump_mime();
255 dump_passwd();
256 dump_virthost();
257 dump_directory_index();
258
259 for (i=0;i<global_server_params_size;i++) {
260 free_requests( &global_server_params[i]);
261 }
262
263 exit(0);
264 }
265
266
267 void sighup(int dummy)
268 {
269 SET_PTH_SIGFLAG( sighup_flag, 1);
270 }
271
272 void sighup_run()
273 {
274 int i;
275
276 SET_PTH_SIGFLAG( sighup_flag, 0);
277
278 time(&current_time);
279 log_error_time();
280 fputs("caught SIGHUP, restarting\n", stderr);
281
282 #ifdef ENABLE_SMP
283 /* Kill all threads! */
284
285 for (i=1;i<global_server_params_size;i++) {
286 int ret;
287 if ((ret=pthread_cancel( global_server_params[i].tid)) != 0) {
288 log_error_time();
289 fprintf(stderr, "Could not cancel thread: %d. errno = %d.\n" , (int)global_server_params[i].tid, ret);
290 exit(1);
291 }
292 }
293
294 log_error_time();
295 fputs("Destroyed the pool of threads.\n", stderr);
296
297 for (i=0;i<global_server_params_size;i++) {
298 free_requests( &global_server_params[i]);
299 }
300
301 #endif
302 for (i=0;i<global_server_params_size;i++) {
303 FD_ZERO(&global_server_params[i].block_read_fdset);
304 FD_ZERO(&global_server_params[i].block_write_fdset);
305 }
306
307 /* Philosophy change for 0.92: don't close and attempt reopen of logfiles,
308 * since usual permission structure prevents such reopening.
309 */
310
311 /* clear_common_env(); NEVER DO THIS */
312 dump_mime();
313 dump_passwd();
314 dump_virthost();
315 dump_directory_index();
316
317 log_error_time();
318 fputs("re-reading configuration files\n", stderr);
319 read_config_files();
320
321 /* We now need to dispatch the threads again */
322 smp_reinit();
323 mmap_reinit();
324
325 log_error_time();
326 fputs("successful restart\n", stderr);
327
328 }
329
330 void sigint(int dummy)
331 {
332 time(&current_time);
333 log_error_time();
334 fputs("caught SIGINT: shutting down\n", stderr);
335 fclose(stderr);
336 chdir(tempdir);
337 exit(1);
338 }
339
340 void sigchld(int dummy)
341 {
342 SET_LOCAL_PTH_SIGFLAG( sigchld_flag, 1);
343 }
344
345 void sigchld_run(void)
346 {
347 int status;
348 pid_t pid;
349
350 SET_LOCAL_PTH_SIGFLAG( sigchld_flag, 0);
351
352 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
353 if (verbose_cgi_logs) {
354 time(&current_time);
355 log_error_time();
356 fprintf(stderr, "reaping child %d: status %d\n", (int) pid, status);
357 }
358 return;
359 }
360
361 void sigalrm(int dummy)
362 {
363 SET_PTH_SIGFLAG( sigalrm_flag, 1);
364 }
365
366 void sigusr1(int dummy)
367 {
368 SET_PTH_SIGFLAG( sigusr1_flag, 1);
369 }
370
371 extern int ssl_params_refresh;
372 extern int boa_ssl;
373
374 void sigalrm_run(void)
375 {
376 SET_PTH_SIGFLAG( sigalrm_flag, 0);
377
378 #ifdef ENABLE_SSL
379 if (boa_ssl)
380 ssl_regenerate_params();
381 #endif
382
383 if (boa_ssl && ssl_params_refresh)
384 alarm( ssl_params_refresh);
385 }
386
387 void sigusr1_run(void)
388 {
389 int i;
390
391 SET_PTH_SIGFLAG( sigusr1_flag, 0);
392
393 time(&current_time);
394
395 for (i=0;i<global_server_params_size;i++) {
396 log_error_time();
397 fprintf(stderr, "Thread %d: %ld requests, %ld errors\n",
398 i+1, global_server_params[i].status.requests,
399 global_server_params[i].status.errors);
400 }
401
402 show_hash_stats();
403
404 }
405

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26