From 1a7c20698625b1b64f2a67c226622295616b8ee5 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 2 Mar 2025 07:37:46 -0800
Subject: [PATCH] Save and restore error messages when rolling back after
failed init
Fixes https://github.com/libsdl-org/SDL/issues/12439
---
src/SDL.c | 16 +++++++++++++++-
src/SDL_error_c.h | 12 ++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/src/SDL.c b/src/SDL.c
index e9c9fb1a2353f..502f6617a4f26 100644
--- a/src/SDL.c
+++ b/src/SDL.c
@@ -356,7 +356,9 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_IncrementSubsystemRefCount(SDL_INIT_VIDEO);
if (!SDL_VideoInit(NULL)) {
SDL_DecrementSubsystemRefCount(SDL_INIT_VIDEO);
+ SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
+ SDL_PopError();
goto quit_and_error;
}
} else {
@@ -381,7 +383,9 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_IncrementSubsystemRefCount(SDL_INIT_AUDIO);
if (!SDL_InitAudio(NULL)) {
SDL_DecrementSubsystemRefCount(SDL_INIT_AUDIO);
+ SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
+ SDL_PopError();
goto quit_and_error;
}
} else {
@@ -406,7 +410,9 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_IncrementSubsystemRefCount(SDL_INIT_JOYSTICK);
if (!SDL_InitJoysticks()) {
SDL_DecrementSubsystemRefCount(SDL_INIT_JOYSTICK);
+ SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
+ SDL_PopError();
goto quit_and_error;
}
} else {
@@ -430,7 +436,9 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_IncrementSubsystemRefCount(SDL_INIT_GAMEPAD);
if (!SDL_InitGamepads()) {
SDL_DecrementSubsystemRefCount(SDL_INIT_GAMEPAD);
+ SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+ SDL_PopError();
goto quit_and_error;
}
} else {
@@ -493,7 +501,9 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
SDL_IncrementSubsystemRefCount(SDL_INIT_CAMERA);
if (!SDL_CameraInit(NULL)) {
SDL_DecrementSubsystemRefCount(SDL_INIT_CAMERA);
+ SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
+ SDL_PopError();
goto quit_and_error;
}
} else {
@@ -511,7 +521,11 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
return SDL_ClearError();
quit_and_error:
- SDL_QuitSubSystem(flags_initialized);
+ {
+ SDL_PushError();
+ SDL_QuitSubSystem(flags_initialized);
+ SDL_PopError();
+ }
return false;
}
diff --git a/src/SDL_error_c.h b/src/SDL_error_c.h
index da9f8b5cad668..ba4550ed02916 100644
--- a/src/SDL_error_c.h
+++ b/src/SDL_error_c.h
@@ -46,4 +46,16 @@ typedef struct SDL_error
// Defined in SDL_thread.c
extern SDL_error *SDL_GetErrBuf(bool create);
+// Macros to save and restore error values
+#define SDL_PushError() \
+ char *saved_error = SDL_strdup(SDL_GetError())
+
+#define SDL_PopError() \
+ do { \
+ if (saved_error) { \
+ SDL_SetError("%s", saved_error); \
+ SDL_free(saved_error); \
+ } \
+ } while (0)
+
#endif // SDL_error_c_h_