sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_getenv.c (8419B)


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