232 lines
5.1 KiB
C
232 lines
5.1 KiB
C
/*
|
|
* Boa, an http server
|
|
* Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
|
|
* Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
|
|
* Some changes Copyright (C) 1996-99 Jon Nelson <jnelson@boa.org>
|
|
* Some changes Copyright (C) 1997 Alain Magloire <alain.magloire@rcsm.ee.mcgill.ca>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 1, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
*/
|
|
|
|
/* $Id: signals.c,v 1.37.2.2 2002/07/23 16:03:41 jnelson Exp $*/
|
|
|
|
#include "boa.h"
|
|
#ifdef HAVE_SYS_WAIT_H
|
|
#include <sys/wait.h> /* wait */
|
|
#endif
|
|
#include <signal.h> /* signal */
|
|
|
|
sigjmp_buf env;
|
|
int handle_sigbus;
|
|
|
|
void sigsegv(int);
|
|
void sigbus(int);
|
|
void sigterm(int);
|
|
void sighup(int);
|
|
void sigint(int);
|
|
void sigchld(int);
|
|
void sigalrm(int);
|
|
|
|
/*
|
|
* Name: init_signals
|
|
* Description: Sets up signal handlers for all our friends.
|
|
*/
|
|
|
|
void init_signals(void)
|
|
{
|
|
struct sigaction sa;
|
|
|
|
sa.sa_flags = 0;
|
|
|
|
sigemptyset(&sa.sa_mask);
|
|
sigaddset(&sa.sa_mask, SIGSEGV);
|
|
sigaddset(&sa.sa_mask, SIGBUS);
|
|
sigaddset(&sa.sa_mask, SIGTERM);
|
|
sigaddset(&sa.sa_mask, SIGHUP);
|
|
sigaddset(&sa.sa_mask, SIGINT);
|
|
sigaddset(&sa.sa_mask, SIGPIPE);
|
|
sigaddset(&sa.sa_mask, SIGCHLD);
|
|
sigaddset(&sa.sa_mask, SIGALRM);
|
|
sigaddset(&sa.sa_mask, SIGUSR1);
|
|
sigaddset(&sa.sa_mask, SIGUSR2);
|
|
|
|
sa.sa_handler = sigsegv;
|
|
sigaction(SIGSEGV, &sa, NULL);
|
|
|
|
sa.sa_handler = sigbus;
|
|
sigaction(SIGBUS, &sa, NULL);
|
|
|
|
sa.sa_handler = sigterm;
|
|
sigaction(SIGTERM, &sa, NULL);
|
|
|
|
sa.sa_handler = sighup;
|
|
sigaction(SIGHUP, &sa, NULL);
|
|
|
|
sa.sa_handler = sigint;
|
|
sigaction(SIGINT, &sa, NULL);
|
|
|
|
sa.sa_handler = SIG_IGN;
|
|
sigaction(SIGPIPE, &sa, NULL);
|
|
|
|
sa.sa_handler = sigchld;
|
|
sigaction(SIGCHLD, &sa, NULL);
|
|
|
|
sa.sa_handler = sigalrm;
|
|
sigaction(SIGALRM, &sa, NULL);
|
|
|
|
sa.sa_handler = SIG_IGN;
|
|
sigaction(SIGUSR1, &sa, NULL);
|
|
|
|
sa.sa_handler = SIG_IGN;
|
|
sigaction(SIGUSR2, &sa, NULL);
|
|
}
|
|
|
|
void sigsegv(int dummy)
|
|
{
|
|
time(¤t_time);
|
|
log_error_time();
|
|
fprintf(stderr, "caught SIGSEGV, dumping core in %s\n", tempdir);
|
|
fclose(stderr);
|
|
chdir(tempdir);
|
|
abort();
|
|
}
|
|
|
|
extern sigjmp_buf env;
|
|
extern int handle_sigbus;
|
|
|
|
void sigbus(int dummy)
|
|
{
|
|
if (handle_sigbus) {
|
|
longjmp(env, dummy);
|
|
}
|
|
time(¤t_time);
|
|
log_error_time();
|
|
fprintf(stderr, "caught SIGBUS, dumping core in %s\n", tempdir);
|
|
fclose(stderr);
|
|
chdir(tempdir);
|
|
abort();
|
|
}
|
|
|
|
void sigterm(int dummy)
|
|
{
|
|
sigterm_flag = 1;
|
|
}
|
|
|
|
void sigterm_stage1_run(int server_s) /* lame duck mode */
|
|
{
|
|
time(¤t_time);
|
|
log_error_time();
|
|
fputs("caught SIGTERM, starting shutdown\n", stderr);
|
|
FD_CLR(server_s, &block_read_fdset);
|
|
close(server_s);
|
|
sigterm_flag = 2;
|
|
}
|
|
|
|
void sigterm_stage2_run() /* lame duck mode */
|
|
{
|
|
log_error_time();
|
|
fprintf(stderr,
|
|
"exiting Boa normally (uptime %d seconds)\n",
|
|
(int) (current_time - start_time));
|
|
chdir(tempdir);
|
|
clear_common_env();
|
|
dump_mime();
|
|
dump_passwd();
|
|
dump_alias();
|
|
free_requests();
|
|
exit(0);
|
|
}
|
|
|
|
|
|
void sighup(int dummy)
|
|
{
|
|
sighup_flag = 1;
|
|
}
|
|
|
|
void sighup_run(void)
|
|
{
|
|
sighup_flag = 0;
|
|
time(¤t_time);
|
|
log_error_time();
|
|
fputs("caught SIGHUP, restarting\n", stderr);
|
|
|
|
/* Philosophy change for 0.92: don't close and attempt reopen of logfiles,
|
|
* since usual permission structure prevents such reopening.
|
|
*/
|
|
|
|
FD_ZERO(&block_read_fdset);
|
|
FD_ZERO(&block_write_fdset);
|
|
/* clear_common_env(); NEVER DO THIS */
|
|
dump_mime();
|
|
dump_passwd();
|
|
dump_alias();
|
|
free_requests();
|
|
|
|
log_error_time();
|
|
fputs("re-reading configuration files\n", stderr);
|
|
read_config_files();
|
|
|
|
log_error_time();
|
|
fputs("successful restart\n", stderr);
|
|
|
|
}
|
|
|
|
void sigint(int dummy)
|
|
{
|
|
time(¤t_time);
|
|
log_error_time();
|
|
fputs("caught SIGINT: shutting down\n", stderr);
|
|
fclose(stderr);
|
|
chdir(tempdir);
|
|
exit(1);
|
|
}
|
|
|
|
void sigchld(int dummy)
|
|
{
|
|
sigchld_flag = 1;
|
|
}
|
|
|
|
void sigchld_run(void)
|
|
{
|
|
int status;
|
|
pid_t pid;
|
|
|
|
sigchld_flag = 0;
|
|
|
|
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
|
if (verbose_cgi_logs) {
|
|
time(¤t_time);
|
|
log_error_time();
|
|
fprintf(stderr, "reaping child %d: status %d\n", (int) pid, status);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void sigalrm(int dummy)
|
|
{
|
|
sigalrm_flag = 1;
|
|
}
|
|
|
|
void sigalrm_run(void)
|
|
{
|
|
time(¤t_time);
|
|
log_error_time();
|
|
fprintf(stderr, "%ld requests, %ld errors\n",
|
|
status.requests, status.errors);
|
|
show_hash_stats();
|
|
sigalrm_flag = 0;
|
|
}
|