Added thread-safe environment functions

Also marked the existing functions as unsafe, as they can cause crashes if used in multi-threaded applications.

As a bonus, since the new functions are hashtable based, hint environment lookups are much faster.
This commit is contained in:
Sam Lantinga
2024-09-13 17:00:15 -07:00
parent 16ff7503b7
commit 90e01040c5
49 changed files with 696 additions and 252 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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_

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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)

View File

@@ -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");

View File

@@ -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;

View File

@@ -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;

View File

@@ -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");

View File

@@ -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)) {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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

View File

@@ -35,15 +35,6 @@
#include "../SDL_sysprocess.h"
#include "../../file/SDL_iostream_c.h"
#if defined(SDL_PLATFORM_MACOS)
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
#elif defined(SDL_PLATFORM_FREEBSD)
#include <dlfcn.h>
#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;
}

View File

@@ -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) {

View File

@@ -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 <crt_externs.h>
#define environ (*_NSGetEnviron())
#elif defined(SDL_PLATFORM_FREEBSD)
#include <dlfcn.h>
#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);
}

View File

@@ -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";

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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";
}

View File

@@ -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");
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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");
}
}

View File

@@ -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) {

View File

@@ -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);
}