mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-28 13:21:10 +00:00
nix: Fork before game code and wait to catch signals and coredumps
Ditched signal_handler to avoid worrying about async-signal-safe functions. D_QuitNetGame is not called, so players whose programs are interrupted by a signal will time out from the server. Because the game runs in a child process, the window can close before the "Signal Caught" text box appears. "(core dumped)" is also included in the message if core dumping could be determined.
This commit is contained in:
parent
3cd5b3a33e
commit
2b837726eb
4 changed files with 87 additions and 6 deletions
|
@ -136,6 +136,10 @@
|
||||||
#define LOGMESSAGES // write message in log.txt
|
#define LOGMESSAGES // write message in log.txt
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (defined (__unix__) && !defined (_MSDOS)) || defined (UNIXCOMMON)
|
||||||
|
#define NEWSIGNALHANDLER
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LOGMESSAGES
|
#ifdef LOGMESSAGES
|
||||||
extern FILE *logstream;
|
extern FILE *logstream;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -92,6 +92,10 @@ ticcmd_t *I_BaseTiccmd4(void);
|
||||||
*/
|
*/
|
||||||
void I_Quit(void) FUNCNORETURN;
|
void I_Quit(void) FUNCNORETURN;
|
||||||
|
|
||||||
|
/** \brief Print a message and text box about a signal that was raised.
|
||||||
|
*/
|
||||||
|
void I_ReportSignal(int num, int coredumped);
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
EvilForce = -1,
|
EvilForce = -1,
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NEWSIGNALHANDLER
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SDL
|
#ifdef HAVE_SDL
|
||||||
|
|
||||||
#ifdef HAVE_TTF
|
#ifdef HAVE_TTF
|
||||||
|
@ -157,6 +162,53 @@ int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
MakeCodeWritable();
|
MakeCodeWritable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NEWSIGNALHANDLER
|
||||||
|
switch (fork())
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
I_Error(
|
||||||
|
"Error setting up signal reporting: fork(): %s\n",
|
||||||
|
strerror(errno)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int signum;
|
||||||
|
if (wait(&status) == -1)
|
||||||
|
{
|
||||||
|
I_Error(
|
||||||
|
"Error setting up signal reporting: fork(): %s\n",
|
||||||
|
strerror(errno)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
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_ShutdownSystem();
|
||||||
|
exit(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif/*NEWSIGNALHANDLER*/
|
||||||
|
|
||||||
// startup SRB2
|
// startup SRB2
|
||||||
CONS_Printf("Setting up SRB2Kart...\n");
|
CONS_Printf("Setting up SRB2Kart...\n");
|
||||||
D_SRB2Main();
|
D_SRB2Main();
|
||||||
|
|
|
@ -246,13 +246,11 @@ SDL_bool framebuffer = SDL_FALSE;
|
||||||
|
|
||||||
UINT8 keyboard_started = false;
|
UINT8 keyboard_started = false;
|
||||||
|
|
||||||
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
|
void I_ReportSignal(int num, int coredumped)
|
||||||
{
|
{
|
||||||
//static char msg[] = "oh no! back to reality!\r\n";
|
//static char msg[] = "oh no! back to reality!\r\n";
|
||||||
const char * sigmsg;
|
const char * sigmsg;
|
||||||
char sigdef[32];
|
char msg[128];
|
||||||
|
|
||||||
D_QuitNetGame(); // Fix server freezes
|
|
||||||
|
|
||||||
switch (num)
|
switch (num)
|
||||||
{
|
{
|
||||||
|
@ -278,8 +276,21 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
|
||||||
sigmsg = "SIGABRT - abnormal termination triggered by abort call";
|
sigmsg = "SIGABRT - abnormal termination triggered by abort call";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(sigdef,"signal number %d", num);
|
sprintf(msg,"signal number %d", num);
|
||||||
sigmsg = sigdef;
|
if (coredumped)
|
||||||
|
sigmsg = 0;
|
||||||
|
else
|
||||||
|
sigmsg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coredumped)
|
||||||
|
{
|
||||||
|
if (sigmsg)
|
||||||
|
sprintf(msg, "%s (core dumped)", sigmsg);
|
||||||
|
else
|
||||||
|
strcat(msg, " (core dumped)");
|
||||||
|
|
||||||
|
sigmsg = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
I_OutputMsg("\nsignal_handler() error: %s\n", sigmsg);
|
I_OutputMsg("\nsignal_handler() error: %s\n", sigmsg);
|
||||||
|
@ -287,11 +298,19 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
|
||||||
"Signal caught",
|
"Signal caught",
|
||||||
sigmsg, NULL);
|
sigmsg, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NEWSIGNALHANDLER
|
||||||
|
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
|
||||||
|
{
|
||||||
|
D_QuitNetGame(); // Fix server freezes
|
||||||
|
I_ReportSignal(num, 0);
|
||||||
I_ShutdownSystem();
|
I_ShutdownSystem();
|
||||||
signal(num, SIG_DFL); //default signal action
|
signal(num, SIG_DFL); //default signal action
|
||||||
raise(num);
|
raise(num);
|
||||||
I_Quit();
|
I_Quit();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
FUNCNORETURN static ATTRNORETURN void quit_handler(int num)
|
FUNCNORETURN static ATTRNORETURN void quit_handler(int num)
|
||||||
{
|
{
|
||||||
|
@ -681,10 +700,12 @@ void I_StartupKeyboard (void)
|
||||||
|
|
||||||
// If these defines don't exist,
|
// If these defines don't exist,
|
||||||
// then compilation would have failed above us...
|
// then compilation would have failed above us...
|
||||||
|
#ifndef NEWSIGNALHANDLER
|
||||||
signal(SIGILL , signal_handler);
|
signal(SIGILL , signal_handler);
|
||||||
signal(SIGSEGV , signal_handler);
|
signal(SIGSEGV , signal_handler);
|
||||||
signal(SIGABRT , signal_handler);
|
signal(SIGABRT , signal_handler);
|
||||||
signal(SIGFPE , signal_handler);
|
signal(SIGFPE , signal_handler);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue