SDL_getenv.c (8138B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "../SDL_internal.h" 22 23#if defined(__WIN32__) 24#include "../core/windows/SDL_windows.h" 25#endif 26 27#include "SDL_stdinc.h" 28 29#if defined(__WIN32__) && (!defined(HAVE_SETENV) || !defined(HAVE_GETENV)) 30/* Note this isn't thread-safe! */ 31static char *SDL_envmem = NULL; /* Ugh, memory leak */ 32static size_t SDL_envmemlen = 0; 33#endif 34 35/* Put a variable into the environment */ 36/* Note: Name may not contain a '=' character. (Reference: http://www.unix.com/man-page/Linux/3/setenv/) */ 37#if defined(HAVE_SETENV) 38int 39SDL_setenv(const char *name, const char *value, int overwrite) 40{ 41 /* Input validation */ 42 if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { 43 return (-1); 44 } 45 46 return setenv(name, value, overwrite); 47} 48#elif defined(__WIN32__) 49int 50SDL_setenv(const char *name, const char *value, int overwrite) 51{ 52 /* Input validation */ 53 if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { 54 return (-1); 55 } 56 57 if (!overwrite) { 58 char ch = 0; 59 const size_t len = GetEnvironmentVariableA(name, &ch, sizeof (ch)); 60 if (len > 0) { 61 return 0; /* asked not to overwrite existing value. */ 62 } 63 } 64 if (!SetEnvironmentVariableA(name, *value ? value : NULL)) { 65 return -1; 66 } 67 return 0; 68} 69/* We have a real environment table, but no real setenv? Fake it w/ putenv. */ 70#elif (defined(HAVE_GETENV) && defined(HAVE_PUTENV) && !defined(HAVE_SETENV)) 71int 72SDL_setenv(const char *name, const char *value, int overwrite) 73{ 74 size_t len; 75 char *new_variable; 76 77 /* Input validation */ 78 if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { 79 return (-1); 80 } 81 82 if (getenv(name) != NULL) { 83 if (overwrite) { 84 unsetenv(name); 85 } else { 86 return 0; /* leave the existing one there. */ 87 } 88 } 89 90 /* This leaks. Sorry. Get a better OS so we don't have to do this. */ 91 len = SDL_strlen(name) + SDL_strlen(value) + 2; 92 new_variable = (char *) SDL_malloc(len); 93 if (!new_variable) { 94 return (-1); 95 } 96 97 SDL_snprintf(new_variable, len, "%s=%s", name, value); 98 return putenv(new_variable); 99} 100#else /* roll our own */ 101static char **SDL_env = (char **) 0; 102int 103SDL_setenv(const char *name, const char *value, int overwrite) 104{ 105 int added; 106 int len, i; 107 char **new_env; 108 char *new_variable; 109 110 /* Input validation */ 111 if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { 112 return (-1); 113 } 114 115 /* See if it already exists */ 116 if (!overwrite && SDL_getenv(name)) { 117 return 0; 118 } 119 120 /* Allocate memory for the variable */ 121 len = SDL_strlen(name) + SDL_strlen(value) + 2; 122 new_variable = (char *) SDL_malloc(len); 123 if (!new_variable) { 124 return (-1); 125 } 126 127 SDL_snprintf(new_variable, len, "%s=%s", name, value); 128 value = new_variable + SDL_strlen(name) + 1; 129 name = new_variable; 130 131 /* Actually put it into the environment */ 132 added = 0; 133 i = 0; 134 if (SDL_env) { 135 /* Check to see if it's already there... */ 136 len = (value - name); 137 for (; SDL_env[i]; ++i) { 138 if (SDL_strncmp(SDL_env[i], name, len) == 0) { 139 break; 140 } 141 } 142 /* If we found it, just replace the entry */ 143 if (SDL_env[i]) { 144 SDL_free(SDL_env[i]); 145 SDL_env[i] = new_variable; 146 added = 1; 147 } 148 } 149 150 /* Didn't find it in the environment, expand and add */ 151 if (!added) { 152 new_env = SDL_realloc(SDL_env, (i + 2) * sizeof(char *)); 153 if (new_env) { 154 SDL_env = new_env; 155 SDL_env[i++] = new_variable; 156 SDL_env[i++] = (char *) 0; 157 added = 1; 158 } else { 159 SDL_free(new_variable); 160 } 161 } 162 return (added ? 0 : -1); 163} 164#endif 165 166/* Retrieve a variable named "name" from the environment */ 167#if defined(HAVE_GETENV) 168char * 169SDL_getenv(const char *name) 170{ 171 /* Input validation */ 172 if (!name || SDL_strlen(name)==0) { 173 return NULL; 174 } 175 176 return getenv(name); 177} 178#elif defined(__WIN32__) 179char * 180SDL_getenv(const char *name) 181{ 182 size_t bufferlen; 183 184 /* Input validation */ 185 if (!name || SDL_strlen(name)==0) { 186 return NULL; 187 } 188 189 bufferlen = 190 GetEnvironmentVariableA(name, SDL_envmem, (DWORD) SDL_envmemlen); 191 if (bufferlen == 0) { 192 return NULL; 193 } 194 if (bufferlen > SDL_envmemlen) { 195 char *newmem = (char *) SDL_realloc(SDL_envmem, bufferlen); 196 if (newmem == NULL) { 197 return NULL; 198 } 199 SDL_envmem = newmem; 200 SDL_envmemlen = bufferlen; 201 GetEnvironmentVariableA(name, SDL_envmem, (DWORD) SDL_envmemlen); 202 } 203 return SDL_envmem; 204} 205#else 206char * 207SDL_getenv(const char *name) 208{ 209 int len, i; 210 char *value; 211 212 /* Input validation */ 213 if (!name || SDL_strlen(name)==0) { 214 return NULL; 215 } 216 217 value = (char *) 0; 218 if (SDL_env) { 219 len = SDL_strlen(name); 220 for (i = 0; SDL_env[i] && !value; ++i) { 221 if ((SDL_strncmp(SDL_env[i], name, len) == 0) && 222 (SDL_env[i][len] == '=')) { 223 value = &SDL_env[i][len + 1]; 224 } 225 } 226 } 227 return value; 228} 229#endif 230 231 232#ifdef TEST_MAIN 233#include <stdio.h> 234 235int 236main(int argc, char *argv[]) 237{ 238 char *value; 239 240 printf("Checking for non-existent variable... "); 241 fflush(stdout); 242 if (!SDL_getenv("EXISTS")) { 243 printf("okay\n"); 244 } else { 245 printf("failed\n"); 246 } 247 printf("Setting FIRST=VALUE1 in the environment... "); 248 fflush(stdout); 249 if (SDL_setenv("FIRST", "VALUE1", 0) == 0) { 250 printf("okay\n"); 251 } else { 252 printf("failed\n"); 253 } 254 printf("Getting FIRST from the environment... "); 255 fflush(stdout); 256 value = SDL_getenv("FIRST"); 257 if (value && (SDL_strcmp(value, "VALUE1") == 0)) { 258 printf("okay\n"); 259 } else { 260 printf("failed\n"); 261 } 262 printf("Setting SECOND=VALUE2 in the environment... "); 263 fflush(stdout); 264 if (SDL_setenv("SECOND", "VALUE2", 0) == 0) { 265 printf("okay\n"); 266 } else { 267 printf("failed\n"); 268 } 269 printf("Getting SECOND from the environment... "); 270 fflush(stdout); 271 value = SDL_getenv("SECOND"); 272 if (value && (SDL_strcmp(value, "VALUE2") == 0)) { 273 printf("okay\n"); 274 } else { 275 printf("failed\n"); 276 } 277 printf("Setting FIRST=NOVALUE in the environment... "); 278 fflush(stdout); 279 if (SDL_setenv("FIRST", "NOVALUE", 1) == 0) { 280 printf("okay\n"); 281 } else { 282 printf("failed\n"); 283 } 284 printf("Getting FIRST from the environment... "); 285 fflush(stdout); 286 value = SDL_getenv("FIRST"); 287 if (value && (SDL_strcmp(value, "NOVALUE") == 0)) { 288 printf("okay\n"); 289 } else { 290 printf("failed\n"); 291 } 292 printf("Checking for non-existent variable... "); 293 fflush(stdout); 294 if (!SDL_getenv("EXISTS")) { 295 printf("okay\n"); 296 } else { 297 printf("failed\n"); 298 } 299 return (0); 300} 301#endif /* TEST_MAIN */ 302 303/* vi: set ts=4 sw=4 expandtab: */