src/stdlib/SDL_getenv.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 20 Jan 2011 18:04:05 -0800
changeset 5062 e8916fe9cfc8
parent 3697 f7b03b6838cb
child 5086 c2539ff054c8
permissions -rw-r--r--
Fixed bug #925

Changed "win32" to "windows"
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2010 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_stdinc.h"
    25 
    26 #ifndef HAVE_GETENV
    27 
    28 #if defined(__WINDOWS__) && !defined(_WIN32_WCE)
    29 
    30 #define WIN32_LEAN_AND_MEAN
    31 #include <windows.h>
    32 
    33 /* Note this isn't thread-safe! */
    34 
    35 static char *SDL_envmem = NULL; /* Ugh, memory leak */
    36 static size_t SDL_envmemlen = 0;
    37 
    38 /* Put a variable into the environment */
    39 int
    40 SDL_setenv(const char *name, const char *value, int overwrite)
    41 {
    42     if (!overwrite) {
    43         char ch = 0;
    44         const size_t len = GetEnvironmentVariable(name, &ch, sizeof (ch));
    45         if (len > 0) {
    46             return 0;  /* asked not to overwrite existing value. */
    47         }
    48     }
    49     if (!SetEnvironmentVariable(name, *value ? value : NULL)) {
    50         return -1;
    51     }
    52     return 0;
    53 }
    54 
    55 /* Retrieve a variable named "name" from the environment */
    56 char *
    57 SDL_getenv(const char *name)
    58 {
    59     size_t bufferlen;
    60 
    61     bufferlen =
    62         GetEnvironmentVariable(name, SDL_envmem, (DWORD) SDL_envmemlen);
    63     if (bufferlen == 0) {
    64         return NULL;
    65     }
    66     if (bufferlen > SDL_envmemlen) {
    67         char *newmem = (char *) SDL_realloc(SDL_envmem, bufferlen);
    68         if (newmem == NULL) {
    69             return NULL;
    70         }
    71         SDL_envmem = newmem;
    72         SDL_envmemlen = bufferlen;
    73         GetEnvironmentVariable(name, SDL_envmem, (DWORD) SDL_envmemlen);
    74     }
    75     return SDL_envmem;
    76 }
    77 
    78 #else /* roll our own */
    79 
    80 static char **SDL_env = (char **) 0;
    81 
    82 /* Put a variable into the environment */
    83 int
    84 SDL_setenv(const char *name, const char *value, int overwrite)
    85 {
    86     int added;
    87     int len, i;
    88     char **new_env;
    89     char *new_variable;
    90 
    91     /* A little error checking */
    92     if (!name || !value) {
    93         return (-1);
    94     }
    95 
    96     /* See if it already exists */
    97     if (!overwrite && SDL_getenv(name)) {
    98         return 0;
    99     }
   100 
   101     /* Allocate memory for the variable */
   102     len = SDL_strlen(name) + SDL_strlen(value) + 2;
   103     new_variable = (char *) SDL_malloc(len);
   104     if (!new_variable) {
   105         return (-1);
   106     }
   107 
   108     SDL_snprintf(new_variable, len, "%s=%s", name, value);
   109     value = new_variable + SDL_strlen(name) + 1;
   110     name = new_variable;
   111 
   112     /* Actually put it into the environment */
   113     added = 0;
   114     i = 0;
   115     if (SDL_env) {
   116         /* Check to see if it's already there... */
   117         len = (value - name);
   118         for (; SDL_env[i]; ++i) {
   119             if (SDL_strncmp(SDL_env[i], name, len) == 0) {
   120                 break;
   121             }
   122         }
   123         /* If we found it, just replace the entry */
   124         if (SDL_env[i]) {
   125             SDL_free(SDL_env[i]);
   126             SDL_env[i] = new_variable;
   127             added = 1;
   128         }
   129     }
   130 
   131     /* Didn't find it in the environment, expand and add */
   132     if (!added) {
   133         new_env = SDL_realloc(SDL_env, (i + 2) * sizeof(char *));
   134         if (new_env) {
   135             SDL_env = new_env;
   136             SDL_env[i++] = new_variable;
   137             SDL_env[i++] = (char *) 0;
   138             added = 1;
   139         } else {
   140             SDL_free(new_variable);
   141         }
   142     }
   143     return (added ? 0 : -1);
   144 }
   145 
   146 /* Retrieve a variable named "name" from the environment */
   147 char *
   148 SDL_getenv(const char *name)
   149 {
   150     int len, i;
   151     char *value;
   152 
   153     value = (char *) 0;
   154     if (SDL_env) {
   155         len = SDL_strlen(name);
   156         for (i = 0; SDL_env[i] && !value; ++i) {
   157             if ((SDL_strncmp(SDL_env[i], name, len) == 0) &&
   158                 (SDL_env[i][len] == '=')) {
   159                 value = &SDL_env[i][len + 1];
   160             }
   161         }
   162     }
   163     return value;
   164 }
   165 
   166 #endif /* __WINDOWS__ */
   167 
   168 #endif /* !HAVE_GETENV */
   169 
   170 
   171 /* We have a real environment table, but no real setenv? Fake it w/ putenv. */
   172 #if (defined(HAVE_GETENV) && defined(HAVE_PUTENV) && !defined(HAVE_SETENV))
   173 int
   174 SDL_setenv(const char *name, const char *value, int overwrite)
   175 {
   176     size_t len;
   177     char *new_variable;
   178 
   179     if (getenv(name) != NULL) {
   180         if (overwrite) {
   181             unsetenv(name);
   182         } else {
   183             return 0;  /* leave the existing one there. */
   184         }
   185     }
   186 
   187     /* This leaks. Sorry. Get a better OS so we don't have to do this. */
   188     len = SDL_strlen(name) + SDL_strlen(value) + 2;
   189     new_variable = (char *) SDL_malloc(len);
   190     if (!new_variable) {
   191         return (-1);
   192     }
   193 
   194     SDL_snprintf(new_variable, len, "%s=%s", name, value);
   195     return putenv(new_variable);
   196 }
   197 #endif
   198 
   199 
   200 #ifdef TEST_MAIN
   201 #include <stdio.h>
   202 
   203 int
   204 main(int argc, char *argv[])
   205 {
   206     char *value;
   207 
   208     printf("Checking for non-existent variable... ");
   209     fflush(stdout);
   210     if (!SDL_getenv("EXISTS")) {
   211         printf("okay\n");
   212     } else {
   213         printf("failed\n");
   214     }
   215     printf("Setting FIRST=VALUE1 in the environment... ");
   216     fflush(stdout);
   217     if (SDL_setenv("FIRST", "VALUE1", 0) == 0) {
   218         printf("okay\n");
   219     } else {
   220         printf("failed\n");
   221     }
   222     printf("Getting FIRST from the environment... ");
   223     fflush(stdout);
   224     value = SDL_getenv("FIRST");
   225     if (value && (SDL_strcmp(value, "VALUE1") == 0)) {
   226         printf("okay\n");
   227     } else {
   228         printf("failed\n");
   229     }
   230     printf("Setting SECOND=VALUE2 in the environment... ");
   231     fflush(stdout);
   232     if (SDL_setenv("SECOND", "VALUE2", 0) == 0) {
   233         printf("okay\n");
   234     } else {
   235         printf("failed\n");
   236     }
   237     printf("Getting SECOND from the environment... ");
   238     fflush(stdout);
   239     value = SDL_getenv("SECOND");
   240     if (value && (SDL_strcmp(value, "VALUE2") == 0)) {
   241         printf("okay\n");
   242     } else {
   243         printf("failed\n");
   244     }
   245     printf("Setting FIRST=NOVALUE in the environment... ");
   246     fflush(stdout);
   247     if (SDL_setenv("FIRST", "NOVALUE", 1) == 0) {
   248         printf("okay\n");
   249     } else {
   250         printf("failed\n");
   251     }
   252     printf("Getting FIRST from the environment... ");
   253     fflush(stdout);
   254     value = SDL_getenv("FIRST");
   255     if (value && (SDL_strcmp(value, "NOVALUE") == 0)) {
   256         printf("okay\n");
   257     } else {
   258         printf("failed\n");
   259     }
   260     printf("Checking for non-existent variable... ");
   261     fflush(stdout);
   262     if (!SDL_getenv("EXISTS")) {
   263         printf("okay\n");
   264     } else {
   265         printf("failed\n");
   266     }
   267     return (0);
   268 }
   269 #endif /* TEST_MAIN */
   270 
   271 /* vi: set ts=4 sw=4 expandtab: */