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