#include "thread.h"
#include "libcurl.h"
-#ifdef WIN32
- // Microsoft's compiler complains about portable code
- #pragma warning(disable : 4996)
-#endif
sys_t sys;
}
-void Sys_Quit (int returnvalue)
-{
- // Unlock mutexes because the quit command may jump directly here, causing a deadlock
- if ((cmd_local)->cbuf->lock)
- Cbuf_Unlock((cmd_local)->cbuf);
- SV_UnlockThreadMutex();
- TaskQueue_Frame(true);
-
- if (Sys_CheckParm("-profilegameonly"))
- Sys_AllowProfiling(false);
- host.state = host_shutdown;
- Host_Shutdown();
-
-#ifdef __ANDROID__
- Sys_AllowProfiling(false);
-#endif
-
-#ifndef WIN32
- fcntl(fileno(stdout), F_SETFL, fcntl(fileno(stdout), F_GETFL, 0) & ~O_NONBLOCK);
- fcntl(fileno(stderr), F_SETFL, fcntl(fileno(stderr), F_GETFL, 0) & ~O_NONBLOCK);
-#endif
- fflush(stdout);
- fflush(stderr);
-
- exit(returnvalue);
-}
-
#ifdef __cplusplus
extern "C"
#endif
double old_benchmark_time = benchmark_time;
benchmark_time += 1;
if(benchmark_time == old_benchmark_time)
- Sys_Abort("sys_usenoclockbutbenchmark cannot run any longer, sorry");
+ Sys_Error("sys_usenoclockbutbenchmark cannot run any longer, sorry");
return benchmark_time * 0.000001;
}
#if HAVE_QUERYPERFORMANCECOUNTER
}
#else
// fallback for using the SDL timer if no other timer is available
- // this calls Sys_Abort() if not linking against SDL
+ // this calls Sys_Error() if not linking against SDL
return (double) Sys_SDL_GetTicks() / 1000.0;
#endif
}
double old_benchmark_time = benchmark_time;
benchmark_time += microseconds;
if(benchmark_time == old_benchmark_time)
- Sys_Abort("sys_usenoclockbutbenchmark cannot run any longer, sorry");
+ Sys_Error("sys_usenoclockbutbenchmark cannot run any longer, sorry");
return 0;
}
===============================================================================
*/
-void Sys_Abort (const char *error, ...)
+void Sys_Error (const char *error, ...)
{
va_list argptr;
char string[MAX_INPUTLINE];
int i;
+ // Disable Sys_HandleSignal() but not Sys_HandleCrash()
+ host.state = host_shutdown;
+
// set output to blocking stderr
sys.outfd = fileno(stderr);
#ifndef WIN32
dpvsnprintf (string, sizeof (string), error, argptr);
va_end (argptr);
- Con_Printf(CON_ERROR "Engine Abort: %s\n^9%s\n", string, engineversion);
+ Con_Printf(CON_ERROR "Engine Aborted: %s\n^9%s\n", string, engineversion);
dp_strlcat(string, "\n\n", sizeof(string));
dp_strlcat(string, engineversion, sizeof(string));
sv.active = false; // make SV_DropClient() skip the QC stuff to avoid recursive errors
for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
if (host_client->active)
- SV_DropClient(false, "Server abort!"); // closes demo file
+ SV_DropClient(false, "Server aborted!"); // closes demo file
}
// don't want a dead window left blocking the OS UI or the abort dialog
VID_Shutdown();
S_StopAllSounds();
- host.state = host_failed; // make Sys_HandleSignal() call exit()
- Sys_SDL_Dialog("Engine Abort", string);
+ host.state = host_failed; // make Sys_HandleSignal() call _Exit()
+ Sys_SDL_Dialog("Engine Aborted", string);
fflush(stderr);
-
exit (1);
}
char **btstrings;
#endif
char dialogtext[3072];
- const char *sigdesc = Sys_SigDesc(sig);
+ const char *sigdesc;
+
+ // Break any loop and disable Sys_HandleSignal()
+ if (host.state == host_failing || host.state == host_failed)
+ return;
+ host.state = host_failing;
+
+ sigdesc = Sys_SigDesc(sig);
// set output to blocking stderr and print header, backtrace, version
sys.outfd = fileno(stderr); // not async-signal-safe :(
Sys_Print("\n", 1);
#endif
- // DP8 TODO: send a disconnect message indicating we crashed, see Sys_Abort() and Host_Error()
+ // DP8 TODO: send a disconnect message indicating we crashed, see Sys_Error() and Host_Error()
// don't want a dead window left blocking the OS UI or the crash dialog
VID_Shutdown();
Sys_SDL_Dialog("Engine Crash", dialogtext);
fflush(stderr); // not async-signal-safe :(
- _Exit(sig);
+
+ // Continue execution with default signal handling.
+ // A real crash will be re-triggered so the platform can handle it,
+ // a fake crash (kill -SEGV) will cause a graceful shutdown.
+ signal(sig, SIG_DFL);
}
static void Sys_HandleSignal(int sig)
{
- const char *sigdesc = Sys_SigDesc(sig);
+ const char *sigdesc;
+
+ // Break any loop, eg if each Sys_Print triggers a SIGPIPE
+ if (host.state == host_shutdown || host.state == host_failing)
+ return;
+
+ sigdesc = Sys_SigDesc(sig);
Sys_Print("\nReceived ", 10);
Sys_Print(sigdesc, strlen(sigdesc));
Sys_Print(" signal, exiting...\n", 20);
if (host.state == host_failed)
{
- // user is trying to kill the process while the dialog is open
+ // user is trying to kill the process while the SDL dialog is open
fflush(stderr); // not async-signal-safe :(
_Exit(sig);
}
Host_Main();
- Sys_Quit(0);
+#ifdef __ANDROID__
+ Sys_AllowProfiling(false);
+#endif
+
+#ifndef WIN32
+ fcntl(fileno(stdout), F_SETFL, fcntl(fileno(stdout), F_GETFL, 0) & ~O_NONBLOCK);
+ fcntl(fileno(stderr), F_SETFL, fcntl(fileno(stderr), F_GETFL, 0) & ~O_NONBLOCK);
+#endif
+ fflush(stdout);
+ fflush(stderr);
return 0;
}