handle src buffer underflow corner cases
[sdl_omap.git] / src / stdlib / SDL_getenv.c
CommitLineData
e14743d1 1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 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(__WIN32__) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
29
30#define WIN32_LEAN_AND_MEAN
31#include <windows.h>
32
33/* Note this isn't thread-safe! */
34
35static char *SDL_envmem = NULL; /* Ugh, memory leak */
36static size_t SDL_envmemlen = 0;
37
38/* Put a variable of the form "name=value" into the environment */
39int SDL_putenv(const char *variable)
40{
41 size_t bufferlen;
42 char *value;
43 const char *sep;
44
45 sep = SDL_strchr(variable, '=');
46 if ( sep == NULL ) {
47 return -1;
48 }
49 bufferlen = SDL_strlen(variable)+1;
50 if ( bufferlen > SDL_envmemlen ) {
51 char *newmem = (char *)SDL_realloc(SDL_envmem, bufferlen);
52 if ( newmem == NULL ) {
53 return -1;
54 }
55 SDL_envmem = newmem;
56 SDL_envmemlen = bufferlen;
57 }
58 SDL_strlcpy(SDL_envmem, variable, bufferlen);
59 value = SDL_envmem + (sep - variable);
60 *value++ = '\0';
61 if ( !SetEnvironmentVariable(SDL_envmem, *value ? value : NULL) ) {
62 return -1;
63 }
64 return 0;
65}
66
67/* Retrieve a variable named "name" from the environment */
68char *SDL_getenv(const char *name)
69{
70 size_t bufferlen;
71
72 bufferlen = GetEnvironmentVariable(name, SDL_envmem, (DWORD)SDL_envmemlen);
73 if ( bufferlen == 0 ) {
74 return NULL;
75 }
76 if ( bufferlen > SDL_envmemlen ) {
77 char *newmem = (char *)SDL_realloc(SDL_envmem, bufferlen);
78 if ( newmem == NULL ) {
79 return NULL;
80 }
81 SDL_envmem = newmem;
82 SDL_envmemlen = bufferlen;
83 GetEnvironmentVariable(name, SDL_envmem, (DWORD)SDL_envmemlen);
84 }
85 return SDL_envmem;
86}
87
88#else /* roll our own */
89
90static char **SDL_env = (char **)0;
91
92/* Put a variable of the form "name=value" into the environment */
93int SDL_putenv(const char *variable)
94{
95 const char *name, *value;
96 int added;
97 int len, i;
98 char **new_env;
99 char *new_variable;
100
101 /* A little error checking */
102 if ( ! variable ) {
103 return(-1);
104 }
105 name = variable;
106 for ( value=variable; *value && (*value != '='); ++value ) {
107 /* Keep looking for '=' */ ;
108 }
109 if ( *value ) {
110 ++value;
111 } else {
112 return(-1);
113 }
114
115 /* Allocate memory for the variable */
116 new_variable = SDL_strdup(variable);
117 if ( ! new_variable ) {
118 return(-1);
119 }
120
121 /* Actually put it into the environment */
122 added = 0;
123 i = 0;
124 if ( SDL_env ) {
125 /* Check to see if it's already there... */
126 len = (value - name);
127 for ( ; SDL_env[i]; ++i ) {
128 if ( SDL_strncmp(SDL_env[i], name, len) == 0 ) {
129 break;
130 }
131 }
132 /* If we found it, just replace the entry */
133 if ( SDL_env[i] ) {
134 SDL_free(SDL_env[i]);
135 SDL_env[i] = new_variable;
136 added = 1;
137 }
138 }
139
140 /* Didn't find it in the environment, expand and add */
141 if ( ! added ) {
142 new_env = SDL_realloc(SDL_env, (i+2)*sizeof(char *));
143 if ( new_env ) {
144 SDL_env = new_env;
145 SDL_env[i++] = new_variable;
146 SDL_env[i++] = (char *)0;
147 added = 1;
148 } else {
149 SDL_free(new_variable);
150 }
151 }
152 return (added ? 0 : -1);
153}
154
155/* Retrieve a variable named "name" from the environment */
156char *SDL_getenv(const char *name)
157{
158 int len, i;
159 char *value;
160
161 value = (char *)0;
162 if ( SDL_env ) {
163 len = SDL_strlen(name);
164 for ( i=0; SDL_env[i] && !value; ++i ) {
165 if ( (SDL_strncmp(SDL_env[i], name, len) == 0) &&
166 (SDL_env[i][len] == '=') ) {
167 value = &SDL_env[i][len+1];
168 }
169 }
170 }
171 return value;
172}
173
174#endif /* __WIN32__ */
175
176#endif /* !HAVE_GETENV */
177
178#ifdef TEST_MAIN
179#include <stdio.h>
180
181int main(int argc, char *argv[])
182{
183 char *value;
184
185 printf("Checking for non-existent variable... ");
186 fflush(stdout);
187 if ( ! SDL_getenv("EXISTS") ) {
188 printf("okay\n");
189 } else {
190 printf("failed\n");
191 }
192 printf("Setting FIRST=VALUE1 in the environment... ");
193 fflush(stdout);
194 if ( SDL_putenv("FIRST=VALUE1") == 0 ) {
195 printf("okay\n");
196 } else {
197 printf("failed\n");
198 }
199 printf("Getting FIRST from the environment... ");
200 fflush(stdout);
201 value = SDL_getenv("FIRST");
202 if ( value && (SDL_strcmp(value, "VALUE1") == 0) ) {
203 printf("okay\n");
204 } else {
205 printf("failed\n");
206 }
207 printf("Setting SECOND=VALUE2 in the environment... ");
208 fflush(stdout);
209 if ( SDL_putenv("SECOND=VALUE2") == 0 ) {
210 printf("okay\n");
211 } else {
212 printf("failed\n");
213 }
214 printf("Getting SECOND from the environment... ");
215 fflush(stdout);
216 value = SDL_getenv("SECOND");
217 if ( value && (SDL_strcmp(value, "VALUE2") == 0) ) {
218 printf("okay\n");
219 } else {
220 printf("failed\n");
221 }
222 printf("Setting FIRST=NOVALUE in the environment... ");
223 fflush(stdout);
224 if ( SDL_putenv("FIRST=NOVALUE") == 0 ) {
225 printf("okay\n");
226 } else {
227 printf("failed\n");
228 }
229 printf("Getting FIRST from the environment... ");
230 fflush(stdout);
231 value = SDL_getenv("FIRST");
232 if ( value && (SDL_strcmp(value, "NOVALUE") == 0) ) {
233 printf("okay\n");
234 } else {
235 printf("failed\n");
236 }
237 printf("Checking for non-existent variable... ");
238 fflush(stdout);
239 if ( ! SDL_getenv("EXISTS") ) {
240 printf("okay\n");
241 } else {
242 printf("failed\n");
243 }
244 return(0);
245}
246#endif /* TEST_MAIN */
247