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