/* ************************************************************************
* File: signals.c Part of CircleMUD *
* Usage: Signal trapping and signal handlers *
* *
* All rights reserved. See license.doc for complete information. *
* *
* Copyright (C) 1993 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
************************************************************************ */
/* Archipelago changes by Alastair J. Neil Copyright (C) 1993, 94, 95, 96 */
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "structs.h"
#include "utils.h"
extern struct descriptor_data *descriptor_list;
extern int mother_desc;
void checkpointing();
void logsig();
void hupsig();
void badcrash();
void unrestrict_game();
void reread_wizlists();
int graceful_tried = 0;
void signal_setup(void)
{
struct itimerval itime;
struct timeval interval;
signal(SIGUSR1, reread_wizlists);
signal(SIGUSR2, unrestrict_game);
/* just to be on the safe side: */
signal(SIGHUP, hupsig);
signal(SIGPIPE, SIG_IGN);
signal(SIGINT, hupsig);
signal(SIGALRM, logsig);
signal(SIGTERM, hupsig);
signal(SIGBUS, badcrash);
#ifndef ESSENCE
signal(SIGSEGV, badcrash);
/* set up the deadlock-protection */
interval.tv_sec = 900; /* 15 minutes */
interval.tv_usec = 0;
itime.it_interval = interval;
itime.it_value = interval;
setitimer(ITIMER_VIRTUAL, &itime, 0);
signal(SIGVTALRM, checkpointing);
#endif
}
void checkpointing(void)
{
extern int tics;
if (!tics) {
logg("CHECKPOINT shutdown: tics not updated");
abort();
} else
tics = 0;
}
void reread_wizlists()
{
void reboot_wizlists(void);
signal(SIGUSR1, reread_wizlists);
mudlog("Rereading wizlists.", CMP, LEVEL_BUILDER, FALSE);
reboot_wizlists();
}
void unrestrict_game()
{
extern int restrict;
extern struct ban_list_element *ban_list;
extern int num_invalid;
signal(SIGUSR2, unrestrict_game);
mudlog("Received SIGUSR2 - unrestricting game (emergent)",
BRF, LEVEL_BUILDER, TRUE);
ban_list = 0;
restrict = 0;
}
/* kick out players etc */
void hupsig(void)
{
logg("Received SIGHUP, SIGINT, or SIGTERM. Shutting down...");
exit(0); /* something more elegant should perhaps be substituted */
}
void badcrash(void)
{
void close_socket(struct descriptor_data *d);
struct rlimit limit;
int old_core_limit;
struct descriptor_data *desc;
logg("SIGSEGV or SIGBUS received. Trying to shut down gracefully.");
if (!graceful_tried) {
graceful_tried = 1;
/* prevent us from generating a second core for debugging reasons */
getrlimit(RLIMIT_CORE, &limit);
old_core_limit = limit.rlim_cur;
limit.rlim_cur = 0;
setrlimit(RLIMIT_CORE, &limit);
close(mother_desc);
logg("Trying to close all sockets.");
for (desc = descriptor_list; desc; desc = desc->next)
close(desc->descriptor);
limit.rlim_cur = old_core_limit;
setrlimit(RLIMIT_CORE, &limit);
}
abort();
}
void logsig(void)
{
logg("Signal received. Ignoring.");
}