summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/common/common.h3
-rw-r--r--src/common/common.c12
-rw-r--r--src/refresh/images.c5
-rw-r--r--src/server/commands.c14
-rw-r--r--src/server/init.c3
-rw-r--r--src/server/mvd/client.c1
-rw-r--r--src/server/mvd/game.c1
-rw-r--r--src/server/save.c24
8 files changed, 44 insertions, 19 deletions
diff --git a/inc/common/common.h b/inc/common/common.h
index 58aafa7..48e5e45 100644
--- a/inc/common/common.h
+++ b/inc/common/common.h
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/cmd.h"
#include "common/utils.h"
+#include <setjmp.h>
//
// common.h -- definitions common between client and server, but not game.dll
@@ -171,6 +172,8 @@ extern unsigned time_before_ref;
extern unsigned time_after_ref;
#endif
+extern jmp_buf com_abortframe;
+
extern const char com_version_string[];
extern unsigned com_framenum;
diff --git a/src/common/common.c b/src/common/common.c
index 31ea3fc..7a0e713 100644
--- a/src/common/common.c
+++ b/src/common/common.c
@@ -49,9 +49,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "server/server.h"
#include "system/system.h"
-#include <setjmp.h>
-
-static jmp_buf abortframe; // an ERR_DROP occured, exit the entire frame
+jmp_buf com_abortframe; // an ERR_DROP occured, exit the entire frame
static qboolean com_errorEntered;
static char com_errorMsg[MAXERRORMSG]; // from Com_Printf/Com_Error
@@ -561,13 +559,13 @@ abort:
FS_Flush(com_logFile);
}
com_errorEntered = qfalse;
- longjmp(abortframe, -1);
+ longjmp(com_abortframe, -1);
}
#ifdef _WIN32
void Com_AbortFrame(void)
{
- longjmp(abortframe, -1);
+ longjmp(com_abortframe, -1);
}
#endif
@@ -865,7 +863,7 @@ Qcommon_Init
*/
void Qcommon_Init(int argc, char **argv)
{
- if (setjmp(abortframe))
+ if (setjmp(com_abortframe))
Sys_Error("Error during initialization: %s", com_errorMsg);
com_argc = argc;
@@ -1048,7 +1046,7 @@ void Qcommon_Frame(void)
static unsigned remaining;
static float frac;
- if (setjmp(abortframe)) {
+ if (setjmp(com_abortframe)) {
return; // an ERR_DROP was thrown
}
diff --git a/src/refresh/images.c b/src/refresh/images.c
index 315e506..bb017e4 100644
--- a/src/refresh/images.c
+++ b/src/refresh/images.c
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "format/wal.h"
#if USE_PNG
+#define PNG_SKIP_SETJMP_CHECK
#include <png.h>
#if USE_ZLIB
#include <zlib.h>
@@ -40,10 +41,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <jpeglib.h>
#endif
-#if USE_PNG || USE_JPG
-#include <setjmp.h>
-#endif
-
#define IMG_LOAD(x) \
static qerror_t IMG_Load##x(byte *rawdata, size_t rawlen, \
const char *filename, byte **pic, int *width, int *height)
diff --git a/src/server/commands.c b/src/server/commands.c
index 146c6de..30df491 100644
--- a/src/server/commands.c
+++ b/src/server/commands.c
@@ -261,6 +261,7 @@ static void SV_Map(qboolean restart)
{
mapcmd_t cmd;
size_t len;
+ jmp_buf tmp;
memset(&cmd, 0, sizeof(cmd));
@@ -274,6 +275,16 @@ static void SV_Map(qboolean restart)
if (!SV_ParseMapCmd(&cmd))
return;
+ // save error frame
+ memcpy(tmp, com_abortframe, sizeof(jmp_buf));
+
+ // catch ERR_DROP and free the map
+ if (setjmp(com_abortframe)) {
+ memcpy(com_abortframe, tmp, sizeof(jmp_buf));
+ CM_FreeMap(&cmd.cm);
+ return;
+ }
+
// wipe savegames
cmd.endofunit |= restart;
@@ -283,6 +294,9 @@ static void SV_Map(qboolean restart)
if ((sv.state != ss_game && sv.state != ss_pic) || restart)
SV_InitGame(MVD_SPAWN_DISABLED); // the game is just starting
+ // restore error frame
+ memcpy(com_abortframe, tmp, sizeof(jmp_buf));
+
SV_SpawnServer(&cmd);
SV_AutoSaveEnd();
diff --git a/src/server/init.c b/src/server/init.c
index 3afa907..f477a12 100644
--- a/src/server/init.c
+++ b/src/server/init.c
@@ -182,8 +182,7 @@ void SV_SpawnServer(mapcmd_t *cmd)
Q_strlcpy(sv.mapcmd, cmd->buffer, sizeof(sv.mapcmd));
if (Cvar_VariableInteger("deathmatch")) {
- sprintf(sv.configstrings[CS_AIRACCEL],
- "%d", sv_airaccelerate->integer);
+ sprintf(sv.configstrings[CS_AIRACCEL], "%d", sv_airaccelerate->integer);
} else {
strcpy(sv.configstrings[CS_AIRACCEL], "0");
}
diff --git a/src/server/mvd/client.c b/src/server/mvd/client.c
index e3c3642..0fa6968 100644
--- a/src/server/mvd/client.c
+++ b/src/server/mvd/client.c
@@ -22,7 +22,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client.h"
#include "server/mvd/protocol.h"
-#include <setjmp.h>
#define FOR_EACH_GTV(gtv) \
LIST_FOR_EACH(gtv_t, gtv, &mvd_gtv_list, entry)
diff --git a/src/server/mvd/game.c b/src/server/mvd/game.c
index 3573a73..01f443a 100644
--- a/src/server/mvd/game.c
+++ b/src/server/mvd/game.c
@@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
//
#include "client.h"
-#include <setjmp.h>
static cvar_t *mvd_admin_password;
static cvar_t *mvd_part_filter;
diff --git a/src/server/save.c b/src/server/save.c
index 2dd1f41..2fddda7 100644
--- a/src/server/save.c
+++ b/src/server/save.c
@@ -309,6 +309,7 @@ static int read_server_file(void)
char name[MAX_OSPATH], string[MAX_STRING_CHARS];
mapcmd_t cmd;
size_t len;
+ jmp_buf tmp;
// errors like missing file, bad version, etc are
// non-fatal and just return to the command handler
@@ -341,6 +342,16 @@ static int read_server_file(void)
if (!SV_ParseMapCmd(&cmd))
return -1;
+ // save error frame
+ memcpy(tmp, com_abortframe, sizeof(jmp_buf));
+
+ // catch ERR_DROP and free the map
+ if (setjmp(com_abortframe)) {
+ memcpy(com_abortframe, tmp, sizeof(jmp_buf));
+ CM_FreeMap(&cmd.cm);
+ return -1;
+ }
+
// any error will drop from this point
SV_Shutdown("Server restarted\n", ERR_RECONNECT);
@@ -378,6 +389,9 @@ static int read_server_file(void)
ge->ReadGame(name);
+ // restore error frame
+ memcpy(com_abortframe, tmp, sizeof(jmp_buf));
+
// go to the map
SV_SpawnServer(&cmd);
return 0;
@@ -402,6 +416,8 @@ static int read_level_file(void)
if (MSG_ReadLong() != SAVE_VERSION)
return -1;
+ // any error will drop from this point
+
// the rest can't underflow
msg_read.allowunderflow = qfalse;
@@ -412,17 +428,17 @@ static int read_level_file(void)
break;
if (index < 0 || index > MAX_CONFIGSTRINGS)
- return -1;
+ Com_Error(ERR_DROP, "Bad savegame configstring index");
maxlen = CS_SIZE(index);
len = MSG_ReadString(sv.configstrings[index], maxlen);
if (len >= maxlen)
- return -1;
+ Com_Error(ERR_DROP, "Savegame configstring too long");
}
len = MSG_ReadByte();
if (len > MAX_MAP_PORTAL_BYTES)
- return -1;
+ Com_Error(ERR_DROP, "Savegame portalbits too long");
SV_ClearWorld();
@@ -432,7 +448,7 @@ static int read_level_file(void)
len = Q_snprintf(name, MAX_OSPATH, "%s/save/" SAVE_CURRENT "/%s.sav",
fs_gamedir, sv.name);
if (len >= MAX_OSPATH)
- return -1;
+ Com_Error(ERR_DROP, "Savegame path too long");
ge->ReadLevel(name);
return 0;