msvcrt: Import lroundf implementation from musl.
[wine.git] / dlls / msvcrt / environ.c
blob698dc761381f40172c172abb42a4840d2d4b8c37
1 /*
2 * msvcrt.dll environment functions
4 * Copyright 1996,1998 Marcus Meissner
5 * Copyright 1996 Jukka Iivonen
6 * Copyright 1997,2000 Uwe Bonnes
7 * Copyright 2000 Jon Griffiths
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "msvcrt.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
28 /*********************************************************************
29 * getenv (MSVCRT.@)
31 char * CDECL getenv(const char *name)
33 char **env;
34 unsigned int length=strlen(name);
36 for (env = MSVCRT__environ; *env; env++)
38 char *str = *env;
39 char *pos = strchr(str,'=');
40 if (pos && ((pos - str) == length) && !_strnicmp(str,name,length))
42 TRACE("(%s): got %s\n", debugstr_a(name), debugstr_a(pos + 1));
43 return pos + 1;
46 return NULL;
49 /*********************************************************************
50 * _wgetenv (MSVCRT.@)
52 wchar_t * CDECL _wgetenv(const wchar_t *name)
54 wchar_t **env;
55 unsigned int length=wcslen(name);
57 /* Initialize the _wenviron array if it's not already created. */
58 if (!MSVCRT__wenviron)
59 MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(NULL);
61 for (env = MSVCRT__wenviron; *env; env++)
63 wchar_t *str = *env;
64 wchar_t *pos = wcschr(str,'=');
65 if (pos && ((pos - str) == length) && !_wcsnicmp(str,name,length))
67 TRACE("(%s): got %s\n", debugstr_w(name), debugstr_w(pos + 1));
68 return pos + 1;
71 return NULL;
74 /*********************************************************************
75 * _putenv (MSVCRT.@)
77 int CDECL _putenv(const char *str)
79 char *name, *value;
80 char *dst;
81 int ret;
83 TRACE("%s\n", debugstr_a(str));
85 if (!str)
86 return -1;
88 name = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
89 if (!name)
90 return -1;
91 dst = name;
92 while (*str && *str != '=')
93 *dst++ = *str++;
94 if (!*str++)
96 ret = -1;
97 goto finish;
99 *dst++ = '\0';
100 value = dst;
101 while (*str)
102 *dst++ = *str++;
103 *dst = '\0';
105 ret = SetEnvironmentVariableA(name, value[0] ? value : NULL) ? 0 : -1;
107 /* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
108 if ((ret == -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) ret = 0;
110 MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ);
111 /* Update the __p__wenviron array only when already initialized */
112 if (MSVCRT__wenviron)
113 MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron);
115 finish:
116 HeapFree(GetProcessHeap(), 0, name);
117 return ret;
120 /*********************************************************************
121 * _wputenv (MSVCRT.@)
123 int CDECL _wputenv(const wchar_t *str)
125 wchar_t *name, *value;
126 wchar_t *dst;
127 int ret;
129 TRACE("%s\n", debugstr_w(str));
131 if (!str)
132 return -1;
133 name = HeapAlloc(GetProcessHeap(), 0, (wcslen(str) + 1) * sizeof(wchar_t));
134 if (!name)
135 return -1;
136 dst = name;
137 while (*str && *str != '=')
138 *dst++ = *str++;
139 if (!*str++)
141 ret = -1;
142 goto finish;
144 *dst++ = 0;
145 value = dst;
146 while (*str)
147 *dst++ = *str++;
148 *dst = 0;
150 ret = SetEnvironmentVariableW(name, value[0] ? value : NULL) ? 0 : -1;
152 /* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
153 if ((ret == -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) ret = 0;
155 MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ);
156 MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron);
158 finish:
159 HeapFree(GetProcessHeap(), 0, name);
160 return ret;
163 /*********************************************************************
164 * _putenv_s (MSVCRT.@)
166 int CDECL _putenv_s(const char *name, const char *value)
168 int ret;
170 TRACE("%s %s\n", debugstr_a(name), debugstr_a(value));
172 if (!MSVCRT_CHECK_PMT(name != NULL)) return -1;
173 if (!MSVCRT_CHECK_PMT(value != NULL)) return -1;
175 ret = SetEnvironmentVariableA(name, value[0] ? value : NULL) ? 0 : -1;
177 /* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
178 if ((ret == -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) ret = 0;
180 MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ);
181 MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron);
183 return ret;
186 /*********************************************************************
187 * _wputenv_s (MSVCRT.@)
189 int CDECL _wputenv_s(const wchar_t *name, const wchar_t *value)
191 int ret;
193 TRACE("%s %s\n", debugstr_w(name), debugstr_w(value));
195 if (!MSVCRT_CHECK_PMT(name != NULL)) return -1;
196 if (!MSVCRT_CHECK_PMT(value != NULL)) return -1;
198 ret = SetEnvironmentVariableW(name, value[0] ? value : NULL) ? 0 : -1;
200 /* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
201 if ((ret == -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) ret = 0;
203 MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ);
204 MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(MSVCRT__wenviron);
206 return ret;
209 #if _MSVCR_VER>=80
211 /******************************************************************
212 * _dupenv_s (MSVCR80.@)
214 int CDECL _dupenv_s(char **buffer, size_t *numberOfElements, const char *varname)
216 char *e;
217 size_t sz;
219 if (!MSVCRT_CHECK_PMT(buffer != NULL)) return EINVAL;
220 if (!MSVCRT_CHECK_PMT(varname != NULL)) return EINVAL;
222 if (!(e = getenv(varname))) return *_errno() = EINVAL;
224 sz = strlen(e) + 1;
225 if (!(*buffer = malloc(sz)))
227 if (numberOfElements) *numberOfElements = 0;
228 return *_errno() = ENOMEM;
230 strcpy(*buffer, e);
231 if (numberOfElements) *numberOfElements = sz;
232 return 0;
235 /******************************************************************
236 * _wdupenv_s (MSVCR80.@)
238 int CDECL _wdupenv_s(wchar_t **buffer, size_t *numberOfElements,
239 const wchar_t *varname)
241 wchar_t *e;
242 size_t sz;
244 if (!MSVCRT_CHECK_PMT(buffer != NULL)) return EINVAL;
245 if (!MSVCRT_CHECK_PMT(varname != NULL)) return EINVAL;
247 if (!(e = _wgetenv(varname))) return *_errno() = EINVAL;
249 sz = wcslen(e) + 1;
250 if (!(*buffer = malloc(sz * sizeof(wchar_t))))
252 if (numberOfElements) *numberOfElements = 0;
253 return *_errno() = ENOMEM;
255 wcscpy(*buffer, e);
256 if (numberOfElements) *numberOfElements = sz;
257 return 0;
260 #endif /* _MSVCR_VER>=80 */
262 /******************************************************************
263 * getenv_s (MSVCRT.@)
265 int CDECL getenv_s(size_t *pReturnValue, char* buffer, size_t numberOfElements, const char *varname)
267 char *e;
269 if (!MSVCRT_CHECK_PMT(pReturnValue != NULL)) return EINVAL;
270 if (!MSVCRT_CHECK_PMT(!(buffer == NULL && numberOfElements > 0))) return EINVAL;
271 if (!MSVCRT_CHECK_PMT(varname != NULL)) return EINVAL;
273 if (!(e = getenv(varname)))
275 *pReturnValue = 0;
276 return *_errno() = EINVAL;
278 *pReturnValue = strlen(e) + 1;
279 if (numberOfElements < *pReturnValue)
281 return *_errno() = ERANGE;
283 strcpy(buffer, e);
284 return 0;
287 /******************************************************************
288 * _wgetenv_s (MSVCRT.@)
290 int CDECL _wgetenv_s(size_t *pReturnValue, wchar_t *buffer, size_t numberOfElements,
291 const wchar_t *varname)
293 wchar_t *e;
295 if (!MSVCRT_CHECK_PMT(pReturnValue != NULL)) return EINVAL;
296 if (!MSVCRT_CHECK_PMT(!(buffer == NULL && numberOfElements > 0))) return EINVAL;
297 if (!MSVCRT_CHECK_PMT(varname != NULL)) return EINVAL;
299 if (!(e = _wgetenv(varname)))
301 *pReturnValue = 0;
302 return *_errno() = EINVAL;
304 *pReturnValue = wcslen(e) + 1;
305 if (numberOfElements < *pReturnValue)
307 return *_errno() = ERANGE;
309 wcscpy(buffer, e);
310 return 0;
313 /*********************************************************************
314 * _get_environ (MSVCRT.@)
316 void CDECL _get_environ(char ***ptr)
318 *ptr = MSVCRT__environ;
321 /*********************************************************************
322 * _get_wenviron (MSVCRT.@)
324 void CDECL _get_wenviron(wchar_t ***ptr)
326 *ptr = MSVCRT__wenviron;