diff --git a/include/QF/sys.h b/include/QF/sys.h index 20d7df19f..559c7fcd4 100644 --- a/include/QF/sys.h +++ b/include/QF/sys.h @@ -54,6 +54,7 @@ void Sys_Printf (const char *fmt, ...) __attribute__((format(printf,1,2))); void Sys_DPrintf (const char *fmt, ...) __attribute__((format(printf,1,2))); void Sys_Error (const char *error, ...) __attribute__((format(printf,1,2), noreturn)); void Sys_Quit (void); +void Sys_RegisterShutdown (void (*func) (void)); double Sys_DoubleTime (void); const char *Sys_ConsoleInput (void); diff --git a/libs/util/Makefile.am b/libs/util/Makefile.am index cf7b89ca5..7c62dfede 100644 --- a/libs/util/Makefile.am +++ b/libs/util/Makefile.am @@ -25,7 +25,7 @@ libQFutil_la_SOURCES = \ info.c link.c \ mathlib.c \ mdfour.c msg.c pcx.c plugin.c qargs.c qendian.c qfplist.c quakefs.c \ - quakeio.c sizebuf.c sys.c sys_error.c tga.c va.c ver_check.c wad.c \ + quakeio.c sizebuf.c sys.c tga.c va.c ver_check.c wad.c \ zone.c $(fnmatch_SRC) LIBLIST = libQFutil.la @LIBRARY_SEARCH_PATH@ diff --git a/libs/util/sys.c b/libs/util/sys.c index 28cf23415..ffa733d3e 100644 --- a/libs/util/sys.c +++ b/libs/util/sys.c @@ -71,6 +71,13 @@ cvar_t *sys_sleep; static sys_printf_t sys_printf_function = Sys_StdPrintf; +typedef struct shutdown_list_s { + struct shutdown_list_s *next; + void (*func)(void); +} shutdown_list_t; + +static shutdown_list_t *shutdown_list; + /* The translation table between the graphical font and plain ASCII --KB */ const char sys_char_map[256] = { '\0', '#', '#', '#', '#', '.', '#', '#', @@ -291,3 +298,56 @@ Sys_Init_Cvars (void) "in seconds between checking for connections. " "Minimum is 0, maximum is 13"); } + +static void +run_shutdown_list (void) +{ + shutdown_list_t *p = shutdown_list; + + while (p) { + p->func (); + p = p->next; + } +} + +void +Sys_Quit (void) +{ + run_shutdown_list (); + + exit (0); +} + +void +Sys_Error (const char *error, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr, error); + vsnprintf (string, sizeof (string), error, argptr); + va_end (argptr); + +#ifdef WIN32 + MessageBox (NULL, text, "Error", 0 /* MB_OK */ ); +#endif + fprintf (stderr, "Fatal error: %s\n", string); + + run_shutdown_list (); + + exit (1); +} + +void +Sys_RegisterShutdown (void (*func) (void)) +{ + shutdown_list_t *p; + if (!func) + return; + p = malloc (sizeof (*p)); + if (!p) + Sys_Error ("Sys_RegisterShutdown: insufficient memory"); + p->func = func; + p->next = shutdown_list; + shutdown_list = p; +} diff --git a/libs/util/sys_error.c b/libs/util/sys_error.c deleted file mode 100644 index 91ed1c9f4..000000000 --- a/libs/util/sys_error.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - sys.c - - virtual filesystem functions - - Copyright (C) 1996-1997 Id Software, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include - -#include "QF/sys.h" - -#include "compat.h" - - -void -QFutil_Sys_Error (const char *error, ...) -{ - va_list argptr; - char string[1024]; - - va_start (argptr, error); - vsnprintf (string, sizeof (string), error, argptr); - fprintf (stderr, "Error: %s\n", string); - - exit (1); -} - -void Sys_Error (const char *error, ...) __attribute ((weak, alias ("QFutil_Sys_Error"))); diff --git a/nq/source/sys_sdl.c b/nq/source/sys_sdl.c index 986763b47..6216e0618 100644 --- a/nq/source/sys_sdl.c +++ b/nq/source/sys_sdl.c @@ -111,33 +111,12 @@ Sys_Init (void) #endif } -void -Sys_Quit (void) +static void +shutdown (void) { - Host_Shutdown (); - exit (0); -} - -void -Sys_Error (const char *error, ...) -{ - va_list argptr; - char text[1024]; - #ifndef _WIN32 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); #endif - va_start (argptr, error); - vsnprintf (text, sizeof (text), error, argptr); - va_end (argptr); - -#ifdef WIN32 - MessageBox (NULL, text, "Error", 0 /* MB_OK */ ); -#endif - fprintf (stderr, "Error: %s\n", text); - - Host_Shutdown (); - exit (1); } void @@ -216,6 +195,9 @@ SDL_main (int c, char **v) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); #endif + Sys_RegisterShutdown (Host_Shutdown); + Sys_RegisterShutdown (shutdown); + Host_Init (&host_parms); Sys_Init_Cvars (); diff --git a/nq/source/sys_unix.c b/nq/source/sys_unix.c index 4b5d9d276..ebc9e1e36 100644 --- a/nq/source/sys_unix.c +++ b/nq/source/sys_unix.c @@ -67,32 +67,11 @@ Sys_Init (void) #endif } -void -Sys_Quit (void) +static void +shutdown (void) { - Host_Shutdown (); + // change stdin to blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); - fflush (stdout); - exit (0); -} - -void -Sys_Error (const char *error, ...) -{ - va_list argptr; - char string[1024]; - - // change stdin to non blocking - fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); - - va_start (argptr, error); - vsnprintf (string, sizeof (string), error, argptr); - va_end (argptr); - fprintf (stderr, "Error: %s\n", string); - - Host_Shutdown (); - exit (1); - } void @@ -189,6 +168,9 @@ main (int c, const char *v[]) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); + Sys_RegisterShutdown (Host_Shutdown); + Sys_RegisterShutdown (shutdown); + Host_Init (&parms); Sys_Init_Cvars (); diff --git a/nq/source/sys_unixd.c b/nq/source/sys_unixd.c index 24fb5ef4d..ed8525be6 100644 --- a/nq/source/sys_unixd.c +++ b/nq/source/sys_unixd.c @@ -139,32 +139,11 @@ Sys_DebugLog (char *file, char *fmt, ...) close (fd); } -void -Sys_Error (char *error, ...) +static void +shutdown (void) { - va_list argptr; - char string[1024]; - - // change stdin to non blocking - fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); - - va_start (argptr, error); - vsnprintf (string, sizeof (string), error, argptr); - va_end (argptr); - fprintf (stderr, "Error: %s\n", string); - - Host_Shutdown (); - exit (1); - -} - -void -Sys_Quit (void) -{ - Host_Shutdown (); fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); fflush (stdout); - exit (0); } void @@ -251,6 +230,9 @@ main (int argc, char *argv[]) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); + Sys_RegisterShutdown (Host_Shutdown); + Sys_RegisterShutdown (shutdown); + printf ("Host_Init\n"); Host_Init (&parms); diff --git a/nq/source/sys_win.c b/nq/source/sys_win.c index 0ffff240c..95bc03202 100644 --- a/nq/source/sys_win.c +++ b/nq/source/sys_win.c @@ -184,83 +184,12 @@ Sys_Init (void) WinNT = false; } -void -Sys_Error (const char *error, ...) -{ - va_list argptr; - char text[1024], text2[1024]; - char *text3 = "Press Enter to exit\n"; - char *text4 = "***********************************\n"; - char *text5 = "\n"; - DWORD dummy; - double starttime; - static int in_sys_error0 = 0; - static int in_sys_error1 = 0; - static int in_sys_error2 = 0; - static int in_sys_error3 = 0; - - if (!in_sys_error3) { - in_sys_error3 = 1; - VID_ForceUnlockedAndReturnState (); - } - - va_start (argptr, error); - vsnprintf (text, sizeof (text), error, argptr); - va_end (argptr); - - if (isDedicated) { - va_start (argptr, error); - vsnprintf (text, sizeof (text), error, argptr); - va_end (argptr); - - snprintf (text2, sizeof (text2), "ERROR: %s\n", text); - WriteFile (houtput, text5, strlen (text5), &dummy, NULL); - WriteFile (houtput, text4, strlen (text4), &dummy, NULL); - WriteFile (houtput, text2, strlen (text2), &dummy, NULL); - WriteFile (houtput, text3, strlen (text3), &dummy, NULL); - WriteFile (houtput, text4, strlen (text4), &dummy, NULL); - - starttime = Sys_DoubleTime (); - sc_return_on_enter = true; // so Enter will get us out of here - - while (!Sys_ConsoleInput () && - ((Sys_DoubleTime () - starttime) < CONSOLE_ERROR_TIMEOUT)) { - } - } else { - // switch to windowed so the message box is visible, unless we - // already tried that and failed - if (!in_sys_error0) { - in_sys_error0 = 1; - VID_SetDefaultMode (); - MessageBox (NULL, text, "Quake Error", - MB_OK | MB_SETFOREGROUND | MB_ICONSTOP); - } else { - MessageBox (NULL, text, "Double Quake Error", - MB_OK | MB_SETFOREGROUND | MB_ICONSTOP); - } - } - - if (!in_sys_error1) { - in_sys_error1 = 1; - Host_Shutdown (); - } - // shut down QHOST hooks if necessary - if (!in_sys_error2) { - in_sys_error2 = 1; - DeinitConProc (); - } - - exit (1); -} - -void -Sys_Quit (void) +static void +shutdown (void) { VID_ForceUnlockedAndReturnState (); - Host_Shutdown (); - if (tevent) CloseHandle (tevent); @@ -269,8 +198,6 @@ Sys_Quit (void) // shut down QHOST hooks if necessary DeinitConProc (); - - exit (0); } const char * @@ -501,6 +428,9 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, // because sound is off until we become active //XXX S_BlockSound (); + Sys_RegisterShutdown (Host_Shutdown); + Sys_RegisterShutdown (shutdown); + Con_Printf ("Host_Init\n"); Host_Init (&parms); diff --git a/nq/source/sys_wind.c b/nq/source/sys_wind.c index 79fcfcd3e..ca33a12f6 100644 --- a/nq/source/sys_wind.c +++ b/nq/source/sys_wind.c @@ -154,22 +154,6 @@ Sys_DebugLog (char *file, char *fmt, ...) { } -void -Sys_Error (char *error, ...) -{ - va_list argptr; - char text[1024]; - - va_start (argptr, error); - vsnprintf (text, sizeof (text), error, argptr); - va_end (argptr); - -// MessageBox(NULL, text, "Error", 0 /* MB_OK */ ); - printf ("ERROR: %s\n", text); - - exit (1); -} - void Sys_Printf (char *fmt, ...) { @@ -180,12 +164,6 @@ Sys_Printf (char *fmt, ...) va_end (argptr); } -void -Sys_Quit (void) -{ - exit (0); -} - void IN_SendKeyEvents (void) { @@ -271,6 +249,9 @@ main (int argc, char **argv) parms.argc = argc; parms.argv = argv; + Sys_RegisterShutdown (Host_Shutdown); + Sys_RegisterShutdown (shutdown); + printf ("Host_Init\n"); Host_Init (&parms); diff --git a/qw/source/cl_sys_sdl.c b/qw/source/cl_sys_sdl.c index 06c8daf66..e285ec02c 100644 --- a/qw/source/cl_sys_sdl.c +++ b/qw/source/cl_sys_sdl.c @@ -111,33 +111,12 @@ Sys_Init (void) #endif } -void -Sys_Quit (void) +static void +shutdown (void) { - Host_Shutdown (); - exit (0); -} - -void -Sys_Error (const char *error, ...) -{ - char text[1024]; - va_list argptr; - #ifndef _WIN32 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); #endif - va_start (argptr, error); - vsnprintf (text, sizeof (text), error, argptr); - va_end (argptr); - -#ifdef WIN32 - MessageBox (NULL, text, "Error", 0 /* MB_OK */ ); -#endif - fprintf (stderr, "Error: %s\n", text); - - Host_Shutdown (); - exit (1); } @@ -219,6 +198,10 @@ SDL_main (int c, char **v) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); #endif + Sys_RegisterShutdown (Host_Shutdown); + Sys_RegisterShutdown (Net_LogStop); + Sys_RegisterShutdown (shutdown); + Host_Init (); oldtime = Sys_DoubleTime (); diff --git a/qw/source/cl_sys_unix.c b/qw/source/cl_sys_unix.c index 42298b771..cb741b490 100644 --- a/qw/source/cl_sys_unix.c +++ b/qw/source/cl_sys_unix.c @@ -69,33 +69,11 @@ Sys_Init (void) #endif } -void -Sys_Quit (void) +static void +shutdown (void) { - Host_Shutdown (); + // change stdin to blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); - - Net_LogStop(); - - exit (0); -} - -void -Sys_Error (const char *error, ...) -{ - char string[1024]; - va_list argptr; - - // change stdin to non blocking - fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); - - va_start (argptr, error); - vsnprintf (string, sizeof (string), error, argptr); - va_end (argptr); - fprintf (stderr, "Error: %s\n", string); - - Host_Shutdown (); - exit (1); } void @@ -204,6 +182,10 @@ main (int c, const char *v[]) if (!noconinput) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); + Sys_RegisterShutdown (Host_Shutdown); + Sys_RegisterShutdown (Net_LogStop); + Sys_RegisterShutdown (shutdown); + Host_Init (); oldtime = Sys_DoubleTime (); diff --git a/qw/source/cl_sys_win.c b/qw/source/cl_sys_win.c index 801238beb..2d4f1dd60 100644 --- a/qw/source/cl_sys_win.c +++ b/qw/source/cl_sys_win.c @@ -124,42 +124,16 @@ Sys_Init (void) WinNT = false; } -void -Sys_Quit (void) +static void +shutdown (void) { VID_ForceUnlockedAndReturnState (); - Host_Shutdown (); - if (tevent) CloseHandle (tevent); if (qwclsemaphore) CloseHandle (qwclsemaphore); - - Net_LogStop(); - - exit (0); -} - -void -Sys_Error (const char *error, ...) -{ - char text[1024]; // , text2[1024]; - va_list argptr; -// DWORD dummy; - - Host_Shutdown (); - - va_start (argptr, error); - vsnprintf (text, sizeof (text), error, argptr); - va_end (argptr); - - MessageBox (NULL, text, "Error", 0 /* MB_OK */ ); - - CloseHandle (qwclsemaphore); - - exit (1); } void @@ -412,6 +386,10 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, Con_Printf ("Host_Init\n"); Host_Init (); + Sys_RegisterShutdown (Host_Shutdown); + Sys_RegisterShutdown (Net_LogStop); + Sys_RegisterShutdown (shutdown); + oldtime = Sys_DoubleTime (); /* main window message loop */ diff --git a/qw/source/sv_ccmds.c b/qw/source/sv_ccmds.c index 745dbb603..a9bca5f40 100644 --- a/qw/source/sv_ccmds.c +++ b/qw/source/sv_ccmds.c @@ -184,7 +184,6 @@ SV_Quit_f (void) { SV_FinalMessage ("server shutdown\n"); SV_Printf ("Shutting down.\n"); - SV_Shutdown (); Sys_Quit (); } diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c index fe187c434..ea7a96f7e 100644 --- a/qw/source/sv_main.c +++ b/qw/source/sv_main.c @@ -233,8 +233,6 @@ SV_Error (const char *error, ...) SV_FinalMessage (va ("server crashed: %s\n", string)); - SV_Shutdown (); - Sys_Error ("SV_Error: %s\n", string); } @@ -2321,6 +2319,8 @@ SV_Init (void) SV_Error ("Only %4.1f megs of memory reported, can't execute game", host_parms.memsize / (float) 0x100000); + Sys_RegisterShutdown (SV_Shutdown); + Cvar_Init_Hash (); Cmd_Init_Hash (); Memory_Init (host_parms.membase, host_parms.memsize); diff --git a/qw/source/sv_sys_unix.c b/qw/source/sv_sys_unix.c index 20f1fec69..022d1b04d 100644 --- a/qw/source/sv_sys_unix.c +++ b/qw/source/sv_sys_unix.c @@ -70,28 +70,6 @@ Sys_Init (void) #endif } -void -Sys_Quit (void) -{ - Net_LogStop(); - - exit (0); -} - -void -Sys_Error (const char *error, ...) -{ - char string[1024]; - va_list argptr; - - va_start (argptr, error); - vsnprintf (string, sizeof (string), error, argptr); - va_end (argptr); - printf ("Fatal error: %s\n", string); - - exit (1); -} - static int do_stdin = 1; /* @@ -147,6 +125,8 @@ main (int argc, const char *argv[]) SV_Init (); + Sys_RegisterShutdown (Net_LogStop); + // run one frame immediately for first heartbeat SV_Frame (0.1); diff --git a/qw/source/sv_sys_win.c b/qw/source/sv_sys_win.c index 147402fa7..378198a10 100644 --- a/qw/source/sv_sys_win.c +++ b/qw/source/sv_sys_win.c @@ -75,29 +75,6 @@ Sys_Init (void) WinNT = false; } -void -Sys_Quit (void) -{ - Net_LogStop(); - exit (0); -} - -void -Sys_Error (const char *error, ...) -{ - char text[1024]; - va_list argptr; - - va_start (argptr, error); - vsnprintf (text, sizeof (text), error, argptr); - va_end (argptr); - -// MessageBox(NULL, text, "Error", 0 /* MB_OK */ ); - printf ("ERROR: %s\n", text); - - exit (1); -} - /* Sys_ConsoleInput @@ -184,6 +161,8 @@ main (int argc, const char **argv) if (WinNT) Cvar_Set (sys_sleep, "0"); + Sys_RegisterShutdown (Net_LogStop); + // run one frame immediately for first heartbeat SV_Frame (0.1);