src/signal.c File Reference

#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include "debug.h"
#include "mudconf.h"
#include "externs.h"
#include "flags.h"

Include dependency graph for signal.c:

Go to the source code of this file.

Defines

#define ALT_STACK_SIZE   (0x40000)
#define ALT_STACK_ALIGN   (0x1000)

Functions

void signal_TERM (int, siginfo_t *, void *)
void signal_PIPE (int, siginfo_t *, void *)
void signal_USR1 (int, siginfo_t *, void *)
void signal_SEGV (int, siginfo_t *, void *)
void signal_BUS (int, siginfo_t *, void *)
void bind_signals ()
void unbind_signals ()

Variables

sigaction saTERM
sigaction saPIPE
sigaction saUSR1
sigaction saSEGV
sigaction saBUS
stack_t sighandler_stack
stack_t regular_stack


Define Documentation

#define ALT_STACK_ALIGN   (0x1000)

Definition at line 52 of file signal.c.

Referenced by bind_signals().

#define ALT_STACK_SIZE   (0x40000)

Definition at line 51 of file signal.c.

Referenced by bind_signals().


Function Documentation

void bind_signals (  ) 

Definition at line 54 of file signal.c.

References ALT_STACK_ALIGN, ALT_STACK_SIZE, dperror, dprintk, log_error(), LOG_PROBLEMS, posix_memalign(), regular_stack, saBUS, saSEGV, saTERM, saUSR1, and sighandler_stack.

Referenced by main().

00055 {
00056     int error_code;
00057     dprintk("creating alternate signal stack.");
00058 #ifdef HAVE_POSIX_MEMALIGN
00059     error_code = posix_memalign(&sighandler_stack.ss_sp, ALT_STACK_ALIGN,
00060             ALT_STACK_SIZE);
00061 #else 
00062     sighandler_stack.ss_sp = malloc(ALT_STACK_SIZE);
00063     if(sighandler_stack.ss_sp != 0) error_code = 0;
00064 #endif
00065     if(error_code == 0) {
00066         sighandler_stack.ss_size = ALT_STACK_SIZE;
00067         sighandler_stack.ss_flags = 0;
00068         memset(sighandler_stack.ss_sp, 0, ALT_STACK_SIZE);
00069         dperror(sigaltstack(&sighandler_stack, &regular_stack) <0);
00070         dprintk("Current stack at 0x%x with length 0x%x and flags 0x%x", 
00071                 (unsigned int)regular_stack.ss_sp, regular_stack.ss_size, regular_stack.ss_flags);
00072         dprintk("Signal stack at 0x%x with length 0x%x and flags 0x%x", 
00073                 (unsigned int)sighandler_stack.ss_sp, sighandler_stack.ss_size, sighandler_stack.ss_flags);
00074         saSEGV.sa_flags |= SA_ONSTACK;
00075         saBUS.sa_flags |= SA_ONSTACK;
00076     } else {
00077         dprintk("posix_memalign failed with %s", strerror(error_code));
00078         log_error(LOG_PROBLEMS, "SIG", "ERR", 
00079                 "posix_memalign() failed with error %s, alternate stack not used.",
00080                 strerror(error_code));
00081         log_error(LOG_PROBLEMS, "SIG", "ERR", 
00082                 "running signal_handlers without sigaltstack() will corrupt your coredumps!");
00083         sighandler_stack.ss_sp = NULL;
00084     }
00085     dprintk("binding signals.");
00086     dperror(sigaction(SIGTERM, &saTERM, NULL) <0);
00087 //      sigaction(SIGPIPE, &saPIPE, NULL);
00088         sigaction(SIGUSR1, &saUSR1, NULL);
00089         sigaction(SIGSEGV, &saSEGV, NULL);
00090         sigaction(SIGBUS, &saBUS, NULL);
00091     signal(SIGCHLD, SIG_IGN);
00092     signal(SIGPIPE, SIG_IGN);
00093     dprintk("done.");
00094 }

void signal_BUS ( int  ,
siginfo_t *  ,
void *   
)

Definition at line 174 of file signal.c.

References confdata::config_file, dprintk, DUMP_CRASHED, dump_database_internal(), dump_restart_db(), statedata::executable_path, mudconf, mudstate, mux_release_socket(), raw_broadcast(), report(), SA_EXIT, and confdata::sig_action.

00175 {
00176     dprintk("caught SIGBUS");
00177         int child;
00178     mux_release_socket();
00179         if(mudconf.sig_action != SA_EXIT && !(child = fork())) {
00180                 dump_restart_db();
00181                 execl(mudstate.executable_path, mudstate.executable_path,
00182                           mudconf.config_file, NULL);
00183         } else {
00184                 switch (siginfo->si_code) {
00185                 case BUS_ADRALN:
00186                         raw_broadcast(0,
00187                                                   "Game: Invalid address alignment accessing %p. Restarting from Checkpoint.",
00188                                                   siginfo->si_addr);
00189                         break;
00190                 case BUS_ADRERR:
00191                         raw_broadcast(0,
00192                                                   "Game: Invalid access of non-existent physical memory at %p. Restarting from Checkpoint.",
00193                                                   siginfo->si_addr);
00194                         break;
00195                 case BUS_OBJERR:
00196                         raw_broadcast(0,
00197                                                   "Game: Invalid object specific hardware error access at %p. Restarting from Checkpoint.",
00198                                                   siginfo->si_addr);
00199                         break;
00200                 default:
00201                         raw_broadcast(0,
00202                                                   "Game: Unhandled SEGV at %p. Restarting from checkpoint.",
00203                                                   siginfo->si_addr);
00204                         break;
00205                 }
00206                 dump_database_internal(DUMP_CRASHED);
00207                 report();
00208         }
00209 }

void signal_PIPE ( int  ,
siginfo_t *  ,
void *   
)

Definition at line 120 of file signal.c.

References dprintk, and eradicate_broken_fd().

00121 {
00122     dprintk("caught SIGPIPE");
00123 #ifdef HAVE_SIGINFO_T_SI_FD
00124         eradicate_broken_fd(siginfo->si_fd);
00125 #else
00126         eradicate_broken_fd(-1);
00127 #endif
00128 }

void signal_SEGV ( int  ,
siginfo_t *  ,
void *   
)

Definition at line 137 of file signal.c.

References confdata::config_file, dprintk, DUMP_CRASHED, dump_database_internal(), dump_restart_db(), statedata::executable_path, mudconf, mudstate, mux_release_socket(), raw_broadcast(), and report().

00138 {
00139     dprintk("caught SIGSEGV");
00140         int child;
00141     mux_release_socket();
00142         if(!(child = fork())) {
00143         sleep(1); // hag 20060404
00144                   // not sure if its necessary but I'm worried about
00145                   // a race.
00146         dprintk("(forked child) dumping restart database");
00147                 dump_restart_db();
00148         dprintk("(forked child) execing new copy of game.");
00149                 execl(mudstate.executable_path, mudstate.executable_path,
00150                           mudconf.config_file, NULL);
00151         } else {
00152                 switch (siginfo->si_code) {
00153                 case SEGV_MAPERR:
00154                         raw_broadcast(0,
00155                                                   "Game: Invalid access of unamapped memory at %p. Restarting from Checkpoint.",
00156                                                   siginfo->si_addr);
00157                         break;
00158                 case SEGV_ACCERR:
00159                         raw_broadcast(0,
00160                                                   "Game: Invalid access of protected memory at %p. Restarting from Checkpoint.",
00161                                                   siginfo->si_addr);
00162                         break;
00163                 default:
00164                         raw_broadcast(0,
00165                                                   "Game: Unhandled SEGV at %p. Restarting from checkpoint.",
00166                                                   siginfo->si_addr);
00167                         break;
00168                 }
00169                 dump_database_internal(DUMP_CRASHED);
00170                 report();
00171         }
00172 }

void signal_TERM ( int  ,
siginfo_t *  ,
void *   
)

Definition at line 114 of file signal.c.

References do_shutdown(), dprintk, NOTHING, and SHUTDN_EXIT.

00115 {
00116         dprintk("caught SIGTERM");
00117         do_shutdown(NOTHING, 0, SHUTDN_EXIT, "received SIGTERM from kernel.");
00118 }

void signal_USR1 ( int  ,
siginfo_t *  ,
void *   
)

Definition at line 130 of file signal.c.

References do_restart(), dprintk, and mux_release_socket().

00131 {
00132     mux_release_socket();
00133     dprintk("caught SIGUSR1");
00134         do_restart(1, 1, 0);
00135 }

void unbind_signals (  ) 

Definition at line 96 of file signal.c.

References sighandler_stack.

Referenced by dnschild_request(), and fork_and_dump().

00097 {
00098         signal(SIGTERM, SIG_DFL);
00099         signal(SIGPIPE, SIG_DFL);
00100         signal(SIGUSR1, SIG_DFL);
00101         signal(SIGSEGV, SIG_DFL);
00102         signal(SIGBUS, SIG_DFL);
00103     signal(SIGCHLD, SIG_DFL);
00104     if(sighandler_stack.ss_sp != NULL) {
00105         void *temp_ptr;
00106         sighandler_stack.ss_flags = SS_DISABLE;
00107         temp_ptr = sighandler_stack.ss_sp;
00108         sigaltstack(&sighandler_stack, NULL);
00109         free(temp_ptr);
00110         sighandler_stack.ss_sp = NULL;
00111     }
00112 }


Variable Documentation

stack_t regular_stack

Definition at line 49 of file signal.c.

Referenced by bind_signals().

struct sigaction saBUS

Initial value:

 {.sa_handler = NULL,.sa_sigaction = signal_BUS,
        .sa_flags = SA_SIGINFO | SA_RESETHAND | SA_RESTART
}

Definition at line 44 of file signal.c.

Referenced by bind_signals().

struct sigaction saPIPE

Initial value:

 {.sa_handler = NULL,.sa_sigaction = signal_PIPE,
        .sa_flags = SA_SIGINFO
}

Definition at line 32 of file signal.c.

struct sigaction saSEGV

Initial value:

 {.sa_handler = NULL,.sa_sigaction = signal_SEGV,
        .sa_flags = SA_SIGINFO | SA_RESETHAND | SA_RESTART
}

Definition at line 40 of file signal.c.

Referenced by bind_signals().

struct sigaction saTERM

Initial value:

 {.sa_handler = NULL,.sa_sigaction = signal_TERM,
        .sa_flags = SA_SIGINFO | SA_RESETHAND | SA_RESTART
}

Definition at line 28 of file signal.c.

Referenced by bind_signals().

struct sigaction saUSR1

Initial value:

 {.sa_handler = NULL,.sa_sigaction = signal_USR1,
        .sa_flags = SA_SIGINFO | SA_RESETHAND | SA_RESTART 
}

Definition at line 36 of file signal.c.

Referenced by bind_signals().

stack_t sighandler_stack

Definition at line 48 of file signal.c.

Referenced by bind_signals(), and unbind_signals().


Generated on Mon May 28 04:25:47 2007 for BattletechMUX by  doxygen 1.4.7