diff --git a/docs/README-vita.md b/docs/README-vita.md index 0a11cf806b..c222a14c86 100644 --- a/docs/README-vita.md +++ b/docs/README-vita.md @@ -21,13 +21,13 @@ Notes ----- * gles1/gles2 support and renderers are disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PVR=ON` These renderers support 720p and 1080i resolutions. These can be specified with: - `SDL_setenv("VITA_RESOLUTION", "720", 1);` and `SDL_setenv("VITA_RESOLUTION", "1080", 1);` + `SDL_SetHint(SDL_HINT_VITA_RESOLUTION, "720");` and `SDL_SetHint(SDL_HINT_VITA_RESOLUTION, "1080");` * Desktop GL 1.X and 2.X support and renderers are also disabled by default and also can be enabled with `-DVIDEO_VITA_PVR=ON` as long as gl4es4vita is present in your SDK. - They support the same resolutions as the gles1/gles2 backends and require specifying `SDL_setenv("VITA_PVR_OGL", "1", 1);` + They support the same resolutions as the gles1/gles2 backends and require specifying `SDL_SetHint(SDL_HINT_VITA_PVR_OPENGL, "1");` anytime before video subsystem initialization. * gles2 support via PIB is disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PIB=ON` * By default SDL emits mouse events for touch events on every touchscreen. Vita has two touchscreens, so it's recommended to use `SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");` and handle touch events instead. Individual touchscreens can be disabled with: - `SDL_setenv("VITA_DISABLE_TOUCH_FRONT", "1", 1);` and `SDL_setenv("VITA_DISABLE_TOUCH_BACK", "1", 1);` + `SDL_SetHint(SDL_HINT_VITA_ENABLE_FRONT_TOUCH, "0");` and `SDL_SetHint(SDL_HINT_VITA_ENABLE_BACK_TOUCH, "0");` * Support for L2/R2/R3/R3 buttons, haptic feedback and gamepad led only available on PSTV, or when using external ds4 gamepad on vita. diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h index aa6563ef89..21113ac6af 100644 --- a/include/SDL3/SDL_stdinc.h +++ b/include/SDL3/SDL_stdinc.h @@ -978,9 +978,213 @@ extern SDL_DECLSPEC void SDLCALL SDL_aligned_free(void *mem); */ extern SDL_DECLSPEC int SDLCALL SDL_GetNumAllocations(void); -extern SDL_DECLSPEC const char * SDLCALL SDL_getenv(const char *name); -extern SDL_DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); -extern SDL_DECLSPEC int SDLCALL SDL_unsetenv(const char *name); +/** + * A thread-safe set of environment variables + * + * \since This struct is available since SDL 3.0.0. + * + * \sa SDL_GetEnvironment + * \sa SDL_CleanupEnvironment + * \sa SDL_CreateEnvironment + * \sa SDL_GetEnvironmentVariable + * \sa SDL_GetEnvironmentVariables + * \sa SDL_SetEnvironmentVariable + * \sa SDL_UnsetEnvironmentVariable + * \sa SDL_DestroyEnvironment + */ +typedef struct SDL_Environment SDL_Environment; + +/** + * Get the process environment. + * + * This is initialized at application start and is not affected by setenv() and unsetenv() calls after that point. Use SDL_SetEnvironmentVariable() and SDL_UnsetEnvironmentVariable() if you want to modify this environment. + * + * \returns a pointer to the environment for the process or NULL on failure; call SDL_GetError() + * for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_CleanupEnvironment + * \sa SDL_GetEnvironmentVariable + * \sa SDL_GetEnvironmentVariables + * \sa SDL_SetEnvironmentVariable + * \sa SDL_UnsetEnvironmentVariable + */ +extern SDL_DECLSPEC SDL_Environment * SDLCALL SDL_GetEnvironment(void); + +/** + * Cleanup the process environment. + * + * This is called during SDL_Quit() to free the process environment. If SDL_GetEnvironment() is called afterwards, it will automatically create a new environment copied from the C runtime environment. + * + * \threadsafety This function is not thread-safe. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetEnvironment + */ +extern SDL_DECLSPEC void SDLCALL SDL_CleanupEnvironment(void); + +/** + * Create a set of environment variables + * + * \param empty SDL_TRUE to create an empty environment, SDL_FALSE to initialize it from the C runtime environment. + * \returns a pointer to the new environment or NULL on failure; call SDL_GetError() + * for more information. + * + * \threadsafety If `empty` is SDL_TRUE, it is safe to call this function from any thread, otherwise it is safe if no other threads are calling setenv() or unsetenv() + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetEnvironmentVariable + * \sa SDL_GetEnvironmentVariables + * \sa SDL_SetEnvironmentVariable + * \sa SDL_UnsetEnvironmentVariable + * \sa SDL_DestroyEnvironment + */ +extern SDL_DECLSPEC SDL_Environment * SDLCALL SDL_CreateEnvironment(SDL_bool empty); + +/** + * Get the value of a variable in the environment. + * + * \param env the environment to query. + * \param name the name of the variable to get. + * \returns a pointer to the value of the variable or NULL if it can't be found. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetEnvironment + * \sa SDL_CreateEnvironment + * \sa SDL_GetEnvironmentVariables + * \sa SDL_SetEnvironmentVariable + * \sa SDL_UnsetEnvironmentVariable + */ +extern SDL_DECLSPEC const char * SDLCALL SDL_GetEnvironmentVariable(SDL_Environment *env, const char *name); + +/** + * Get all variables in the environment. + * + * \param env the environment to query. + * \returns a NULL terminated array of pointers to environment variables in the form "variable=value" or NULL on + * failure; call SDL_GetError() for more information. This is a + * single allocation that should be freed with SDL_free() when it is + * no longer needed. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetEnvironment + * \sa SDL_CreateEnvironment + * \sa SDL_GetEnvironmentVariables + * \sa SDL_SetEnvironmentVariable + * \sa SDL_UnsetEnvironmentVariable + */ +extern SDL_DECLSPEC char ** SDLCALL SDL_GetEnvironmentVariables(SDL_Environment *env); + +/** + * Set the value of a variable in the environment. + * + * \param env the environment to modify. + * \param name the name of the variable to set. + * \param value the value of the variable to set. + * \param overwrite SDL_TRUE to overwrite the variable if it exists, SDL_FALSE to return success without setting the variable if it already exists. + * \returns SDL_TRUE on success or SDL_FALSE on failure; call SDL_GetError() + * for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetEnvironment + * \sa SDL_CreateEnvironment + * \sa SDL_GetEnvironmentVariable + * \sa SDL_GetEnvironmentVariables + * \sa SDL_UnsetEnvironmentVariable + */ +extern SDL_DECLSPEC SDL_bool SDLCALL SDL_SetEnvironmentVariable(SDL_Environment *env, const char *name, const char *value, SDL_bool overwrite); + +/** + * Clear a variable from the environment. + * + * \param env the environment to modify. + * \param name the name of the variable to unset. + * \returns SDL_TRUE on success or SDL_FALSE on failure; call SDL_GetError() + * for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetEnvironment + * \sa SDL_CreateEnvironment + * \sa SDL_GetEnvironmentVariable + * \sa SDL_GetEnvironmentVariables + * \sa SDL_SetEnvironmentVariable + * \sa SDL_UnsetEnvironmentVariable + */ +extern SDL_DECLSPEC SDL_bool SDLCALL SDL_UnsetEnvironmentVariable(SDL_Environment *env, const char *name); + +/** + * Destroy a set of environment variables. + * + * \param env the environment to destroy. + * + * \threadsafety It is safe to call this function from any thread, as long as the environment is no longer in use. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_CreateEnvironment + */ +extern SDL_DECLSPEC void SDLCALL SDL_DestroyEnvironment(SDL_Environment *env); + +/** + * Get the value of a variable in the environment. + * + * \param name the name of the variable to get. + * \returns a pointer to the value of the variable or NULL if it can't be found. + * + * \threadsafety This function is not thread safe, consider using SDL_GetEnvironmentVariable() instead. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetEnvironmentVariable + */ +extern SDL_DECLSPEC const char * SDLCALL SDL_getenv_unsafe(const char *name); + +/** + * Set the value of a variable in the environment. + * + * \param name the name of the variable to set. + * \param value the value of the variable to set. + * \param overwrite 1 to overwrite the variable if it exists, 0 to return success without setting the variable if it already exists. + * \returns 0 on success, -1 on error. + * + * \threadsafety This function is not thread safe, consider using SDL_SetEnvironmentVariable() instead. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_SetEnvironmentVariable + */ +extern SDL_DECLSPEC int SDLCALL SDL_setenv_unsafe(const char *name, const char *value, int overwrite); + +/** + * Clear a variable from the environment. + * + * \param name the name of the variable to unset. + * \returns 0 on success, -1 on error. + * + * \threadsafety This function is not thread safe, consider using SDL_UnsetEnvironmentVariable() instead.. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_UnsetEnvironmentVariable + */ +extern SDL_DECLSPEC int SDLCALL SDL_unsetenv_unsafe(const char *name); typedef int (SDLCALL *SDL_CompareCallback)(const void *a, const void *b); extern SDL_DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, SDL_CompareCallback compare); diff --git a/src/SDL.c b/src/SDL.c index e66fc34adf..63c3347fb0 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -255,12 +255,14 @@ void SDL_InitMainThread(void) SDL_InitLog(); SDL_InitProperties(); SDL_GetGlobalProperties(); + SDL_GetEnvironment(); SDL_InitHints(); } static void SDL_QuitMainThread(void) { SDL_QuitHints(); + SDL_CleanupEnvironment(); SDL_QuitProperties(); SDL_QuitLog(); SDL_QuitFilesystem(); diff --git a/src/SDL_hashtable.c b/src/SDL_hashtable.c index 168fe1e30b..d233ce5949 100644 --- a/src/SDL_hashtable.c +++ b/src/SDL_hashtable.c @@ -318,6 +318,11 @@ bool SDL_KeyMatchID(const void *a, const void *b, void *unused) return false; } +void SDL_NukeFreeKey(const void *key, const void *value, void *unused) +{ + SDL_free((void *)key); +} + void SDL_NukeFreeValue(const void *key, const void *value, void *unused) { SDL_free((void *)value); diff --git a/src/SDL_hashtable.h b/src/SDL_hashtable.h index c897e07c31..55b6d53e86 100644 --- a/src/SDL_hashtable.h +++ b/src/SDL_hashtable.h @@ -55,6 +55,7 @@ extern bool SDL_KeyMatchString(const void *a, const void *b, void *unused); extern Uint32 SDL_HashID(const void *key, void *unused); extern bool SDL_KeyMatchID(const void *a, const void *b, void *unused); +extern void SDL_NukeFreeKey(const void *key, const void *value, void *unused); extern void SDL_NukeFreeValue(const void *key, const void *value, void *unused); #endif // SDL_hashtable_h_ diff --git a/src/SDL_hints.c b/src/SDL_hints.c index 8dd9c551cc..a91877bbaa 100644 --- a/src/SDL_hints.c +++ b/src/SDL_hints.c @@ -72,7 +72,7 @@ SDL_bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPr return SDL_InvalidParamError("name"); } - const char *env = SDL_getenv(name); + const char *env = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), name); if (env && (priority < SDL_HINT_OVERRIDE)) { return SDL_SetError("An environment variable is taking priority"); } @@ -126,7 +126,7 @@ SDL_bool SDL_ResetHint(const char *name) return SDL_InvalidParamError("name"); } - const char *env = SDL_getenv(name); + const char *env = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), name); const SDL_PropertiesID hints = GetHintProperties(false); if (!hints) { @@ -165,7 +165,7 @@ static void SDLCALL ResetHintsCallback(void *userdata, SDL_PropertiesID hints, c return; // uh...okay. } - const char *env = SDL_getenv(name); + const char *env = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), name); if ((!env && hint->value) || (env && !hint->value) || (env && SDL_strcmp(env, hint->value) != 0)) { SDL_HintWatch *entry = hint->callbacks; while (entry) { @@ -196,7 +196,7 @@ const char *SDL_GetHint(const char *name) return NULL; } - const char *result = SDL_getenv(name); + const char *result = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), name); const SDL_PropertiesID hints = GetHintProperties(false); if (hints) { diff --git a/src/audio/SDL_audiodev.c b/src/audio/SDL_audiodev.c index f48a5b25d0..f5dc4b20e9 100644 --- a/src/audio/SDL_audiodev.c +++ b/src/audio/SDL_audiodev.c @@ -87,7 +87,7 @@ static void SDL_EnumUnixAudioDevices_Internal(const bool recording, const bool c } // Figure out what our audio device is - audiodev = SDL_getenv("AUDIODEV"); + audiodev = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "AUDIODEV"); if (!audiodev) { if (classic) { audiodev = SDL_PATH_DEV_AUDIO; diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index e24eaea13c..61baf17101 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -1524,7 +1524,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)( const char *utfname = (*env)->GetStringUTFChars(env, name, NULL); const char *utfvalue = (*env)->GetStringUTFChars(env, value, NULL); - SDL_setenv(utfname, utfvalue, 1); + // This is only called at startup, to initialize the environment + SDL_setenv_unsafe(utfname, utfvalue, 1); (*env)->ReleaseStringUTFChars(env, name, utfname); (*env)->ReleaseStringUTFChars(env, value, utfvalue); diff --git a/src/core/linux/SDL_ibus.c b/src/core/linux/SDL_ibus.c index dbbc3e1740..62daaf3a5f 100644 --- a/src/core/linux/SDL_ibus.c +++ b/src/core/linux/SDL_ibus.c @@ -331,14 +331,14 @@ static char *IBus_GetDBusAddressFilename(void) } // Use this environment variable if it exists. - addr = SDL_getenv("IBUS_ADDRESS"); + addr = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "IBUS_ADDRESS"); if (addr && *addr) { return SDL_strdup(addr); } /* Otherwise, we have to get the hostname, display, machine id, config dir and look up the address from a filepath using all those bits, eek. */ - disp_env = SDL_getenv("DISPLAY"); + disp_env = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "DISPLAY"); if (!disp_env || !*disp_env) { display = SDL_strdup(":0.0"); @@ -363,7 +363,7 @@ static char *IBus_GetDBusAddressFilename(void) } if (!*host) { - const char *session = SDL_getenv("XDG_SESSION_TYPE"); + const char *session = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XDG_SESSION_TYPE"); if (session && SDL_strcmp(session, "wayland") == 0) { host = "unix-wayland"; } else { @@ -373,11 +373,11 @@ static char *IBus_GetDBusAddressFilename(void) SDL_memset(config_dir, 0, sizeof(config_dir)); - conf_env = SDL_getenv("XDG_CONFIG_HOME"); + conf_env = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XDG_CONFIG_HOME"); if (conf_env && *conf_env) { SDL_strlcpy(config_dir, conf_env, sizeof(config_dir)); } else { - const char *home_env = SDL_getenv("HOME"); + const char *home_env = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "HOME"); if (!home_env || !*home_env) { SDL_free(display); return NULL; diff --git a/src/core/linux/SDL_ime.c b/src/core/linux/SDL_ime.c index a853618bb4..a371e658e1 100644 --- a/src/core/linux/SDL_ime.c +++ b/src/core/linux/SDL_ime.c @@ -44,8 +44,8 @@ static void InitIME(void) { static bool inited = false; #ifdef HAVE_FCITX - const char *im_module = SDL_getenv("SDL_IM_MODULE"); - const char *xmodifiers = SDL_getenv("XMODIFIERS"); + const char *im_module = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "SDL_IM_MODULE"); + const char *xmodifiers = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XMODIFIERS"); #endif if (inited == true) { diff --git a/src/core/linux/SDL_sandbox.c b/src/core/linux/SDL_sandbox.c index 413148fc7b..797d36c1ef 100644 --- a/src/core/linux/SDL_sandbox.c +++ b/src/core/linux/SDL_sandbox.c @@ -33,7 +33,9 @@ SDL_Sandbox SDL_DetectSandbox(void) /* For Snap, we check multiple variables because they might be set for * unrelated reasons. This is the same thing WebKitGTK does. */ - if (SDL_getenv("SNAP") != NULL && SDL_getenv("SNAP_NAME") != NULL && SDL_getenv("SNAP_REVISION") != NULL) { + if (SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "SNAP") != NULL && + SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "SNAP_NAME") != NULL && + SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "SNAP_REVISION") != NULL) { return SDL_SANDBOX_SNAP; } diff --git a/src/dialog/unix/SDL_zenitydialog.c b/src/dialog/unix/SDL_zenitydialog.c index 131352e7d9..b77593aef2 100644 --- a/src/dialog/unix/SDL_zenitydialog.c +++ b/src/dialog/unix/SDL_zenitydialog.c @@ -229,12 +229,12 @@ static void run_zenity(zenityArgs* arg_struct) /* Recent versions of Zenity have different exit codes, but picks up different codes from the environment */ - SDL_setenv("ZENITY_OK", "0", 1); - SDL_setenv("ZENITY_CANCEL", "1", 1); - SDL_setenv("ZENITY_ESC", "1", 1); - SDL_setenv("ZENITY_EXTRA", "2", 1); - SDL_setenv("ZENITY_ERROR", "2", 1); - SDL_setenv("ZENITY_TIMEOUT", "2", 1); + SDL_setenv_unsafe("ZENITY_OK", "0", 1); + SDL_setenv_unsafe("ZENITY_CANCEL", "1", 1); + SDL_setenv_unsafe("ZENITY_ESC", "1", 1); + SDL_setenv_unsafe("ZENITY_EXTRA", "2", 1); + SDL_setenv_unsafe("ZENITY_ERROR", "2", 1); + SDL_setenv_unsafe("ZENITY_TIMEOUT", "2", 1); execv(args[0], args); diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c index b67b6cb4eb..f963c396db 100644 --- a/src/dynapi/SDL_dynapi.c +++ b/src/dynapi/SDL_dynapi.c @@ -351,7 +351,7 @@ static Sint32 initialize_jumptable(Uint32 apiver, void *table, Uint32 tablesize) // Init our jump table first. #if ENABLE_SDL_CALL_LOGGING { - const char *env = SDL_getenv_REAL("SDL_DYNAPI_LOG_CALLS"); + const char *env = SDL_getenv_unsafe_REAL("SDL_DYNAPI_LOG_CALLS"); const SDL_bool log_calls = (env && SDL_atoi_REAL(env)); if (log_calls) { #define SDL_DYNAPI_PROC(rc, fn, params, args, ret) jump_table.fn = fn##_LOGSDLCALLS; @@ -461,7 +461,7 @@ extern SDL_NORETURN void SDL_ExitProcess(int exitcode); static void SDL_InitDynamicAPILocked(void) { - const char *libname = SDL_getenv_REAL(SDL_DYNAMIC_API_ENVVAR); + const char *libname = SDL_getenv_unsafe_REAL(SDL_DYNAMIC_API_ENVVAR); SDL_DYNAPI_ENTRYFN entry = NULL; // funcs from here by default. SDL_bool use_internal = SDL_TRUE; diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index e44ed771ad..21b51d2db3 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -52,6 +52,7 @@ SDL3_0.0.0 { SDL_BroadcastCondition; SDL_CaptureMouse; SDL_ClaimWindowForGPUDevice; + SDL_CleanupEnvironment; SDL_CleanupTLS; SDL_ClearAudioStream; SDL_ClearClipboardData; @@ -84,6 +85,7 @@ SDL3_0.0.0 { SDL_CreateCondition; SDL_CreateCursor; SDL_CreateDirectory; + SDL_CreateEnvironment; SDL_CreateGPUBuffer; SDL_CreateGPUComputePipeline; SDL_CreateGPUDevice; @@ -125,6 +127,7 @@ SDL3_0.0.0 { SDL_DestroyAudioStream; SDL_DestroyCondition; SDL_DestroyCursor; + SDL_DestroyEnvironment; SDL_DestroyGPUDevice; SDL_DestroyHapticEffect; SDL_DestroyMutex; @@ -276,6 +279,9 @@ SDL3_0.0.0 { SDL_GetDisplayProperties; SDL_GetDisplayUsableBounds; SDL_GetDisplays; + SDL_GetEnvironment; + SDL_GetEnvironmentVariable; + SDL_GetEnvironmentVariables; SDL_GetError; SDL_GetEventFilter; SDL_GetFloatProperty; @@ -785,6 +791,7 @@ SDL3_0.0.0 { SDL_SetClipboardData; SDL_SetClipboardText; SDL_SetCursor; + SDL_SetEnvironmentVariable; SDL_SetError; SDL_SetEventEnabled; SDL_SetEventFilter; @@ -933,6 +940,7 @@ SDL3_0.0.0 { SDL_UnlockTexture; SDL_UnmapGPUTransferBuffer; SDL_UnregisterApp; + SDL_UnsetEnvironmentVariable; SDL_UpdateGamepads; SDL_UpdateHapticEffect; SDL_UpdateJoysticks; @@ -1020,7 +1028,7 @@ SDL3_0.0.0 { SDL_fmod; SDL_fmodf; SDL_free; - SDL_getenv; + SDL_getenv_unsafe; SDL_hid_ble_scan; SDL_hid_close; SDL_hid_device_change_count; @@ -1095,7 +1103,7 @@ SDL3_0.0.0 { SDL_roundf; SDL_scalbn; SDL_scalbnf; - SDL_setenv; + SDL_setenv_unsafe; SDL_sin; SDL_sinf; SDL_snprintf; @@ -1138,7 +1146,7 @@ SDL3_0.0.0 { SDL_uitoa; SDL_ulltoa; SDL_ultoa; - SDL_unsetenv; + SDL_unsetenv_unsafe; SDL_utf8strlcpy; SDL_utf8strlen; SDL_utf8strnlen; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 74a4b0bd88..7aa3c9bdc0 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -77,6 +77,7 @@ #define SDL_BroadcastCondition SDL_BroadcastCondition_REAL #define SDL_CaptureMouse SDL_CaptureMouse_REAL #define SDL_ClaimWindowForGPUDevice SDL_ClaimWindowForGPUDevice_REAL +#define SDL_CleanupEnvironment SDL_CleanupEnvironment_REAL #define SDL_CleanupTLS SDL_CleanupTLS_REAL #define SDL_ClearAudioStream SDL_ClearAudioStream_REAL #define SDL_ClearClipboardData SDL_ClearClipboardData_REAL @@ -109,6 +110,7 @@ #define SDL_CreateCondition SDL_CreateCondition_REAL #define SDL_CreateCursor SDL_CreateCursor_REAL #define SDL_CreateDirectory SDL_CreateDirectory_REAL +#define SDL_CreateEnvironment SDL_CreateEnvironment_REAL #define SDL_CreateGPUBuffer SDL_CreateGPUBuffer_REAL #define SDL_CreateGPUComputePipeline SDL_CreateGPUComputePipeline_REAL #define SDL_CreateGPUDevice SDL_CreateGPUDevice_REAL @@ -150,6 +152,7 @@ #define SDL_DestroyAudioStream SDL_DestroyAudioStream_REAL #define SDL_DestroyCondition SDL_DestroyCondition_REAL #define SDL_DestroyCursor SDL_DestroyCursor_REAL +#define SDL_DestroyEnvironment SDL_DestroyEnvironment_REAL #define SDL_DestroyGPUDevice SDL_DestroyGPUDevice_REAL #define SDL_DestroyHapticEffect SDL_DestroyHapticEffect_REAL #define SDL_DestroyMutex SDL_DestroyMutex_REAL @@ -301,6 +304,9 @@ #define SDL_GetDisplayProperties SDL_GetDisplayProperties_REAL #define SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds_REAL #define SDL_GetDisplays SDL_GetDisplays_REAL +#define SDL_GetEnvironment SDL_GetEnvironment_REAL +#define SDL_GetEnvironmentVariable SDL_GetEnvironmentVariable_REAL +#define SDL_GetEnvironmentVariables SDL_GetEnvironmentVariables_REAL #define SDL_GetError SDL_GetError_REAL #define SDL_GetEventFilter SDL_GetEventFilter_REAL #define SDL_GetFloatProperty SDL_GetFloatProperty_REAL @@ -810,6 +816,7 @@ #define SDL_SetClipboardData SDL_SetClipboardData_REAL #define SDL_SetClipboardText SDL_SetClipboardText_REAL #define SDL_SetCursor SDL_SetCursor_REAL +#define SDL_SetEnvironmentVariable SDL_SetEnvironmentVariable_REAL #define SDL_SetError SDL_SetError_REAL #define SDL_SetEventEnabled SDL_SetEventEnabled_REAL #define SDL_SetEventFilter SDL_SetEventFilter_REAL @@ -958,6 +965,7 @@ #define SDL_UnlockTexture SDL_UnlockTexture_REAL #define SDL_UnmapGPUTransferBuffer SDL_UnmapGPUTransferBuffer_REAL #define SDL_UnregisterApp SDL_UnregisterApp_REAL +#define SDL_UnsetEnvironmentVariable SDL_UnsetEnvironmentVariable_REAL #define SDL_UpdateGamepads SDL_UpdateGamepads_REAL #define SDL_UpdateHapticEffect SDL_UpdateHapticEffect_REAL #define SDL_UpdateJoysticks SDL_UpdateJoysticks_REAL @@ -1045,7 +1053,7 @@ #define SDL_fmod SDL_fmod_REAL #define SDL_fmodf SDL_fmodf_REAL #define SDL_free SDL_free_REAL -#define SDL_getenv SDL_getenv_REAL +#define SDL_getenv_unsafe SDL_getenv_unsafe_REAL #define SDL_hid_ble_scan SDL_hid_ble_scan_REAL #define SDL_hid_close SDL_hid_close_REAL #define SDL_hid_device_change_count SDL_hid_device_change_count_REAL @@ -1120,7 +1128,7 @@ #define SDL_roundf SDL_roundf_REAL #define SDL_scalbn SDL_scalbn_REAL #define SDL_scalbnf SDL_scalbnf_REAL -#define SDL_setenv SDL_setenv_REAL +#define SDL_setenv_unsafe SDL_setenv_unsafe_REAL #define SDL_sin SDL_sin_REAL #define SDL_sinf SDL_sinf_REAL #define SDL_snprintf SDL_snprintf_REAL @@ -1163,7 +1171,7 @@ #define SDL_uitoa SDL_uitoa_REAL #define SDL_ulltoa SDL_ulltoa_REAL #define SDL_ultoa SDL_ultoa_REAL -#define SDL_unsetenv SDL_unsetenv_REAL +#define SDL_unsetenv_unsafe SDL_unsetenv_unsafe_REAL #define SDL_utf8strlcpy SDL_utf8strlcpy_REAL #define SDL_utf8strlen SDL_utf8strlen_REAL #define SDL_utf8strnlen SDL_utf8strnlen_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 29d5adc2c5..069d04ccc5 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -97,6 +97,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_BlitSurfaceUncheckedScaled,(SDL_Surface *a, const S SDL_DYNAPI_PROC(void,SDL_BroadcastCondition,(SDL_Condition *a),(a),) SDL_DYNAPI_PROC(SDL_bool,SDL_CaptureMouse,(SDL_bool a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_ClaimWindowForGPUDevice,(SDL_GPUDevice *a, SDL_Window *b),(a,b),return) +SDL_DYNAPI_PROC(void,SDL_CleanupEnvironment,(void),(),) SDL_DYNAPI_PROC(void,SDL_CleanupTLS,(void),(),) SDL_DYNAPI_PROC(SDL_bool,SDL_ClearAudioStream,(SDL_AudioStream *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_ClearClipboardData,(void),(),return) @@ -129,6 +130,7 @@ SDL_DYNAPI_PROC(SDL_Cursor*,SDL_CreateColorCursor,(SDL_Surface *a, int b, int c) SDL_DYNAPI_PROC(SDL_Condition*,SDL_CreateCondition,(void),(),return) SDL_DYNAPI_PROC(SDL_Cursor*,SDL_CreateCursor,(const Uint8 *a, const Uint8 *b, int c, int d, int e, int f),(a,b,c,d,e,f),return) SDL_DYNAPI_PROC(SDL_bool,SDL_CreateDirectory,(const char *a),(a),return) +SDL_DYNAPI_PROC(SDL_Environment*,SDL_CreateEnvironment,(SDL_bool a),(a),return) SDL_DYNAPI_PROC(SDL_GPUBuffer*,SDL_CreateGPUBuffer,(SDL_GPUDevice *a, const SDL_GPUBufferCreateInfo* b),(a,b),return) SDL_DYNAPI_PROC(SDL_GPUComputePipeline*,SDL_CreateGPUComputePipeline,(SDL_GPUDevice *a, const SDL_GPUComputePipelineCreateInfo *b),(a,b),return) SDL_DYNAPI_PROC(SDL_GPUDevice*,SDL_CreateGPUDevice,(SDL_GPUShaderFormat a, SDL_bool b, const char *c),(a,b,c),return) @@ -170,6 +172,7 @@ SDL_DYNAPI_PROC(void,SDL_DelayNS,(Uint64 a),(a),) SDL_DYNAPI_PROC(void,SDL_DestroyAudioStream,(SDL_AudioStream *a),(a),) SDL_DYNAPI_PROC(void,SDL_DestroyCondition,(SDL_Condition *a),(a),) SDL_DYNAPI_PROC(void,SDL_DestroyCursor,(SDL_Cursor *a),(a),) +SDL_DYNAPI_PROC(void,SDL_DestroyEnvironment,(SDL_Environment *a),(a),) SDL_DYNAPI_PROC(void,SDL_DestroyGPUDevice,(SDL_GPUDevice *a),(a),) SDL_DYNAPI_PROC(void,SDL_DestroyHapticEffect,(SDL_Haptic *a, int b),(a,b),) SDL_DYNAPI_PROC(void,SDL_DestroyMutex,(SDL_Mutex *a),(a),) @@ -321,6 +324,9 @@ SDL_DYNAPI_PROC(const char*,SDL_GetDisplayName,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetDisplayProperties,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_GetDisplayUsableBounds,(SDL_DisplayID a, SDL_Rect *b),(a,b),return) SDL_DYNAPI_PROC(SDL_DisplayID*,SDL_GetDisplays,(int *a),(a),return) +SDL_DYNAPI_PROC(SDL_Environment*,SDL_GetEnvironment,(void),(),return) +SDL_DYNAPI_PROC(const char*,SDL_GetEnvironmentVariable,(SDL_Environment *a, const char *b),(a,b),return) +SDL_DYNAPI_PROC(char**,SDL_GetEnvironmentVariables,(SDL_Environment *a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetError,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_GetEventFilter,(SDL_EventFilter *a, void **b),(a,b),return) SDL_DYNAPI_PROC(float,SDL_GetFloatProperty,(SDL_PropertiesID a, const char *b, float c),(a,b,c),return) @@ -821,6 +827,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_SetBooleanProperty,(SDL_PropertiesID a, const char SDL_DYNAPI_PROC(SDL_bool,SDL_SetClipboardData,(SDL_ClipboardDataCallback a, SDL_ClipboardCleanupCallback b, void *c, const char **d, size_t e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(SDL_bool,SDL_SetClipboardText,(const char *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_SetCursor,(SDL_Cursor *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_SetEnvironmentVariable,(SDL_Environment *a, const char *b, const char *c, SDL_bool d),(a,b,c,d),return) SDL_DYNAPI_PROC(void,SDL_SetEventEnabled,(Uint32 a, SDL_bool b),(a,b),) SDL_DYNAPI_PROC(void,SDL_SetEventFilter,(SDL_EventFilter a, void *b),(a,b),) SDL_DYNAPI_PROC(SDL_bool,SDL_SetFloatProperty,(SDL_PropertiesID a, const char *b, float c),(a,b,c),return) @@ -968,6 +975,7 @@ SDL_DYNAPI_PROC(void,SDL_UnlockSurface,(SDL_Surface *a),(a),) SDL_DYNAPI_PROC(void,SDL_UnlockTexture,(SDL_Texture *a),(a),) SDL_DYNAPI_PROC(void,SDL_UnmapGPUTransferBuffer,(SDL_GPUDevice *a, SDL_GPUTransferBuffer *b),(a,b),) SDL_DYNAPI_PROC(void,SDL_UnregisterApp,(void),(),) +SDL_DYNAPI_PROC(SDL_bool,SDL_UnsetEnvironmentVariable,(SDL_Environment *a, const char *b),(a,b),return) SDL_DYNAPI_PROC(void,SDL_UpdateGamepads,(void),(),) SDL_DYNAPI_PROC(SDL_bool,SDL_UpdateHapticEffect,(SDL_Haptic *a, int b, const SDL_HapticEffect *c),(a,b,c),return) SDL_DYNAPI_PROC(void,SDL_UpdateJoysticks,(void),(),) @@ -1054,7 +1062,7 @@ SDL_DYNAPI_PROC(float,SDL_floorf,(float a),(a),return) SDL_DYNAPI_PROC(double,SDL_fmod,(double a, double b),(a,b),return) SDL_DYNAPI_PROC(float,SDL_fmodf,(float a, float b),(a,b),return) SDL_DYNAPI_PROC(void,SDL_free,(void *a),(a),) -SDL_DYNAPI_PROC(const char*,SDL_getenv,(const char *a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_getenv_unsafe,(const char *a),(a),return) SDL_DYNAPI_PROC(void,SDL_hid_ble_scan,(SDL_bool a),(a),) SDL_DYNAPI_PROC(int,SDL_hid_close,(SDL_hid_device *a),(a),return) SDL_DYNAPI_PROC(Uint32,SDL_hid_device_change_count,(void),(),return) @@ -1129,7 +1137,7 @@ SDL_DYNAPI_PROC(double,SDL_round,(double a),(a),return) SDL_DYNAPI_PROC(float,SDL_roundf,(float a),(a),return) SDL_DYNAPI_PROC(double,SDL_scalbn,(double a, int b),(a,b),return) SDL_DYNAPI_PROC(float,SDL_scalbnf,(float a, int b),(a,b),return) -SDL_DYNAPI_PROC(int,SDL_setenv,(const char *a, const char *b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_setenv_unsafe,(const char *a, const char *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(double,SDL_sin,(double a),(a),return) SDL_DYNAPI_PROC(float,SDL_sinf,(float a),(a),return) SDL_DYNAPI_PROC(double,SDL_sqrt,(double a),(a),return) @@ -1169,7 +1177,7 @@ SDL_DYNAPI_PROC(float,SDL_truncf,(float a),(a),return) SDL_DYNAPI_PROC(char*,SDL_uitoa,(unsigned int a, char *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(char*,SDL_ulltoa,(unsigned long long a, char *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(char*,SDL_ultoa,(unsigned long a, char *b, int c),(a,b,c),return) -SDL_DYNAPI_PROC(int,SDL_unsetenv,(const char *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_unsetenv_unsafe,(const char *a),(a),return) SDL_DYNAPI_PROC(size_t,SDL_utf8strlcpy,(SDL_OUT_Z_CAP(c) char *a, const char *b, size_t c),(a,b,c),return) SDL_DYNAPI_PROC(size_t,SDL_utf8strlen,(const char *a),(a),return) SDL_DYNAPI_PROC(size_t,SDL_utf8strnlen,(const char *a, size_t b),(a,b),return) diff --git a/src/filesystem/cocoa/SDL_sysfilesystem.m b/src/filesystem/cocoa/SDL_sysfilesystem.m index 07a75ff74e..c88ad1c1ad 100644 --- a/src/filesystem/cocoa/SDL_sysfilesystem.m +++ b/src/filesystem/cocoa/SDL_sysfilesystem.m @@ -144,7 +144,7 @@ char *SDL_SYS_GetUserFolder(SDL_Folder folder) switch (folder) { case SDL_FOLDER_HOME: - base = SDL_getenv("HOME"); + base = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "HOME"); if (!base) { SDL_SetError("No $HOME environment variable available"); diff --git a/src/filesystem/emscripten/SDL_sysfilesystem.c b/src/filesystem/emscripten/SDL_sysfilesystem.c index e10081c775..8e228203c4 100644 --- a/src/filesystem/emscripten/SDL_sysfilesystem.c +++ b/src/filesystem/emscripten/SDL_sysfilesystem.c @@ -93,7 +93,7 @@ char *SDL_SYS_GetUserFolder(SDL_Folder folder) return NULL; } - home = SDL_getenv("HOME"); + home = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "HOME"); if (!home) { SDL_SetError("No $HOME environment variable available"); return NULL; diff --git a/src/filesystem/haiku/SDL_sysfilesystem.cc b/src/filesystem/haiku/SDL_sysfilesystem.cc index 60e7d5b09d..e8f7071559 100644 --- a/src/filesystem/haiku/SDL_sysfilesystem.cc +++ b/src/filesystem/haiku/SDL_sysfilesystem.cc @@ -68,7 +68,7 @@ char *SDL_SYS_GetBasePath(void) char *SDL_SYS_GetPrefPath(const char *org, const char *app) { // !!! FIXME: is there a better way to do this? - const char *home = SDL_getenv("HOME"); + const char *home = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "HOME"); const char *append = "/config/settings/"; size_t len = SDL_strlen(home); @@ -102,7 +102,7 @@ char *SDL_SYS_GetUserFolder(SDL_Folder folder) const char *home = NULL; char *result; - home = SDL_getenv("HOME"); + home = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "HOME"); if (!home) { SDL_SetError("No $HOME environment variable available"); return NULL; diff --git a/src/filesystem/unix/SDL_sysfilesystem.c b/src/filesystem/unix/SDL_sysfilesystem.c index 630620e399..80938c47c5 100644 --- a/src/filesystem/unix/SDL_sysfilesystem.c +++ b/src/filesystem/unix/SDL_sysfilesystem.c @@ -74,7 +74,7 @@ static char *readSymLink(const char *path) #ifdef SDL_PLATFORM_OPENBSD static char *search_path_for_binary(const char *bin) { - const char *envr_real = SDL_getenv("PATH"); + const char *envr_real = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "PATH"); char *envr; size_t alloc_size; char *exe = NULL; @@ -163,7 +163,7 @@ char *SDL_SYS_GetBasePath(void) exe = search_path_for_binary(cmdline[0]); } else { if (exe && *exe == '.') { - const char *pwd = SDL_getenv("PWD"); + const char *pwd = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "PWD"); if (pwd && *pwd) { SDL_asprintf(&pwddst, "%s/%s", pwd, exe); } @@ -265,7 +265,7 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app) * * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html */ - const char *envr = SDL_getenv("XDG_DATA_HOME"); + const char *envr = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XDG_DATA_HOME"); const char *append; char *result = NULL; char *ptr = NULL; @@ -281,7 +281,7 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app) if (!envr) { // You end up with "$HOME/.local/share/Game Name 2" - envr = SDL_getenv("HOME"); + envr = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "HOME"); if (!envr) { // we could take heroic measures with /etc/passwd, but oh well. SDL_SetError("neither XDG_DATA_HOME nor HOME environment is set"); @@ -368,12 +368,12 @@ static char *xdg_user_dir_lookup_with_fallback (const char *type, const char *fa int relative; size_t l; - home_dir = SDL_getenv ("HOME"); + home_dir = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "HOME"); if (!home_dir) goto error; - config_home = SDL_getenv ("XDG_CONFIG_HOME"); + config_home = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XDG_CONFIG_HOME"); if (!config_home || config_home[0] == 0) { l = SDL_strlen (home_dir) + SDL_strlen ("/.config/user-dirs.dirs") + 1; @@ -495,7 +495,7 @@ static char *xdg_user_dir_lookup (const char *type) if (dir) return dir; - home_dir = SDL_getenv("HOME"); + home_dir = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "HOME"); if (!home_dir) return NULL; @@ -533,7 +533,7 @@ char *SDL_SYS_GetUserFolder(SDL_Folder folder) */ switch(folder) { case SDL_FOLDER_HOME: - param = SDL_getenv("HOME"); + param = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "HOME"); if (!param) { SDL_SetError("No $HOME environment variable available"); diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index 156c02f241..2dadbb2d9b 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -11591,7 +11591,7 @@ static Uint8 VULKAN_INTERNAL_CreateLogicalDevice( static void VULKAN_INTERNAL_LoadEntryPoints(void) { // Required for MoltenVK support - SDL_setenv("MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE", "1", 1); + SDL_setenv_unsafe("MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE", "1", 1); // Load Vulkan entry points if (!SDL_Vulkan_LoadLibrary(NULL)) { diff --git a/src/haptic/SDL_haptic.c b/src/haptic/SDL_haptic.c index 2f6ef78ea1..c40afacbf2 100644 --- a/src/haptic/SDL_haptic.c +++ b/src/haptic/SDL_haptic.c @@ -537,7 +537,7 @@ SDL_bool SDL_SetHapticGain(SDL_Haptic *haptic, int gain) } // The user can use an environment variable to override the max gain. - env = SDL_getenv("SDL_HAPTIC_GAIN_MAX"); + env = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "SDL_HAPTIC_GAIN_MAX"); if (env) { max_gain = SDL_atoi(env); diff --git a/src/locale/unix/SDL_syslocale.c b/src/locale/unix/SDL_syslocale.c index e945da5c86..ac4301dc1a 100644 --- a/src/locale/unix/SDL_syslocale.c +++ b/src/locale/unix/SDL_syslocale.c @@ -78,13 +78,13 @@ bool SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) *tmp = '\0'; // LANG is the primary locale (maybe) - envr = SDL_getenv("LANG"); + envr = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "LANG"); if (envr) { SDL_strlcpy(tmp, envr, buflen); } // fallback languages - envr = SDL_getenv("LANGUAGE"); + envr = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "LANGUAGE"); if (envr) { if (*tmp) { SDL_strlcat(tmp, ":", buflen); diff --git a/src/main/emscripten/SDL_sysmain_runapp.c b/src/main/emscripten/SDL_sysmain_runapp.c index 6eda160962..db75e29213 100644 --- a/src/main/emscripten/SDL_sysmain_runapp.c +++ b/src/main/emscripten/SDL_sysmain_runapp.c @@ -48,7 +48,7 @@ int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserv _free(cvalue); } } - }, SDL_setenv); + }, SDL_setenv_unsafe); return mainFunction(argc, argv); } diff --git a/src/misc/unix/SDL_sysurl.c b/src/misc/unix/SDL_sysurl.c index 670a099b23..681c0deccc 100644 --- a/src/misc/unix/SDL_sysurl.c +++ b/src/misc/unix/SDL_sysurl.c @@ -41,7 +41,7 @@ bool SDL_SYS_OpenURL(const char *url) pid_t pid2; const char *args[] = { "xdg-open", url, NULL }; // Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam - SDL_unsetenv("LD_PRELOAD"); + SDL_unsetenv_unsafe("LD_PRELOAD"); if (posix_spawnp(&pid2, args[0], NULL, NULL, (char **)args, environ) == 0) { // Child process doesn't wait for possibly-blocking grandchild. _exit(EXIT_SUCCESS); @@ -51,7 +51,7 @@ bool SDL_SYS_OpenURL(const char *url) #else pid_t pid2; // Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam - SDL_unsetenv("LD_PRELOAD"); + SDL_unsetenv_unsafe("LD_PRELOAD"); // Notice this is vfork and not fork! pid2 = vfork(); if (pid2 == 0) { // Grandchild process will try to launch the url diff --git a/src/process/posix/SDL_posixprocess.c b/src/process/posix/SDL_posixprocess.c index 69cc802360..35cc6a5dbd 100644 --- a/src/process/posix/SDL_posixprocess.c +++ b/src/process/posix/SDL_posixprocess.c @@ -35,15 +35,6 @@ #include "../SDL_sysprocess.h" #include "../../file/SDL_iostream_c.h" -#if defined(SDL_PLATFORM_MACOS) -#include -#define environ (*_NSGetEnviron()) -#elif defined(SDL_PLATFORM_FREEBSD) -#include -#define environ ((char **)dlsym(RTLD_DEFAULT, "environ")) -#else -extern char **environ; -#endif #define READ_END 0 #define WRITE_END 1 @@ -114,7 +105,7 @@ static bool GetStreamFD(SDL_PropertiesID props, const char *property, int *resul bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID props) { char * const *args = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, NULL); - char * const *env = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, environ); + char * const *env = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, NULL); SDL_ProcessIO stdin_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDIN_NUMBER, SDL_PROCESS_STDIO_NULL); SDL_ProcessIO stdout_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER, SDL_PROCESS_STDIO_INHERITED); SDL_ProcessIO stderr_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDERR_NUMBER, SDL_PROCESS_STDIO_INHERITED); @@ -124,6 +115,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID int stdout_pipe[2] = { -1, -1 }; int stderr_pipe[2] = { -1, -1 }; int fd = -1; + char **env_copy = NULL; // Keep the malloc() before exec() so that an OOM won't run a process at all SDL_ProcessData *data = SDL_calloc(1, sizeof(*data)); @@ -278,6 +270,11 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID } } + if (!env) { + env_copy = SDL_GetEnvironmentVariables(SDL_GetEnvironment()); + env = env_copy; + } + // Spawn the new process if (posix_spawnp(&data->pid, args[0], &fa, &attr, args, env) != 0) { SDL_SetError("posix_spawn failed: %s", strerror(errno)); @@ -308,6 +305,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID posix_spawn_file_actions_destroy(&fa); posix_spawnattr_destroy(&attr); + SDL_free(env_copy); return true; @@ -338,6 +336,7 @@ posix_spawn_fail_none: if (stderr_pipe[WRITE_END] >= 0) { close(stderr_pipe[WRITE_END]); } + SDL_free(env_copy); return false; } diff --git a/src/process/windows/SDL_windowsprocess.c b/src/process/windows/SDL_windowsprocess.c index 7c96514289..2ae13022a2 100644 --- a/src/process/windows/SDL_windowsprocess.c +++ b/src/process/windows/SDL_windowsprocess.c @@ -186,6 +186,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID HANDLE stdin_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; HANDLE stdout_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; HANDLE stderr_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; + char **env_copy = NULL; bool result = false; // Keep the malloc() before exec() so that an OOM won't run a process at all @@ -199,6 +200,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID goto done; } + if (!env) { + env_copy = SDL_GetEnvironmentVariables(SDL_GetEnvironment()); + env = (const char * const *)env_copy; + } if (!join_env(env, &createprocess_env)) { goto done; } @@ -381,6 +386,7 @@ done: } SDL_free(createprocess_cmdline); SDL_free(createprocess_env); + SDL_free(env_copy); if (!result) { if (stdin_pipe[WRITE_END] != INVALID_HANDLE_VALUE) { diff --git a/src/stdlib/SDL_getenv.c b/src/stdlib/SDL_getenv.c index 1fcdb64e8b..7c0beb6e5c 100644 --- a/src/stdlib/SDL_getenv.c +++ b/src/stdlib/SDL_getenv.c @@ -21,6 +21,7 @@ #include "SDL_internal.h" #include "SDL_getenv_c.h" +#include "../SDL_hashtable.h" #if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) #include "../core/windows/SDL_windows.h" @@ -40,11 +41,23 @@ #define HAVE_LOCAL_ENVIRONMENT #endif +#if !defined(SDL_PLATFORM_WINDOWS) +#if defined(SDL_PLATFORM_MACOS) +#include +#define environ (*_NSGetEnviron()) +#elif defined(SDL_PLATFORM_FREEBSD) +#include +#define environ ((char **)dlsym(RTLD_DEFAULT, "environ")) +#else +extern char **environ; +#endif +#endif // !SDL_PLATFORM_WINDOWS + // Put a variable into the environment // Note: Name may not contain a '=' character. (Reference: http://www.unix.com/man-page/Linux/3/setenv/) #ifdef HAVE_LIBC_ENVIRONMENT #if defined(HAVE_SETENV) -int SDL_setenv(const char *name, const char *value, int overwrite) +int SDL_setenv_unsafe(const char *name, const char *value, int overwrite) { // Input validation if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) { @@ -55,7 +68,7 @@ int SDL_setenv(const char *name, const char *value, int overwrite) } // We have a real environment table, but no real setenv? Fake it w/ putenv. #else -int SDL_setenv(const char *name, const char *value, int overwrite) +int SDL_setenv_unsafe(const char *name, const char *value, int overwrite) { char *new_variable; @@ -79,7 +92,7 @@ int SDL_setenv(const char *name, const char *value, int overwrite) } #endif #elif defined(HAVE_WIN32_ENVIRONMENT) -int SDL_setenv(const char *name, const char *value, int overwrite) +int SDL_setenv_unsafe(const char *name, const char *value, int overwrite) { // Input validation if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) { @@ -101,7 +114,7 @@ int SDL_setenv(const char *name, const char *value, int overwrite) // We'll leak this, as environment variables are intended to persist past SDL_Quit() static char **SDL_env; -int SDL_setenv(const char *name, const char *value, int overwrite) +int SDL_setenv_unsafe(const char *name, const char *value, int overwrite) { int added; size_t len, i; @@ -114,7 +127,7 @@ int SDL_setenv(const char *name, const char *value, int overwrite) } // See if it already exists - if (!overwrite && SDL_getenv(name)) { + if (!overwrite && SDL_getenv_unsafe(name)) { return 0; } @@ -164,7 +177,7 @@ int SDL_setenv(const char *name, const char *value, int overwrite) #ifdef HAVE_LIBC_ENVIRONMENT #if defined(HAVE_UNSETENV) -int SDL_unsetenv(const char *name) +int SDL_unsetenv_unsafe(const char *name) { // Input validation if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL) { @@ -175,7 +188,7 @@ int SDL_unsetenv(const char *name) } // We have a real environment table, but no unsetenv? Fake it w/ putenv. #else -int SDL_unsetenv(const char *name) +int SDL_unsetenv_unsafe(const char *name) { // Input validation if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL) { @@ -187,7 +200,7 @@ int SDL_unsetenv(const char *name) } #endif #elif defined(HAVE_WIN32_ENVIRONMENT) -int SDL_unsetenv(const char *name) +int SDL_unsetenv_unsafe(const char *name) { // Input validation if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL) { @@ -200,7 +213,7 @@ int SDL_unsetenv(const char *name) return 0; } #else -int SDL_unsetenv(const char *name) +int SDL_unsetenv_unsafe(const char *name) { size_t len, i; @@ -226,7 +239,7 @@ int SDL_unsetenv(const char *name) // Retrieve a variable named "name" from the environment #ifdef HAVE_LIBC_ENVIRONMENT -const char *SDL_getenv(const char *name) +const char *SDL_getenv_unsafe(const char *name) { #ifdef SDL_PLATFORM_ANDROID // Make sure variables from the application manifest are available @@ -241,7 +254,7 @@ const char *SDL_getenv(const char *name) return getenv(name); } #elif defined(HAVE_WIN32_ENVIRONMENT) -const char *SDL_getenv(const char *name) +const char *SDL_getenv_unsafe(const char *name) { DWORD length, maxlen = 0; char *string = NULL; @@ -280,7 +293,7 @@ const char *SDL_getenv(const char *name) return result; } #else -const char *SDL_getenv(const char *name) +const char *SDL_getenv_unsafe(const char *name) { size_t len, i; char *value; @@ -304,3 +317,244 @@ const char *SDL_getenv(const char *name) return value; } #endif // HAVE_LIBC_ENVIRONMENT + + +struct SDL_Environment +{ + SDL_Mutex *lock; + SDL_HashTable *strings; +}; +static SDL_Environment *SDL_environment; + +SDL_Environment *SDL_GetEnvironment(void) +{ + if (!SDL_environment) { + SDL_environment = SDL_CreateEnvironment(false); + } + return SDL_environment; +} + +void SDL_CleanupEnvironment(void) +{ + SDL_Environment *env = SDL_environment; + + if (env) { + SDL_environment = NULL; + SDL_DestroyEnvironment(env); + } +} + +SDL_Environment *SDL_CreateEnvironment(SDL_bool empty) +{ + SDL_Environment *env = SDL_calloc(1, sizeof(*env)); + if (!env) { + return NULL; + } + + env->strings = SDL_CreateHashTable(NULL, 16, SDL_HashString, SDL_KeyMatchString, SDL_NukeFreeKey, false); + if (!env->strings) { + SDL_free(env); + return NULL; + } + + // Don't fail if we can't create a mutex (e.g. on a single-thread environment) + env->lock = SDL_CreateMutex(); + + if (!empty) { +#ifdef SDL_PLATFORM_WINDOWS + LPWCH strings = GetEnvironmentStringsW(); + if (strings) { + for (LPWCH string = strings; *string; string += SDL_wcslen(string) + 1) { + char *variable = WIN_StringToUTF8W(string); + if (!variable) { + continue; + } + + char *value = SDL_strchr(variable, '='); + if (!value || value == variable) { + SDL_free(variable); + continue; + } + *value++ = '\0'; + + SDL_InsertIntoHashTable(env->strings, variable, value); + } + FreeEnvironmentStringsW(strings); + } +#else +#ifdef SDL_PLATFORM_ANDROID + // Make sure variables from the application manifest are available + Android_JNI_GetManifestEnvironmentVariables(); +#endif + char **strings = environ; + for (int i = 0; strings[i]; ++i) { + char *variable = SDL_strdup(strings[i]); + if (!variable) { + continue; + } + + char *value = SDL_strchr(variable, '='); + if (!value || value == variable) { + SDL_free(variable); + continue; + } + *value++ = '\0'; + + SDL_InsertIntoHashTable(env->strings, variable, value); + } +#endif // SDL_PLATFORM_WINDOWS + } + + return env; +} + +const char *SDL_GetEnvironmentVariable(SDL_Environment *env, const char *name) +{ + const char *result = NULL; + + if (!env) { + return NULL; + } else if (!name || *name == '\0') { + return NULL; + } + + SDL_LockMutex(env->lock); + { + const char *value; + + if (SDL_FindInHashTable(env->strings, name, (const void **)&value)) { + result = SDL_GetPersistentString(value); + } + } + SDL_UnlockMutex(env->lock); + + return result; +} + +char **SDL_GetEnvironmentVariables(SDL_Environment *env) +{ + char **result = NULL; + + if (!env) { + SDL_InvalidParamError("env"); + return NULL; + } + + SDL_LockMutex(env->lock); + { + size_t count, length = 0; + void *iter; + const char *key, *value; + + // First pass, get the size we need for all the strings + count = 0; + iter = NULL; + while (SDL_IterateHashTable(env->strings, (const void **)&key, (const void **)&value, &iter)) { + length += SDL_strlen(key) + 1 + SDL_strlen(value) + 1; + ++count; + } + + // Allocate memory for the strings + result = (char **)SDL_malloc((count + 1) * sizeof(*result) + length); + char *string = (char *)(result + count + 1); + + // Second pass, copy the strings + count = 0; + iter = NULL; + while (SDL_IterateHashTable(env->strings, (const void **)&key, (const void **)&value, &iter)) { + size_t len; + + result[count] = string; + len = SDL_strlen(key); + SDL_memcpy(string, key, len); + string += len; + *string++ = '='; + len = SDL_strlen(value); + SDL_memcpy(string, value, len); + string += len; + *string++ = '\0'; + ++count; + } + result[count] = NULL; + } + SDL_UnlockMutex(env->lock); + + return result; +} + +SDL_bool SDL_SetEnvironmentVariable(SDL_Environment *env, const char *name, const char *value, SDL_bool overwrite) +{ + bool result = false; + + if (!env) { + return SDL_InvalidParamError("env"); + } else if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL) { + return SDL_InvalidParamError("name"); + } else if (!value) { + return SDL_InvalidParamError("value"); + } + + SDL_LockMutex(env->lock); + { + const void *existing_value; + bool insert = true; + + if (SDL_FindInHashTable(env->strings, name, &existing_value)) { + if (!overwrite) { + result = true; + insert = false; + } else { + SDL_RemoveFromHashTable(env->strings, name); + } + } + + if (insert) { + char *string = NULL; + if (SDL_asprintf(&string, "%s=%s", name, value) > 0) { + size_t len = SDL_strlen(name); + string[len] = '\0'; + name = string; + value = string + len + 1; + result = SDL_InsertIntoHashTable(env->strings, name, value); + } + } + } + SDL_UnlockMutex(env->lock); + + return result; +} + +SDL_bool SDL_UnsetEnvironmentVariable(SDL_Environment *env, const char *name) +{ + bool result = false; + + if (!env) { + return SDL_InvalidParamError("env"); + } else if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL) { + return SDL_InvalidParamError("name"); + } + + SDL_LockMutex(env->lock); + { + const void *value; + if (SDL_FindInHashTable(env->strings, name, &value)) { + result = SDL_RemoveFromHashTable(env->strings, name); + } else { + result = true; + } + } + SDL_UnlockMutex(env->lock); + + return result; +} + +void SDL_DestroyEnvironment(SDL_Environment *env) +{ + if (!env || env == SDL_environment) { + return; + } + + SDL_DestroyMutex(env->lock); + SDL_DestroyHashTable(env->strings); + SDL_free(env); +} diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index e5d8fb5714..7aff8c59cd 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -163,15 +163,15 @@ static const char *getlocale(char *buffer, size_t bufsize) const char *lang; char *ptr; - lang = SDL_getenv("LC_ALL"); + lang = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "LC_ALL"); if (!lang) { - lang = SDL_getenv("LC_CTYPE"); + lang = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "LC_CTYPE"); } if (!lang) { - lang = SDL_getenv("LC_MESSAGES"); + lang = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "LC_MESSAGES"); } if (!lang) { - lang = SDL_getenv("LANG"); + lang = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "LANG"); } if (!lang || !*lang || SDL_strcmp(lang, "C") == 0) { lang = "ASCII"; diff --git a/src/test/SDL_test_memory.c b/src/test/SDL_test_memory.c index 98ee44fe15..7c7084b004 100644 --- a/src/test/SDL_test_memory.c +++ b/src/test/SDL_test_memory.c @@ -299,7 +299,7 @@ void SDLTest_TrackAllocations(void) #ifdef SDLTEST_UNWIND_NO_PROC_NAME_BY_IP do { /* Don't use SDL_GetHint: SDL_malloc is off limits. */ - const char *env_trackmem = SDL_getenv("SDL_TRACKMEM_SYMBOL_NAMES"); + const char *env_trackmem = SDL_getenv_unsafe("SDL_TRACKMEM_SYMBOL_NAMES"); if (env_trackmem) { if (SDL_strcasecmp(env_trackmem, "1") == 0 || SDL_strcasecmp(env_trackmem, "yes") == 0 || SDL_strcasecmp(env_trackmem, "true") == 0) { s_unwind_symbol_names = SDL_TRUE; diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index 53886b989c..3d35427959 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -341,7 +341,7 @@ static bool SDL_EGL_LoadLibraryInternal(SDL_VideoDevice *_this, const char *egl_ #if !defined(SDL_VIDEO_STATIC_ANGLE) && !defined(SDL_VIDEO_DRIVER_VITA) /* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */ - path = SDL_getenv("SDL_VIDEO_GL_DRIVER"); + path = SDL_getenv_unsafe("SDL_VIDEO_GL_DRIVER"); if (path) { opengl_dll_handle = SDL_LoadObject(path); } @@ -401,7 +401,7 @@ static bool SDL_EGL_LoadLibraryInternal(SDL_VideoDevice *_this, const char *egl_ if (egl_dll_handle) { SDL_UnloadObject(egl_dll_handle); } - path = SDL_getenv("SDL_VIDEO_EGL_DRIVER"); + path = SDL_getenv_unsafe("SDL_VIDEO_EGL_DRIVER"); if (!path) { path = DEFAULT_EGL; } diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index b209116d01..9b52619617 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1292,11 +1292,11 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, */ // Look up the preferred locale, falling back to "C" as default - locale = SDL_getenv("LC_ALL"); + locale = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "LC_ALL"); if (!locale) { - locale = SDL_getenv("LC_CTYPE"); + locale = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "LC_CTYPE"); if (!locale) { - locale = SDL_getenv("LANG"); + locale = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "LANG"); if (!locale) { locale = "C"; } diff --git a/src/video/wayland/SDL_waylandmessagebox.c b/src/video/wayland/SDL_waylandmessagebox.c index bcc6c426ac..40edb3e782 100644 --- a/src/video/wayland/SDL_waylandmessagebox.c +++ b/src/video/wayland/SDL_waylandmessagebox.c @@ -141,8 +141,8 @@ bool Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *butto }; // Are we trying to connect to or are currently in a Wayland session? - if (!SDL_getenv("WAYLAND_DISPLAY")) { - const char *session = SDL_getenv("XDG_SESSION_TYPE"); + if (!SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "WAYLAND_DISPLAY")) { + const char *session = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XDG_SESSION_TYPE"); if (session && SDL_strcasecmp(session, "wayland") != 0) { return SDL_SetError("Not on a wayland display"); } diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c index 576e898a9c..b6f7e98248 100644 --- a/src/video/wayland/SDL_waylandmouse.c +++ b/src/video/wayland/SDL_waylandmouse.c @@ -345,7 +345,7 @@ static bool wayland_get_system_cursor(SDL_VideoData *vdata, SDL_CursorData *cdat // Fallback envvar if the DBus properties don't exist if (size <= 0) { - const char *xcursor_size = SDL_getenv("XCURSOR_SIZE"); + const char *xcursor_size = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XCURSOR_SIZE"); if (xcursor_size) { size = SDL_atoi(xcursor_size); } @@ -381,7 +381,7 @@ static bool wayland_get_system_cursor(SDL_VideoData *vdata, SDL_CursorData *cdat // Fallback envvar if the DBus properties don't exist if (!xcursor_theme) { - xcursor_theme = SDL_getenv("XCURSOR_THEME"); + xcursor_theme = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XCURSOR_THEME"); } theme = WAYLAND_wl_cursor_theme_load(xcursor_theme, size, vdata->shm); diff --git a/src/video/wayland/SDL_waylandshmbuffer.c b/src/video/wayland/SDL_waylandshmbuffer.c index 40ff2bd901..813f2ee6fe 100644 --- a/src/video/wayland/SDL_waylandshmbuffer.c +++ b/src/video/wayland/SDL_waylandshmbuffer.c @@ -80,7 +80,7 @@ static int CreateTempFD(off_t size) const char *xdg_path; char tmp_path[PATH_MAX]; - xdg_path = SDL_getenv("XDG_RUNTIME_DIR"); + xdg_path = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XDG_RUNTIME_DIR"); if (!xdg_path) { return -1; } diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index b57052ebc6..d893b4b43b 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -429,8 +429,8 @@ static SDL_VideoDevice *Wayland_CreateDevice(bool require_preferred_protocols) bool display_is_external = !!display; // Are we trying to connect to or are currently in a Wayland session? - if (!SDL_getenv("WAYLAND_DISPLAY")) { - const char *session = SDL_getenv("XDG_SESSION_TYPE"); + if (!SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "WAYLAND_DISPLAY")) { + const char *session = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XDG_SESSION_TYPE"); if (session && SDL_strcasecmp(session, "wayland") != 0) { return NULL; } diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 44a6d95031..d043b13c13 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -1914,14 +1914,14 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) /* Note that we don't check for empty strings, as that is still * considered a valid activation token! */ - const char *activation_token = SDL_getenv("XDG_ACTIVATION_TOKEN"); + const char *activation_token = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XDG_ACTIVATION_TOKEN"); if (activation_token) { xdg_activation_v1_activate(c->activation_manager, activation_token, data->surface); // Clear this variable, per the protocol's request - SDL_unsetenv("XDG_ACTIVATION_TOKEN"); + SDL_unsetenv_unsafe("XDG_ACTIVATION_TOKEN"); } } diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c index 1ec1df1d8c..e3e10636de 100644 --- a/src/video/x11/SDL_x11keyboard.c +++ b/src/video/x11/SDL_x11keyboard.c @@ -169,7 +169,7 @@ bool X11_InitKeyboard(SDL_VideoDevice *_this) char *prev_locale = setlocale(LC_ALL, NULL); char *prev_xmods = X11_XSetLocaleModifiers(NULL); const char *new_xmods = ""; - const char *env_xmods = SDL_getenv("XMODIFIERS"); + const char *env_xmods = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XMODIFIERS"); bool has_dbus_ime_support = false; if (prev_locale) { diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c index 1194af2c0e..aa8161e431 100644 --- a/src/video/x11/SDL_x11modes.c +++ b/src/video/x11/SDL_x11modes.c @@ -248,7 +248,7 @@ static float GetGlobalContentScale(SDL_VideoDevice *_this) // If that failed, try the GDK_SCALE envvar... if (scale_factor <= 0.0) { - const char *scale_str = SDL_getenv("GDK_SCALE"); + const char *scale_str = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "GDK_SCALE"); if (scale_str) { scale_factor = SDL_atoi(scale_str); } diff --git a/test/childprocess.c b/test/childprocess.c index d76534ee72..d66bf95164 100644 --- a/test/childprocess.c +++ b/test/childprocess.c @@ -5,14 +5,6 @@ #include #include -#if defined(SDL_PLATFORM_WINDOWS) -#include -#elif defined(SDL_PLATFORM_MACOS) -#include -#define environ (*_NSGetEnviron()) -#else -extern char **environ; -#endif int main(int argc, char *argv[]) { SDLTest_CommonState *state; @@ -95,26 +87,18 @@ int main(int argc, char *argv[]) { } if (print_environment || expect_environment) { - -#if defined(SDL_PLATFORM_WINDOWS) - char *original_env = GetEnvironmentStrings(); - const char *env = original_env; - for (; env[0]; env += SDL_strlen(env) + 1) { -#else - char **envp = environ; - for (; *envp; envp++) { - const char *env = *envp; -#endif - if (print_environment) { - fprintf(stdout, "%s\n", env); - } - if (expect_environment) { - expect_environment_match |= SDL_strcmp(env, expect_environment) == 0; + char **env = SDL_GetEnvironmentVariables(SDL_GetEnvironment()); + if (env) { + for (i = 0; env[i]; ++i) { + if (print_environment) { + fprintf(stdout, "%s\n", env[i]); + } + if (expect_environment) { + expect_environment_match |= SDL_strcmp(env[i], expect_environment) == 0; + } } + SDL_free(env); } -#ifdef SDL_PLATFORM_WINDOWS - FreeEnvironmentStringsA(original_env); -#endif } if (stdin_to_stdout || stdin_to_stderr) { diff --git a/test/testatomic.c b/test/testatomic.c index 9350d6c993..885f8db359 100644 --- a/test/testatomic.c +++ b/test/testatomic.c @@ -740,7 +740,7 @@ int main(int argc, char *argv[]) RunBasicTest(); - if (SDL_getenv("SDL_TESTS_QUICK") != NULL) { + if (SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "SDL_TESTS_QUICK") != NULL) { SDL_Log("Not running slower tests"); return 0; } diff --git a/test/testautomation_hints.c b/test/testautomation_hints.c index a6fb65d8eb..41ed3ce9c1 100644 --- a/test/testautomation_hints.c +++ b/test/testautomation_hints.c @@ -130,7 +130,7 @@ static int SDLCALL hints_setHint(void *arg) SDL_free(value); /* Set default value in environment */ - SDL_setenv(testHint, "original", 1); + SDL_SetEnvironmentVariable(SDL_GetEnvironment(), testHint, "original", 1); SDLTest_AssertPass("Call to SDL_GetHint() after saving and restoring hint"); originalValue = SDL_GetHint(testHint); diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c index 38bbb44d73..b21dac50d0 100644 --- a/test/testautomation_stdlib.c +++ b/test/testautomation_stdlib.c @@ -542,10 +542,11 @@ static int SDLCALL stdlib_swprintf(void *arg) #endif /** - * Call to SDL_getenv and SDL_setenv + * Call to SDL_GetEnvironmentVariable() and SDL_SetEnvironmentVariable() */ static int SDLCALL stdlib_getsetenv(void *arg) { + SDL_Environment *env = SDL_GetEnvironment(); const int nameLen = 16; char name[17]; int counter; @@ -556,7 +557,7 @@ static int SDLCALL stdlib_getsetenv(void *arg) int overwrite; const char *text; - /* Create a random name. This tests SDL_getenv, since we need to */ + /* Create a random name. This tests SDL_GetEnvironmentVariable, since we need to */ /* make sure the variable is not set yet (it shouldn't). */ do { for (counter = 0; counter < nameLen; counter++) { @@ -564,8 +565,8 @@ static int SDLCALL stdlib_getsetenv(void *arg) } name[nameLen] = '\0'; - text = SDL_getenv(name); - SDLTest_AssertPass("Call to SDL_getenv('%s')", name); + text = SDL_GetEnvironmentVariable(env, name); + SDLTest_AssertPass("Call to SDL_GetEnvironmentVariable(env, '%s')", name); if (text) { SDLTest_Log("Expected: NULL, Got: '%s' (%i)", text, (int)SDL_strlen(text)); } @@ -578,13 +579,13 @@ static int SDLCALL stdlib_getsetenv(void *arg) /* Set value 1 without overwrite */ overwrite = 0; expected = value1; - result = SDL_setenv(name, value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value1, overwrite); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); + result = SDL_SetEnvironmentVariable(env, name, value1, overwrite); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, '%s','%s', %i)", name, value1, overwrite); + SDLTest_AssertCheck(result == SDL_TRUE, "Check result, expected: 1, got: %i", result); /* Check value */ - text = SDL_getenv(name); - SDLTest_AssertPass("Call to SDL_getenv('%s')", name); + text = SDL_GetEnvironmentVariable(env, name); + SDLTest_AssertPass("Call to SDL_GetEnvironmentVariable(env, '%s')", name); SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); if (text != NULL) { SDLTest_AssertCheck( @@ -597,13 +598,13 @@ static int SDLCALL stdlib_getsetenv(void *arg) /* Set value 2 with overwrite */ overwrite = 1; expected = value2; - result = SDL_setenv(name, value2, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value2, overwrite); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); + result = SDL_SetEnvironmentVariable(env, name, value2, overwrite); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, '%s','%s', %i)", name, value2, overwrite); + SDLTest_AssertCheck(result == SDL_TRUE, "Check result, expected: 1, got: %i", result); /* Check value */ - text = SDL_getenv(name); - SDLTest_AssertPass("Call to SDL_getenv('%s')", name); + text = SDL_GetEnvironmentVariable(env, name); + SDLTest_AssertPass("Call to SDL_GetEnvironmentVariable(env, '%s')", name); SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); if (text != NULL) { SDLTest_AssertCheck( @@ -616,13 +617,13 @@ static int SDLCALL stdlib_getsetenv(void *arg) /* Set value 1 without overwrite */ overwrite = 0; expected = value2; - result = SDL_setenv(name, value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value1, overwrite); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); + result = SDL_SetEnvironmentVariable(env, name, value1, overwrite); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, '%s','%s', %i)", name, value1, overwrite); + SDLTest_AssertCheck(result == SDL_TRUE, "Check result, expected: 1, got: %i", result); /* Check value */ - text = SDL_getenv(name); - SDLTest_AssertPass("Call to SDL_getenv('%s')", name); + text = SDL_GetEnvironmentVariable(env, name); + SDLTest_AssertPass("Call to SDL_GetEnvironmentVariable(env, '%s')", name); SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); if (text != NULL) { SDLTest_AssertCheck( @@ -635,13 +636,13 @@ static int SDLCALL stdlib_getsetenv(void *arg) /* Set value 1 with overwrite */ overwrite = 1; expected = value1; - result = SDL_setenv(name, value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value1, overwrite); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); + result = SDL_SetEnvironmentVariable(env, name, value1, overwrite); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, '%s','%s', %i)", name, value1, overwrite); + SDLTest_AssertCheck(result == SDL_TRUE, "Check result, expected: 1, got: %i", result); /* Check value */ - text = SDL_getenv(name); - SDLTest_AssertPass("Call to SDL_getenv('%s')", name); + text = SDL_GetEnvironmentVariable(env, name); + SDLTest_AssertPass("Call to SDL_GetEnvironmentVariable(env, '%s')", name); SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); if (text != NULL) { SDLTest_AssertCheck( @@ -652,48 +653,48 @@ static int SDLCALL stdlib_getsetenv(void *arg) } /* Verify setenv() with empty string vs unsetenv() */ - result = SDL_setenv("FOO", "1", 1); - SDLTest_AssertPass("Call to SDL_setenv('FOO','1', 1)"); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); + result = SDL_SetEnvironmentVariable(env, "FOO", "1", 1); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, 'FOO','1', 1)"); + SDLTest_AssertCheck(result == SDL_TRUE, "Check result, expected: 1, got: %i", result); expected = "1"; - text = SDL_getenv("FOO"); - SDLTest_AssertPass("Call to SDL_getenv('FOO')"); + text = SDL_GetEnvironmentVariable(env, "FOO"); + SDLTest_AssertPass("Call to SDL_GetEnvironmentVariable(env, 'FOO')"); SDLTest_AssertCheck(text && SDL_strcmp(text, expected) == 0, "Verify returned text, expected: %s, got: %s", expected, text); - result = SDL_setenv("FOO", "", 1); - SDLTest_AssertPass("Call to SDL_setenv('FOO','', 1)"); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); + result = SDL_SetEnvironmentVariable(env, "FOO", "", 1); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, 'FOO','', 1)"); + SDLTest_AssertCheck(result == SDL_TRUE, "Check result, expected: 1, got: %i", result); expected = ""; - text = SDL_getenv("FOO"); - SDLTest_AssertPass("Call to SDL_getenv('FOO')"); + text = SDL_GetEnvironmentVariable(env, "FOO"); + SDLTest_AssertPass("Call to SDL_GetEnvironmentVariable(env, 'FOO')"); SDLTest_AssertCheck(text && SDL_strcmp(text, expected) == 0, "Verify returned text, expected: '%s', got: '%s'", expected, text); - result = SDL_unsetenv("FOO"); - SDLTest_AssertPass("Call to SDL_unsetenv('FOO')"); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); - text = SDL_getenv("FOO"); - SDLTest_AssertPass("Call to SDL_getenv('FOO')"); + result = SDL_UnsetEnvironmentVariable(env, "FOO"); + SDLTest_AssertPass("Call to SDL_UnsetEnvironmentVariable(env, 'FOO')"); + SDLTest_AssertCheck(result == SDL_TRUE, "Check result, expected: 1, got: %i", result); + text = SDL_GetEnvironmentVariable(env, "FOO"); + SDLTest_AssertPass("Call to SDL_GetEnvironmentVariable(env, 'FOO')"); SDLTest_AssertCheck(text == NULL, "Verify returned text, expected: (null), got: %s", text); - result = SDL_setenv("FOO", "0", 0); - SDLTest_AssertPass("Call to SDL_setenv('FOO','0', 0)"); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); + result = SDL_SetEnvironmentVariable(env, "FOO", "0", 0); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, 'FOO','0', 0)"); + SDLTest_AssertCheck(result == SDL_TRUE, "Check result, expected: 1, got: %i", result); expected = "0"; - text = SDL_getenv("FOO"); - SDLTest_AssertPass("Call to SDL_getenv('FOO')"); + text = SDL_GetEnvironmentVariable(env, "FOO"); + SDLTest_AssertPass("Call to SDL_GetEnvironmentVariable(env, 'FOO')"); SDLTest_AssertCheck(text && SDL_strcmp(text, expected) == 0, "Verify returned text, expected: %s, got: %s", expected, text); /* Negative cases */ for (overwrite = 0; overwrite <= 1; overwrite++) { - result = SDL_setenv(NULL, value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv(NULL,'%s', %i)", value1, overwrite); - SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); - result = SDL_setenv("", value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('','%s', %i)", value1, overwrite); - SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); - result = SDL_setenv("=", value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('=','%s', %i)", value1, overwrite); - SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); - result = SDL_setenv(name, NULL, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('%s', NULL, %i)", name, overwrite); - SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); + result = SDL_SetEnvironmentVariable(env, NULL, value1, overwrite); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, NULL,'%s', %i)", value1, overwrite); + SDLTest_AssertCheck(result == SDL_FALSE, "Check result, expected: 0, got: %i", result); + result = SDL_SetEnvironmentVariable(env, "", value1, overwrite); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, '','%s', %i)", value1, overwrite); + SDLTest_AssertCheck(result == SDL_FALSE, "Check result, expected: 0, got: %i", result); + result = SDL_SetEnvironmentVariable(env, "=", value1, overwrite); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, '=','%s', %i)", value1, overwrite); + SDLTest_AssertCheck(result == SDL_FALSE, "Check result, expected: 0, got: %i", result); + result = SDL_SetEnvironmentVariable(env, name, NULL, overwrite); + SDLTest_AssertPass("Call to SDL_SetEnvironmentVariable(env, '%s', NULL, %i)", name, overwrite); + SDLTest_AssertCheck(result == SDL_FALSE, "Check result, expected: 0, got: %i", result); } /* Clean up */ @@ -1402,7 +1403,7 @@ static const SDLTest_TestCaseReference stdlibTest_swprintf = { }; static const SDLTest_TestCaseReference stdlibTest_getsetenv = { - stdlib_getsetenv, "stdlib_getsetenv", "Call to SDL_getenv and SDL_setenv", TEST_ENABLED + stdlib_getsetenv, "stdlib_getsetenv", "Call to SDL_GetEnvironmentVariable and SDL_SetEnvironmentVariable", TEST_ENABLED }; static const SDLTest_TestCaseReference stdlibTest_sscanf = { diff --git a/test/testautomation_video.c b/test/testautomation_video.c index 6d2685868c..96b860a1c8 100644 --- a/test/testautomation_video.c +++ b/test/testautomation_video.c @@ -43,7 +43,7 @@ static SDL_Window *createVideoSuiteTestWindow(const char *title) needs_renderer = SDL_TRUE; } else if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) { /* Try to detect if the x11 driver is running under XWayland */ - const char *session_type = SDL_getenv("XDG_SESSION_TYPE"); + const char *session_type = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XDG_SESSION_TYPE"); if (session_type && SDL_strcasecmp(session_type, "wayland") == 0) { needs_renderer = SDL_TRUE; } @@ -1929,7 +1929,7 @@ static int SDLCALL video_getSetWindowState(void *arg) * Other desktops can be enabled in the future as required. */ if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0 || SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) { - const char *desktop = SDL_getenv("XDG_CURRENT_DESKTOP"); + const char *desktop = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "XDG_CURRENT_DESKTOP"); if (SDL_strcmp(desktop, "GNOME") != 0 && SDL_strcmp(desktop, "KDE") != 0) { SDLTest_Log("Skipping test video_getSetWindowState: desktop environment %s not supported", desktop); return TEST_SKIPPED; diff --git a/test/testerror.c b/test/testerror.c index ba372be97c..043c5855d7 100644 --- a/test/testerror.c +++ b/test/testerror.c @@ -93,7 +93,7 @@ int main(int argc, char *argv[]) /* Set the error value for the main thread */ SDL_SetError("No worries"); - if (SDL_getenv("SDL_TESTS_QUICK") != NULL) { + if (SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "SDL_TESTS_QUICK") != NULL) { SDL_Log("Not running slower tests"); SDL_Quit(); return 0; diff --git a/test/testprocess.c b/test/testprocess.c index 3d2ed5e192..9898e516ae 100644 --- a/test/testprocess.c +++ b/test/testprocess.c @@ -35,39 +35,35 @@ static void SDLCALL setUpProcess(void **arg) { static const char *options[] = { "/path/to/childprocess" EXE, NULL }; -static char *env_key_val_string(const char *key) { - const char *env = SDL_getenv(key); - size_t size_result; - char *result; - - if (env == NULL) { - return NULL; - } - size_result = SDL_strlen(key) + SDL_strlen(env) + 2; - result = SDL_malloc(size_result); - SDL_snprintf(result, size_result, "%s=%s", key, env); - return result; -} - static char **DuplicateEnvironment(const char *key0, ...) { va_list ap; - size_t count = 1; - size_t i; const char *keyN; + SDL_Environment *env = SDL_GetEnvironment(); + SDL_Environment *new_env = SDL_CreateEnvironment(SDL_TRUE); char **result; if (key0) { - if (SDL_strchr(key0, '=') || SDL_getenv(key0)) { - count += 1; + char *sep = SDL_strchr(key0, '='); + if (sep) { + *sep = '\0'; + SDL_SetEnvironmentVariable(new_env, key0, sep + 1, SDL_TRUE); + *sep = '='; + SDL_SetEnvironmentVariable(new_env, key0, sep, SDL_TRUE); + } else { + SDL_SetEnvironmentVariable(new_env, key0, SDL_GetEnvironmentVariable(env, key0), SDL_TRUE); } - va_start(ap, key0); for (;;) { keyN = va_arg(ap, const char *); if (keyN) { - if (SDL_strchr(keyN, '=') || SDL_getenv(keyN)) { - count += 1; + sep = SDL_strchr(keyN, '='); + if (sep) { + *sep = '\0'; + SDL_SetEnvironmentVariable(new_env, keyN, sep + 1, SDL_TRUE); + *sep = '='; + } else { + SDL_SetEnvironmentVariable(new_env, keyN, SDL_GetEnvironmentVariable(env, keyN), SDL_TRUE); } } else { break; @@ -76,45 +72,11 @@ static char **DuplicateEnvironment(const char *key0, ...) va_end(ap); } - result = SDL_calloc(count, sizeof(char *)); - - i = 0; - if (key0) { - if (SDL_strchr(key0, '=')) { - result[i++] = SDL_strdup(key0); - } else if (SDL_getenv(key0)) { - result[i++] = env_key_val_string(key0); - } - va_start(ap, key0); - for (;;) { - keyN = va_arg(ap, const char *); - if (keyN) { - if (SDL_strchr(keyN, '=')) { - result[i++] = SDL_strdup(keyN); - } else if (SDL_getenv(keyN)) { - result[i++] = env_key_val_string(keyN); - } - } else { - break; - } - } - va_end(ap); - } + result = SDL_GetEnvironmentVariables(new_env); + SDL_DestroyEnvironment(new_env); return result; } -static void DestroyEnvironment(char **environment) { - char **envp; - - if (!environment) { - return; - } - for (envp = environment; *envp; envp++) { - SDL_free(*envp); - } - SDL_free(environment); -} - static int SDLCALL process_testArguments(void *arg) { TestProcessData *data = (TestProcessData *)arg; @@ -187,7 +149,7 @@ static int SDLCALL process_testInheritedEnv(void *arg) test_env_val = SDLTest_RandomAsciiStringOfSize(32); SDLTest_AssertPass("Setting parent environment variable %s=%s", TEST_ENV_KEY, test_env_val); - SDL_setenv(TEST_ENV_KEY, test_env_val, 1); + SDL_SetEnvironmentVariable(SDL_GetEnvironment(), TEST_ENV_KEY, test_env_val, SDL_TRUE); SDL_snprintf(buffer, sizeof(buffer), "%s=%s", TEST_ENV_KEY, test_env_val); process_args[3] = buffer; @@ -312,13 +274,14 @@ static int SDLCALL process_testNewEnv(void *arg) SDLTest_AssertCheck(exit_code == 0, "Exit code should be 0, is %d", exit_code); SDLTest_AssertPass("About to destroy process"); SDL_DestroyProcess(process); - DestroyEnvironment(process_env); + SDL_free(process_env); SDL_free(test_env_val); return TEST_COMPLETED; + failed: SDL_free(test_env_val); SDL_DestroyProcess(process); - DestroyEnvironment(process_env); + SDL_free(process_env); return TEST_ABORTED; } @@ -330,7 +293,6 @@ static int process_testStdinToStdout(void *arg) "--stdin-to-stdout", NULL, }; - const char **process_env = NULL; SDL_PropertiesID props; SDL_Process *process = NULL; Sint64 pid; @@ -346,7 +308,6 @@ static int process_testStdinToStdout(void *arg) props = SDL_CreateProperties(); SDL_SetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, (void *)process_args); - SDL_SetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, (void *)process_env); SDL_SetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDIN_NUMBER, SDL_PROCESS_STDIO_APP); SDL_SetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER, SDL_PROCESS_STDIO_APP); process = SDL_CreateProcessWithProperties(props); diff --git a/test/testsurround.c b/test/testsurround.c index d0d8ff8a87..876ebd0d0a 100644 --- a/test/testsurround.c +++ b/test/testsurround.c @@ -223,7 +223,7 @@ int main(int argc, char *argv[]) SDL_Log("Playing %d Hz test tone on channel: %s\n", sine_freq, get_channel_name(j, total_channels)); /* fill_buffer() will increment the active channel */ - if (SDL_getenv("SDL_TESTS_QUICK") != NULL) { + if (SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "SDL_TESTS_QUICK") != NULL) { SDL_Delay(QUICK_TEST_TIME_MSEC); } else { SDL_Delay(CHANNEL_TEST_TIME_SEC * 1000); diff --git a/test/testthread.c b/test/testthread.c index 9eeea4104e..a18f8fcfd0 100644 --- a/test/testthread.c +++ b/test/testthread.c @@ -127,7 +127,7 @@ int main(int argc, char *argv[]) return 1; } - if (SDL_getenv("SDL_TESTS_QUICK") != NULL) { + if (SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "SDL_TESTS_QUICK") != NULL) { SDL_Log("Not running slower tests"); SDL_Quit(); return 0; diff --git a/test/testtimer.c b/test/testtimer.c index 3b9473cdf6..82baf98f34 100644 --- a/test/testtimer.c +++ b/test/testtimer.c @@ -124,7 +124,7 @@ int main(int argc, char *argv[]) return 1; } - if (SDL_getenv("SDL_TESTS_QUICK") != NULL) { + if (SDL_GetEnvironmentVariable(SDL_GetEnvironment(), "SDL_TESTS_QUICK") != NULL) { SDL_Log("Not running slower tests"); SDL_Quit(); return 0;