Merge branch 'fixsignalhandler' into 'master'

Handle signals correctly on linux

See merge request STJr/SRB2!530
This commit is contained in:
James R 2019-12-24 02:54:44 -05:00
commit 9defd997c3
5 changed files with 132 additions and 24 deletions

View File

@ -562,9 +562,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();

View File

@ -127,6 +127,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

View File

@ -184,10 +184,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);

View File

@ -47,6 +47,7 @@ extern int SDL_main(int argc, char *argv[]);
#ifdef LOGMESSAGES
FILE *logstream = NULL;
char logfilename[1024];
#endif
#ifndef DOXYGEN
@ -116,7 +117,6 @@ int main(int argc, char **argv)
#endif
{
const char *logdir = NULL;
char logfile[MAX_WADPATH];
myargc = argc;
myargv = argv; /// \todo pull out path to exe from this string
@ -141,7 +141,7 @@ int main(int argc, char **argv)
timeinfo = localtime(&my_time);
strftime(buf, 26, "%Y-%m-%d %H-%M-%S", timeinfo);
strcpy(logfile, va("log-%s.txt", buf));
strcpy(logfilename, va("log-%s.txt", buf));
#ifdef DEFAULTDIR
if (logdir)
@ -149,14 +149,16 @@ int main(int argc, char **argv)
// Create dirs here because D_SRB2Main() is too late.
I_mkdir(va("%s%s"DEFAULTDIR, logdir, PATHSEP), 0755);
I_mkdir(va("%s%s"DEFAULTDIR"%slogs",logdir, PATHSEP, PATHSEP), 0755);
logstream = fopen(va("%s%s"DEFAULTDIR"%slogs%s%s",logdir, PATHSEP, PATHSEP, PATHSEP, logfile), "wt");
strcpy(logfilename, va("%s%s"DEFAULTDIR"%slogs%s%s",logdir, PATHSEP, PATHSEP, PATHSEP, logfilename));
}
else
#endif
{
I_mkdir("."PATHSEP"logs"PATHSEP, 0755);
logstream = fopen(va("."PATHSEP"logs"PATHSEP"%s", logfile), "wt");
strcpy(logfilename, va("."PATHSEP"logs"PATHSEP"%s", logfilename));
}
logstream = fopen(logfilename, "wt");
}
#endif
@ -181,12 +183,13 @@ int main(int argc, char **argv)
#endif
MakeCodeWritable();
#endif
// startup SRB2
CONS_Printf("Setting up SRB2...\n");
D_SRB2Main();
#ifdef LOGMESSAGES
if (!M_CheckParm("-nolog"))
CONS_Printf("Logfile: %s\n", logfile);
CONS_Printf("Logfile: %s\n", logfilename);
#endif
CONS_Printf("Entering main game loop...\n");
// never return

View File

@ -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 <errno.h>
#include <sys/wait.h>
#define NEWSIGNALHANDLER
#endif
#ifndef NOMUMBLE
#ifdef __linux__ // need -lrt
#include <sys/mman.h>
@ -229,13 +235,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)
{
@ -261,20 +265,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)
{
@ -650,7 +675,7 @@ static inline void I_ShutdownConsole(void){}
//
// StartupKeyboard
//
void I_StartupKeyboard (void)
void I_RegisterSignals (void)
{
#ifdef SIGINT
signal(SIGINT , quit_handler);
@ -664,10 +689,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
}
//
@ -2139,6 +2166,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;
@ -2146,6 +2252,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",
@ -2169,7 +2279,6 @@ void I_Quit(void)
if (quiting) goto death;
SDLforceUngrabMouse();
quiting = SDL_FALSE;
I_ShutdownConsole();
M_SaveConfig(NULL); //save game config, cvars..
#ifndef NONET
D_SaveBan(); // save the ban list
@ -2287,8 +2396,6 @@ void I_Error(const char *error, ...)
I_OutputMsg("\nI_Error(): %s\n", buffer);
// ---
I_ShutdownConsole();
M_SaveConfig(NULL); // save game config, cvars..
#ifndef NONET
D_SaveBan(); // save the ban list
@ -2388,6 +2495,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])();