# HG changeset patch # User Ryan C. Gordon # Date 1260961191 0 # Node ID 15eea7a1fa970a5c44ff3a047cd1e0519435f8e2 # Parent 951dd6a5d1a2ec716e67562b961ba59db7286184 Implemented SDL_setenv(), moved SDL_putenv() to compat. Fixes Bugzilla #779. diff -r 951dd6a5d1a2 -r 15eea7a1fa97 configure.in --- a/configure.in Wed Dec 16 08:17:05 2009 +0000 +++ b/configure.in Wed Dec 16 10:59:51 2009 +0000 @@ -207,7 +207,7 @@ AC_DEFINE(HAVE_MPROTECT) ]), ) - AC_CHECK_FUNCS(malloc calloc realloc free getenv putenv unsetenv qsort abs bcopy memset memcpy memmove strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp sscanf snprintf vsnprintf sigaction setjmp nanosleep sysctlbyname) + AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp sscanf snprintf vsnprintf sigaction setjmp nanosleep sysctlbyname) AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"]) AC_CHECK_FUNCS(ceil copysign cos cosf fabs floor log pow scalbn sin sinf sqrt) diff -r 951dd6a5d1a2 -r 15eea7a1fa97 include/SDL_compat.h --- a/include/SDL_compat.h Wed Dec 16 08:17:05 2009 +0000 +++ b/include/SDL_compat.h Wed Dec 16 10:59:51 2009 +0000 @@ -297,6 +297,8 @@ #define SDL_RenderFill SDL_RenderRect +extern DECLSPEC int SDLCALL SDL_putenv(const char *variable); + /*@}*//*Compatibility*/ /* Ends C function definitions when using C++ */ diff -r 951dd6a5d1a2 -r 15eea7a1fa97 include/SDL_config.h.in --- a/include/SDL_config.h.in Wed Dec 16 08:17:05 2009 +0000 +++ b/include/SDL_config.h.in Wed Dec 16 10:59:51 2009 +0000 @@ -90,6 +90,7 @@ #undef HAVE_ALLOCA #ifndef _WIN32 /* Don't use C runtime versions of these on Windows */ #undef HAVE_GETENV +#undef HAVE_SETENV #undef HAVE_PUTENV #undef HAVE_UNSETENV #endif diff -r 951dd6a5d1a2 -r 15eea7a1fa97 include/SDL_config_iphoneos.h --- a/include/SDL_config_iphoneos.h Wed Dec 16 08:17:05 2009 +0000 +++ b/include/SDL_config_iphoneos.h Wed Dec 16 10:59:51 2009 +0000 @@ -61,7 +61,9 @@ #define HAVE_FREE 1 #define HAVE_ALLOCA 1 #define HAVE_GETENV 1 +#define HAVE_SETENV 1 #define HAVE_PUTENV 1 +#define HAVE_SETENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 #define HAVE_ABS 1 diff -r 951dd6a5d1a2 -r 15eea7a1fa97 include/SDL_config_macosx.h --- a/include/SDL_config_macosx.h Wed Dec 16 08:17:05 2009 +0000 +++ b/include/SDL_config_macosx.h Wed Dec 16 10:59:51 2009 +0000 @@ -60,6 +60,7 @@ #define HAVE_FREE 1 #define HAVE_ALLOCA 1 #define HAVE_GETENV 1 +#define HAVE_SETENV 1 #define HAVE_PUTENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 diff -r 951dd6a5d1a2 -r 15eea7a1fa97 include/SDL_config_nintendods.h --- a/include/SDL_config_nintendods.h Wed Dec 16 08:17:05 2009 +0000 +++ b/include/SDL_config_nintendods.h Wed Dec 16 10:59:51 2009 +0000 @@ -62,6 +62,7 @@ #define HAVE_FREE 1 #define HAVE_ALLOCA 1 #define HAVE_GETENV 1 +#define HAVE_SETENV 1 #define HAVE_PUTENV 1 #define HAVE_QSORT 1 #define HAVE_ABS 1 diff -r 951dd6a5d1a2 -r 15eea7a1fa97 include/SDL_config_pandora.h --- a/include/SDL_config_pandora.h Wed Dec 16 08:17:05 2009 +0000 +++ b/include/SDL_config_pandora.h Wed Dec 16 10:59:51 2009 +0000 @@ -53,6 +53,7 @@ #define HAVE_FREE 1 #define HAVE_ALLOCA 1 #define HAVE_GETENV 1 +#define HAVE_SETENV 1 #define HAVE_PUTENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 diff -r 951dd6a5d1a2 -r 15eea7a1fa97 include/SDL_config_wiz.h --- a/include/SDL_config_wiz.h Wed Dec 16 08:17:05 2009 +0000 +++ b/include/SDL_config_wiz.h Wed Dec 16 10:59:51 2009 +0000 @@ -58,6 +58,7 @@ #define HAVE_FREE 1 #define HAVE_ALLOCA 1 #define HAVE_GETENV 1 +#define HAVE_SETENV 1 #define HAVE_PUTENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 diff -r 951dd6a5d1a2 -r 15eea7a1fa97 include/SDL_stdinc.h --- a/include/SDL_stdinc.h Wed Dec 16 08:17:05 2009 +0000 +++ b/include/SDL_stdinc.h Wed Dec 16 10:59:51 2009 +0000 @@ -267,20 +267,12 @@ extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); #endif -/** - * \warning On some platforms, the string you pass to SDL_putenv() becomes - * part of the environment table directly...it will use this specific - * buffer, and not a copy of it! This means you can't free it, and - * other pieces of code may try to write to it. In practice, this - * isn't a big deal, but be aware of the possibility. - * However, due to this issue, you should be prepared to - * pass a (char*), or be willing to cast away the constness of your - * string for this call. - */ -#ifdef HAVE_PUTENV -#define SDL_putenv putenv +/* SDL_putenv() has moved to SDL_compat. */ +#ifdef HAVE_SETENV +#define SDL_setenv setenv #else -extern DECLSPEC int SDLCALL SDL_putenv(const char *variable); +extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, + int overwrite); #endif #ifdef HAVE_QSORT diff -r 951dd6a5d1a2 -r 15eea7a1fa97 src/SDL_compat.c --- a/src/SDL_compat.c Wed Dec 16 08:17:05 2009 +0000 +++ b/src/SDL_compat.c Wed Dec 16 10:59:51 2009 +0000 @@ -1754,4 +1754,26 @@ return previous; } + +int +SDL_putenv(const char *_var) +{ + char *ptr = NULL; + char *var = SDL_strdup(_var); + if (var == NULL) { + return -1; /* we don't set errno. */ + } + + ptr = strchr(var, '='); + if (ptr == NULL) { + SDL_free(var); + return -1; + } + + *ptr = '\0'; /* split the string into name and value. */ + SDL_setenv(var, ptr + 1, 1); + SDL_free(var); + return 0; +} + /* vi: set ts=4 sw=4 expandtab: */ diff -r 951dd6a5d1a2 -r 15eea7a1fa97 src/audio/esd/SDL_esdaudio.c --- a/src/audio/esd/SDL_esdaudio.c Wed Dec 16 08:17:05 2009 +0000 +++ b/src/audio/esd/SDL_esdaudio.c Wed Dec 16 10:59:51 2009 +0000 @@ -321,9 +321,7 @@ int connection = 0; /* Don't start ESD if it's not running */ - if (SDL_getenv("ESD_NO_SPAWN") == NULL) { - SDL_putenv("ESD_NO_SPAWN=1"); - } + SDL_setenv("ESD_NO_SPAWN", "1", 0); connection = SDL_NAME(esd_open_sound) (NULL); if (connection < 0) { diff -r 951dd6a5d1a2 -r 15eea7a1fa97 src/stdlib/SDL_getenv.c --- a/src/stdlib/SDL_getenv.c Wed Dec 16 08:17:05 2009 +0000 +++ b/src/stdlib/SDL_getenv.c Wed Dec 16 10:59:51 2009 +0000 @@ -35,31 +35,18 @@ static char *SDL_envmem = NULL; /* Ugh, memory leak */ static size_t SDL_envmemlen = 0; -/* Put a variable of the form "name=value" into the environment */ +/* Put a variable into the environment */ int -SDL_putenv(const char *variable) +SDL_setenv(const char *name, const char *value, int overwrite) { - size_t bufferlen; - char *value; - const char *sep; - - sep = SDL_strchr(variable, '='); - if (sep == NULL) { - return -1; + if (!overwrite) { + char ch = 0; + const size_t len = GetEnvironmentVariable(name, &ch, sizeof (ch)); + if (len > 0) { + return 0; /* asked not to overwrite existing value. */ + } } - bufferlen = SDL_strlen(variable) + 1; - if (bufferlen > SDL_envmemlen) { - char *newmem = (char *) SDL_realloc(SDL_envmem, bufferlen); - if (newmem == NULL) { - return -1; - } - SDL_envmem = newmem; - SDL_envmemlen = bufferlen; - } - SDL_strlcpy(SDL_envmem, variable, bufferlen); - value = SDL_envmem + (sep - variable); - *value++ = '\0'; - if (!SetEnvironmentVariable(SDL_envmem, *value ? value : NULL)) { + if (!SetEnvironmentVariable(name, *value ? value : NULL)) { return -1; } return 0; @@ -92,36 +79,31 @@ static char **SDL_env = (char **) 0; -/* Put a variable of the form "name=value" into the environment */ +/* Put a variable into the environment */ int -SDL_putenv(const char *variable) +SDL_setenv(const char *name, const char *value, int overwrite) { - const char *name, *value; int added; int len, i; char **new_env; char *new_variable; /* A little error checking */ - if (!variable) { - return (-1); - } - name = variable; - for (value = variable; *value && (*value != '='); ++value) { - /* Keep looking for '=' */ ; - } - if (*value) { - ++value; - } else { + if (!name || !value) { return (-1); } /* Allocate memory for the variable */ - new_variable = SDL_strdup(variable); + len = SDL_strlen(name) + SDL_strlen(value) + 2; + new_variable = (char *) SDL_malloc(len); if (!new_variable) { return (-1); } + SDL_snprintf(new_variable, len, "%s=%s", name, value); + value = new_variable + SDL_strlen(name) + 1; + name = new_variable; + /* Actually put it into the environment */ added = 0; i = 0; @@ -135,6 +117,10 @@ } /* If we found it, just replace the entry */ if (SDL_env[i]) { + if (!overwrite) { + SDL_free(new_variable); + return 0; + } SDL_free(SDL_env[i]); SDL_env[i] = new_variable; added = 1; @@ -180,6 +166,36 @@ #endif /* !HAVE_GETENV */ + +/* We have a real environment table, but no real setenv? Fake it w/ putenv. */ +#if (defined(HAVE_GETENV) && defined(HAVE_PUTENV) && !defined(HAVE_SETENV)) +int +SDL_setenv(const char *name, const char *value, int overwrite) +{ + size_t len; + char *new_variable; + + if (getenv(name) != NULL) { + if (overwrite) { + unsetenv(name); + } else { + return 0; /* leave the existing one there. */ + } + } + + /* This leaks. Sorry. Get a better OS so we don't have to do this. */ + len = SDL_strlen(name) + SDL_strlen(value) + 2; + new_variable = (char *) SDL_malloc(len); + if (!new_variable) { + return (-1); + } + + SDL_snprintf(new_variable, len, "%s=%s", name, value); + return putenv(new_variable); +} +#endif + + #ifdef TEST_MAIN #include diff -r 951dd6a5d1a2 -r 15eea7a1fa97 test/testime.c --- a/test/testime.c Wed Dec 16 08:17:05 2009 +0000 +++ b/test/testime.c Wed Dec 16 10:59:51 2009 +0000 @@ -60,7 +60,7 @@ } } - SDL_putenv("SDL_VIDEO_WINDOW_POS=center"); + SDL_setenv("SDL_VIDEO_WINDOW_POS", "center", 1); if (SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());