/*
// ColdMUD was created and is copyright 1993, 1994 by Greg Hudson
//
// ColdX is a derivitive work, and is copyright 1995 by the ColdX Project.
// Full copyright information can be found in the file doc/CREDITS
//
// File: sig.c
// Version: 0.1-5
// Last Edited: 18 May 1995
//
// ---
//
// Coldmud signal handling.
*/
#define _POSIX_SOURCE
#include "config.h"
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "defs.h"
#include "sig.h"
#include "log.h" /* write_err() */
#include "execute.h" /* task() */
#include "cmstring.h" /* string_from_chars() */
#include "data.h"
#include "x.tab.h"
#include "main.h"
void catch_SIGCHLD(int sig);
void uninit_sig(void) {
signal(SIGFPE, SIG_DFL);
signal(SIGILL, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGHUP, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGALRM, SIG_DFL);
signal(SIGUSR1, SIG_DFL);
signal(SIGUSR2, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
}
void init_sig(void) {
signal(SIGFPE, catch_signal);
signal(SIGILL, catch_signal);
signal(SIGQUIT, catch_signal);
#if 0
signal(SIGSEGV, catch_signal);
#endif
signal(SIGINT, catch_signal);
signal(SIGHUP, catch_signal);
signal(SIGTERM, catch_signal);
signal(SIGALRM, catch_signal);
signal(SIGUSR1, catch_signal);
signal(SIGUSR2, catch_signal);
signal(SIGCHLD, catch_SIGCHLD);
}
void catch_SIGCHLD(int sig) {
waitpid(-1, NULL, WNOHANG);
#ifdef SYSV /* BSD signals shouldn't need this, could be wrong though */
signal(SIGCHLD, catch_SIGCHLD);
#endif
}
char *sig_name(int sig) {
char buf[10];
switch(sig) {
case SIGFPE: return "SIGFPE";
case SIGILL: return "SIGILL";
case SIGQUIT: return "SIGQUIT";
case SIGSEGV: return "SIGSEGV";
case SIGINT: return "SIGINT";
case SIGHUP: return "SIGHUP";
case SIGTERM: return "SIGTERM";
case SIGALRM: return "SIGALRM";
case SIGUSR1: return "SIGUSR1";
case SIGUSR2: return "SIGUSR2";
default: return "Unknown";
}
return NULL;
}
/* void catch_signal(int sig, int code, struct sigcontext *scp) { */
void catch_signal(int sig) {
char *sptr;
String *sigstr;
Data arg1, arg2;
sptr = sig_name(sig);
sigstr = string_from_chars(sptr, strlen(sptr));
write_err("Caught signal %d: %S", sig, sigstr);
/* send a message to the system object */
arg1.type = SYMBOL;
arg1.u.symbol = ident_get(sig_name(sig));
arg2.type = STRING;
arg2.u.str = sigstr;
task(NULL, SYSTEM_DBREF, signal_id, 2, &arg1, &arg2);
/* figure out what to do */
switch(sig) {
case SIGUSR1:
case SIGUSR2:
case SIGHUP:
case SIGALRM:
/* let the server do what it wants, don't shutdown */
break;
case SIGILL:
case SIGFPE:
case SIGSEGV:
/* lets panic and hopefully dump */
panic(sig_name(sig));
break;
case SIGINT:
case SIGQUIT:
case SIGTERM:
default: /* shutdown nicely */
if (running) {
write_err("*** Attempting normal shutdown ***");
running = 0;
} else {
panic(sig_name(sig));
}
break;
}
#ifdef SYSV /* BSD signals shouldn't need this, could be wrong though */
signal(sig, catch_signal);
#endif
}