src/stdlib/SDL_getenv.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Sat, 05 Apr 2014 23:32:41 +0200
changeset 8695 a672c01a4ab7
parent 8645 d69fdbefeecf
child 9306 817656bd36ec
permissions -rw-r--r--
Fixed names of four hint environment variables.
     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! */
    31 static char *SDL_envmem = NULL; /* Ugh, memory leak */
    32 static 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)
    38 int
    39 SDL_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__)
    49 int
    50 SDL_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))
    71 int
    72 SDL_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 */
   101 static char **SDL_env = (char **) 0;
   102 int
   103 SDL_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)
   168 char *
   169 SDL_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__)
   179 char *
   180 SDL_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
   206 char *
   207 SDL_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 
   235 int
   236 main(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: */