diff --git a/src/d_main.c b/src/d_main.c index e513a095..cde5a9df 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -616,9 +616,6 @@ void D_SRB2Loop(void) // Pushing of + parameters is now done back in D_SRB2Main, not here. - CONS_Printf("I_StartupKeyboard()...\n"); - I_StartupKeyboard(); - #ifdef _WINDOWS CONS_Printf("I_StartupMouse()...\n"); I_DoStartupMouse(); diff --git a/src/doomdef.h b/src/doomdef.h index 71a92240..13d6a643 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -138,6 +138,7 @@ #ifdef LOGMESSAGES extern FILE *logstream; +extern char logfilename[1024]; #endif //#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 diff --git a/src/i_system.h b/src/i_system.h index d1708fe5..3e589c69 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -226,10 +226,6 @@ void I_StartupMouse(void); */ void I_StartupMouse2(void); -/** \brief keyboard startup, shutdown, handler -*/ -void I_StartupKeyboard(void); - /** \brief setup timer irq and user timer routine. */ void I_StartupTimer(void); diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 41a9d7cd..41874e9f 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -45,6 +45,7 @@ extern int SDL_main(int argc, char *argv[]); #ifdef LOGMESSAGES FILE *logstream = NULL; +char logfilename[1024]; #endif #ifndef DOXYGEN @@ -130,10 +131,12 @@ int main(int argc, char **argv) #ifdef LOGMESSAGES #ifdef DEFAULTDIR if (logdir) - logstream = fopen(va("%s/"DEFAULTDIR"/log.txt",logdir), "wt"); + strcpy(logfilename, va("%s/"DEFAULTDIR"/log.txt",logdir)); else #endif - logstream = fopen("./log.txt", "wt"); + strcpy(logfilename, "./log.txt"); + + logstream = fopen(logfilename, "wt"); #endif //I_OutputMsg("I_StartupSystem() ...\n"); @@ -157,6 +160,7 @@ int main(int argc, char **argv) #endif MakeCodeWritable(); #endif + // startup SRB2 CONS_Printf("Setting up SRB2Kart...\n"); D_SRB2Main(); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index c0fca64d..37d6dd79 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -102,6 +102,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #endif +#if (defined (__unix__) && !defined (_MSDOS)) || defined (UNIXCOMMON) +#include +#include +#define NEWSIGNALHANDLER +#endif + #ifndef NOMUMBLE #ifdef __linux__ // need -lrt #include @@ -246,13 +252,11 @@ SDL_bool framebuffer = SDL_FALSE; UINT8 keyboard_started = false; -FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) +static void I_ReportSignal(int num, int coredumped) { //static char msg[] = "oh no! back to reality!\r\n"; const char * sigmsg; - char sigdef[32]; - - D_QuitNetGame(); // Fix server freezes + char msg[128]; switch (num) { @@ -278,20 +282,41 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) sigmsg = "SIGABRT - abnormal termination triggered by abort call"; break; default: - sprintf(sigdef,"signal number %d", num); - sigmsg = sigdef; + sprintf(msg,"signal number %d", num); + if (coredumped) + sigmsg = 0; + else + sigmsg = msg; } - I_OutputMsg("\nsignal_handler() error: %s\n", sigmsg); + if (coredumped) + { + if (sigmsg) + sprintf(msg, "%s (core dumped)", sigmsg); + else + strcat(msg, " (core dumped)"); + + sigmsg = msg; + } + + I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "Signal caught", + "Process killed by signal", sigmsg, NULL); +} + +#ifndef NEWSIGNALHANDLER +FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) +{ + D_QuitNetGame(); // Fix server freezes + I_ReportSignal(num, 0); I_ShutdownSystem(); signal(num, SIG_DFL); //default signal action raise(num); I_Quit(); } +#endif FUNCNORETURN static ATTRNORETURN void quit_handler(int num) { @@ -667,7 +692,7 @@ static inline void I_ShutdownConsole(void){} // // StartupKeyboard // -void I_StartupKeyboard (void) +void I_RegisterSignals (void) { #ifdef SIGINT signal(SIGINT , quit_handler); @@ -681,10 +706,12 @@ void I_StartupKeyboard (void) // If these defines don't exist, // then compilation would have failed above us... +#ifndef NEWSIGNALHANDLER signal(SIGILL , signal_handler); signal(SIGSEGV , signal_handler); signal(SIGABRT , signal_handler); signal(SIGFPE , signal_handler); +#endif } // @@ -3022,6 +3049,85 @@ void I_Sleep(void) SDL_Delay(cv_sleep.value); } +#ifdef NEWSIGNALHANDLER +static void newsignalhandler_Warn(const char *pr) +{ + char text[128]; + + snprintf(text, sizeof text, + "Error while setting up signal reporting: %s: %s", + pr, + strerror(errno) + ); + + I_OutputMsg("%s\n", text); + + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, + "Startup error", + text, NULL); + + I_ShutdownConsole(); + exit(-1); +} + +static void I_Fork(void) +{ + int child; + int status; + int signum; + int c; + + child = fork(); + + switch (child) + { + case -1: + newsignalhandler_Warn("fork()"); + break; + case 0: + break; + default: + if (logstream) + fclose(logstream);/* the child has this */ + + c = wait(&status); + +#ifdef LOGMESSAGES + /* By the way, exit closes files. */ + logstream = fopen(logfilename, "at"); +#else + logstream = 0; +#endif + + if (c == -1) + { + kill(child, SIGKILL); + newsignalhandler_Warn("wait()"); + } + else + { + if (WIFSIGNALED (status)) + { + signum = WTERMSIG (status); +#ifdef WCOREDUMP + I_ReportSignal(signum, WCOREDUMP (status)); +#else + I_ReportSignal(signum, 0); +#endif + status = 128 + signum; + } + else if (WIFEXITED (status)) + { + status = WEXITSTATUS (status); + } + + I_ShutdownConsole(); + exit(status); + } + } +} +#endif/*NEWSIGNALHANDLER*/ + INT32 I_StartupSystem(void) { SDL_version SDLcompiled; @@ -3029,6 +3135,10 @@ INT32 I_StartupSystem(void) SDL_VERSION(&SDLcompiled) SDL_GetVersion(&SDLlinked); I_StartupConsole(); +#ifdef NEWSIGNALHANDLER + I_Fork(); +#endif + I_RegisterSignals(); I_OutputMsg("Compiled for SDL version: %d.%d.%d\n", SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); I_OutputMsg("Linked with SDL version: %d.%d.%d\n", @@ -3271,6 +3381,10 @@ void I_ShutdownSystem(void) { INT32 c; +#ifndef NEWSIGNALHANDLER + I_ShutdownConsole(); +#endif + for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) if (quit_funcs[c]) (*quit_funcs[c])();