comparison src/stdlib/SDL_getenv.c @ 3581:15eea7a1fa97

Implemented SDL_setenv(), moved SDL_putenv() to compat. Fixes Bugzilla #779.
author Ryan C. Gordon <icculus@icculus.org>
date Wed, 16 Dec 2009 10:59:51 +0000
parents 99210400e8b9
children 65f66674b7fb
comparison
equal deleted inserted replaced
3580:951dd6a5d1a2 3581:15eea7a1fa97
33 /* Note this isn't thread-safe! */ 33 /* Note this isn't thread-safe! */
34 34
35 static char *SDL_envmem = NULL; /* Ugh, memory leak */ 35 static char *SDL_envmem = NULL; /* Ugh, memory leak */
36 static size_t SDL_envmemlen = 0; 36 static size_t SDL_envmemlen = 0;
37 37
38 /* Put a variable of the form "name=value" into the environment */ 38 /* Put a variable into the environment */
39 int 39 int
40 SDL_putenv(const char *variable) 40 SDL_setenv(const char *name, const char *value, int overwrite)
41 { 41 {
42 size_t bufferlen; 42 if (!overwrite) {
43 char *value; 43 char ch = 0;
44 const char *sep; 44 const size_t len = GetEnvironmentVariable(name, &ch, sizeof (ch));
45 45 if (len > 0) {
46 sep = SDL_strchr(variable, '='); 46 return 0; /* asked not to overwrite existing value. */
47 if (sep == NULL) { 47 }
48 return -1; 48 }
49 } 49 if (!SetEnvironmentVariable(name, *value ? value : NULL)) {
50 bufferlen = SDL_strlen(variable) + 1;
51 if (bufferlen > SDL_envmemlen) {
52 char *newmem = (char *) SDL_realloc(SDL_envmem, bufferlen);
53 if (newmem == NULL) {
54 return -1;
55 }
56 SDL_envmem = newmem;
57 SDL_envmemlen = bufferlen;
58 }
59 SDL_strlcpy(SDL_envmem, variable, bufferlen);
60 value = SDL_envmem + (sep - variable);
61 *value++ = '\0';
62 if (!SetEnvironmentVariable(SDL_envmem, *value ? value : NULL)) {
63 return -1; 50 return -1;
64 } 51 }
65 return 0; 52 return 0;
66 } 53 }
67 54
90 77
91 #else /* roll our own */ 78 #else /* roll our own */
92 79
93 static char **SDL_env = (char **) 0; 80 static char **SDL_env = (char **) 0;
94 81
95 /* Put a variable of the form "name=value" into the environment */ 82 /* Put a variable into the environment */
96 int 83 int
97 SDL_putenv(const char *variable) 84 SDL_setenv(const char *name, const char *value, int overwrite)
98 { 85 {
99 const char *name, *value;
100 int added; 86 int added;
101 int len, i; 87 int len, i;
102 char **new_env; 88 char **new_env;
103 char *new_variable; 89 char *new_variable;
104 90
105 /* A little error checking */ 91 /* A little error checking */
106 if (!variable) { 92 if (!name || !value) {
107 return (-1); 93 return (-1);
108 } 94 }
109 name = variable;
110 for (value = variable; *value && (*value != '='); ++value) {
111 /* Keep looking for '=' */ ;
112 }
113 if (*value) {
114 ++value;
115 } else {
116 return (-1);
117 }
118 95
119 /* Allocate memory for the variable */ 96 /* Allocate memory for the variable */
120 new_variable = SDL_strdup(variable); 97 len = SDL_strlen(name) + SDL_strlen(value) + 2;
98 new_variable = (char *) SDL_malloc(len);
121 if (!new_variable) { 99 if (!new_variable) {
122 return (-1); 100 return (-1);
123 } 101 }
102
103 SDL_snprintf(new_variable, len, "%s=%s", name, value);
104 value = new_variable + SDL_strlen(name) + 1;
105 name = new_variable;
124 106
125 /* Actually put it into the environment */ 107 /* Actually put it into the environment */
126 added = 0; 108 added = 0;
127 i = 0; 109 i = 0;
128 if (SDL_env) { 110 if (SDL_env) {
133 break; 115 break;
134 } 116 }
135 } 117 }
136 /* If we found it, just replace the entry */ 118 /* If we found it, just replace the entry */
137 if (SDL_env[i]) { 119 if (SDL_env[i]) {
120 if (!overwrite) {
121 SDL_free(new_variable);
122 return 0;
123 }
138 SDL_free(SDL_env[i]); 124 SDL_free(SDL_env[i]);
139 SDL_env[i] = new_variable; 125 SDL_env[i] = new_variable;
140 added = 1; 126 added = 1;
141 } 127 }
142 } 128 }
178 164
179 #endif /* __WIN32__ */ 165 #endif /* __WIN32__ */
180 166
181 #endif /* !HAVE_GETENV */ 167 #endif /* !HAVE_GETENV */
182 168
169
170 /* We have a real environment table, but no real setenv? Fake it w/ putenv. */
171 #if (defined(HAVE_GETENV) && defined(HAVE_PUTENV) && !defined(HAVE_SETENV))
172 int
173 SDL_setenv(const char *name, const char *value, int overwrite)
174 {
175 size_t len;
176 char *new_variable;
177
178 if (getenv(name) != NULL) {
179 if (overwrite) {
180 unsetenv(name);
181 } else {
182 return 0; /* leave the existing one there. */
183 }
184 }
185
186 /* This leaks. Sorry. Get a better OS so we don't have to do this. */
187 len = SDL_strlen(name) + SDL_strlen(value) + 2;
188 new_variable = (char *) SDL_malloc(len);
189 if (!new_variable) {
190 return (-1);
191 }
192
193 SDL_snprintf(new_variable, len, "%s=%s", name, value);
194 return putenv(new_variable);
195 }
196 #endif
197
198
183 #ifdef TEST_MAIN 199 #ifdef TEST_MAIN
184 #include <stdio.h> 200 #include <stdio.h>
185 201
186 int 202 int
187 main(int argc, char *argv[]) 203 main(int argc, char *argv[])