/* // 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 }