/src/irssi/subprojects/glib-2.74.3/glib/genviron.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* GLIB - Library of useful routines for C programming |
2 | | * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald |
3 | | * |
4 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
5 | | * |
6 | | * This library is free software; you can redistribute it and/or |
7 | | * modify it under the terms of the GNU Lesser General Public |
8 | | * License as published by the Free Software Foundation; either |
9 | | * version 2.1 of the License, or (at your option) any later version. |
10 | | * |
11 | | * This library is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | | * Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
18 | | */ |
19 | | |
20 | | /* |
21 | | * Modified by the GLib Team and others 1997-2000. See the AUTHORS |
22 | | * file for a list of people on the GLib Team. See the ChangeLog |
23 | | * files for a list of changes. These files are distributed with |
24 | | * GLib at ftp://ftp.gtk.org/pub/gtk/. |
25 | | */ |
26 | | |
27 | | #include "config.h" |
28 | | |
29 | | #include "genviron.h" |
30 | | |
31 | | #include <stdlib.h> |
32 | | #include <string.h> |
33 | | #ifdef HAVE_CRT_EXTERNS_H |
34 | | #include <crt_externs.h> /* for _NSGetEnviron */ |
35 | | #endif |
36 | | #ifdef G_OS_WIN32 |
37 | | #include <windows.h> |
38 | | #endif |
39 | | |
40 | | #include "glib-private.h" |
41 | | #include "gmem.h" |
42 | | #include "gmessages.h" |
43 | | #include "gstrfuncs.h" |
44 | | #include "gunicode.h" |
45 | | #include "gconvert.h" |
46 | | #include "gquark.h" |
47 | | #include "gthreadprivate.h" |
48 | | |
49 | | /* Environ array functions {{{1 */ |
50 | | static gboolean |
51 | | g_environ_matches (const gchar *env, const gchar *variable, gsize len) |
52 | 0 | { |
53 | | #ifdef G_OS_WIN32 |
54 | | /* TODO handle Unicode environment variable names */ |
55 | | /* Like filesystem paths, environment variables are case-insensitive. */ |
56 | | return g_ascii_strncasecmp (env, variable, len) == 0 && env[len] == '='; |
57 | | #else |
58 | 0 | return strncmp (env, variable, len) == 0 && env[len] == '='; |
59 | 0 | #endif |
60 | 0 | } |
61 | | |
62 | | static gint |
63 | | g_environ_find (gchar **envp, |
64 | | const gchar *variable) |
65 | 0 | { |
66 | 0 | gsize len; |
67 | 0 | gint i; |
68 | |
|
69 | 0 | if (envp == NULL) |
70 | 0 | return -1; |
71 | | |
72 | 0 | len = strlen (variable); |
73 | |
|
74 | 0 | for (i = 0; envp[i]; i++) |
75 | 0 | { |
76 | 0 | if (g_environ_matches (envp[i], variable, len)) |
77 | 0 | return i; |
78 | 0 | } |
79 | | |
80 | 0 | return -1; |
81 | 0 | } |
82 | | |
83 | | /** |
84 | | * g_environ_getenv: |
85 | | * @envp: (nullable) (array zero-terminated=1) (transfer none) (element-type filename): |
86 | | * an environment list (eg, as returned from g_get_environ()), or %NULL |
87 | | * for an empty environment list |
88 | | * @variable: (type filename): the environment variable to get |
89 | | * |
90 | | * Returns the value of the environment variable @variable in the |
91 | | * provided list @envp. |
92 | | * |
93 | | * Returns: (type filename) (nullable): the value of the environment variable, or %NULL if |
94 | | * the environment variable is not set in @envp. The returned |
95 | | * string is owned by @envp, and will be freed if @variable is |
96 | | * set or unset again. |
97 | | * |
98 | | * Since: 2.32 |
99 | | */ |
100 | | const gchar * |
101 | | g_environ_getenv (gchar **envp, |
102 | | const gchar *variable) |
103 | 0 | { |
104 | 0 | gint index; |
105 | |
|
106 | 0 | g_return_val_if_fail (variable != NULL, NULL); |
107 | | |
108 | 0 | index = g_environ_find (envp, variable); |
109 | 0 | if (index != -1) |
110 | 0 | return envp[index] + strlen (variable) + 1; |
111 | 0 | else |
112 | 0 | return NULL; |
113 | 0 | } |
114 | | |
115 | | /** |
116 | | * g_environ_setenv: |
117 | | * @envp: (nullable) (array zero-terminated=1) (element-type filename) (transfer full): |
118 | | * an environment list that can be freed using g_strfreev() (e.g., as |
119 | | * returned from g_get_environ()), or %NULL for an empty |
120 | | * environment list |
121 | | * @variable: (type filename): the environment variable to set, must not |
122 | | * contain '=' |
123 | | * @value: (type filename): the value for to set the variable to |
124 | | * @overwrite: whether to change the variable if it already exists |
125 | | * |
126 | | * Sets the environment variable @variable in the provided list |
127 | | * @envp to @value. |
128 | | * |
129 | | * Returns: (array zero-terminated=1) (element-type filename) (transfer full): |
130 | | * the updated environment list. Free it using g_strfreev(). |
131 | | * |
132 | | * Since: 2.32 |
133 | | */ |
134 | | gchar ** |
135 | | g_environ_setenv (gchar **envp, |
136 | | const gchar *variable, |
137 | | const gchar *value, |
138 | | gboolean overwrite) |
139 | 0 | { |
140 | 0 | gint index; |
141 | |
|
142 | 0 | g_return_val_if_fail (variable != NULL, NULL); |
143 | 0 | g_return_val_if_fail (strchr (variable, '=') == NULL, NULL); |
144 | 0 | g_return_val_if_fail (value != NULL, NULL); |
145 | | |
146 | 0 | index = g_environ_find (envp, variable); |
147 | 0 | if (index != -1) |
148 | 0 | { |
149 | 0 | if (overwrite) |
150 | 0 | { |
151 | 0 | g_free (envp[index]); |
152 | 0 | envp[index] = g_strdup_printf ("%s=%s", variable, value); |
153 | 0 | } |
154 | 0 | } |
155 | 0 | else |
156 | 0 | { |
157 | 0 | gint length; |
158 | |
|
159 | 0 | length = envp ? g_strv_length (envp) : 0; |
160 | 0 | envp = g_renew (gchar *, envp, length + 2); |
161 | 0 | envp[length] = g_strdup_printf ("%s=%s", variable, value); |
162 | 0 | envp[length + 1] = NULL; |
163 | 0 | } |
164 | |
|
165 | 0 | return envp; |
166 | 0 | } |
167 | | |
168 | | static gchar ** |
169 | | g_environ_unsetenv_internal (gchar **envp, |
170 | | const gchar *variable, |
171 | | gboolean free_value) |
172 | 0 | { |
173 | 0 | gsize len; |
174 | 0 | gchar **e, **f; |
175 | |
|
176 | 0 | len = strlen (variable); |
177 | | |
178 | | /* Note that we remove *all* environment entries for |
179 | | * the variable name, not just the first. |
180 | | */ |
181 | 0 | e = f = envp; |
182 | 0 | while (*e != NULL) |
183 | 0 | { |
184 | 0 | if (!g_environ_matches (*e, variable, len)) |
185 | 0 | { |
186 | 0 | *f = *e; |
187 | 0 | f++; |
188 | 0 | } |
189 | 0 | else |
190 | 0 | { |
191 | 0 | if (free_value) |
192 | 0 | g_free (*e); |
193 | 0 | } |
194 | |
|
195 | 0 | e++; |
196 | 0 | } |
197 | 0 | *f = NULL; |
198 | |
|
199 | 0 | return envp; |
200 | 0 | } |
201 | | |
202 | | |
203 | | /** |
204 | | * g_environ_unsetenv: |
205 | | * @envp: (nullable) (array zero-terminated=1) (element-type filename) (transfer full): |
206 | | * an environment list that can be freed using g_strfreev() (e.g., as |
207 | | * returned from g_get_environ()), or %NULL for an empty environment list |
208 | | * @variable: (type filename): the environment variable to remove, must not |
209 | | * contain '=' |
210 | | * |
211 | | * Removes the environment variable @variable from the provided |
212 | | * environment @envp. |
213 | | * |
214 | | * Returns: (array zero-terminated=1) (element-type filename) (transfer full): |
215 | | * the updated environment list. Free it using g_strfreev(). |
216 | | * |
217 | | * Since: 2.32 |
218 | | */ |
219 | | gchar ** |
220 | | g_environ_unsetenv (gchar **envp, |
221 | | const gchar *variable) |
222 | 0 | { |
223 | 0 | g_return_val_if_fail (variable != NULL, NULL); |
224 | 0 | g_return_val_if_fail (strchr (variable, '=') == NULL, NULL); |
225 | | |
226 | 0 | if (envp == NULL) |
227 | 0 | return NULL; |
228 | | |
229 | 0 | return g_environ_unsetenv_internal (envp, variable, TRUE); |
230 | 0 | } |
231 | | |
232 | | /* UNIX implementation {{{1 */ |
233 | | #ifndef G_OS_WIN32 |
234 | | |
235 | | /** |
236 | | * g_getenv: |
237 | | * @variable: (type filename): the environment variable to get |
238 | | * |
239 | | * Returns the value of an environment variable. |
240 | | * |
241 | | * On UNIX, the name and value are byte strings which might or might not |
242 | | * be in some consistent character set and encoding. On Windows, they are |
243 | | * in UTF-8. |
244 | | * On Windows, in case the environment variable's value contains |
245 | | * references to other environment variables, they are expanded. |
246 | | * |
247 | | * Returns: (type filename) (nullable): the value of the environment variable, or %NULL if |
248 | | * the environment variable is not found. The returned string |
249 | | * may be overwritten by the next call to g_getenv(), g_setenv() |
250 | | * or g_unsetenv(). |
251 | | */ |
252 | | const gchar * |
253 | | g_getenv (const gchar *variable) |
254 | 1.36k | { |
255 | 1.36k | g_return_val_if_fail (variable != NULL, NULL); |
256 | | |
257 | 1.36k | return getenv (variable); |
258 | 1.36k | } |
259 | | |
260 | | /** |
261 | | * g_setenv: |
262 | | * @variable: (type filename): the environment variable to set, must not |
263 | | * contain '='. |
264 | | * @value: (type filename): the value for to set the variable to. |
265 | | * @overwrite: whether to change the variable if it already exists. |
266 | | * |
267 | | * Sets an environment variable. On UNIX, both the variable's name and |
268 | | * value can be arbitrary byte strings, except that the variable's name |
269 | | * cannot contain '='. On Windows, they should be in UTF-8. |
270 | | * |
271 | | * Note that on some systems, when variables are overwritten, the memory |
272 | | * used for the previous variables and its value isn't reclaimed. |
273 | | * |
274 | | * You should be mindful of the fact that environment variable handling |
275 | | * in UNIX is not thread-safe, and your program may crash if one thread |
276 | | * calls g_setenv() while another thread is calling getenv(). (And note |
277 | | * that many functions, such as gettext(), call getenv() internally.) |
278 | | * This function is only safe to use at the very start of your program, |
279 | | * before creating any other threads (or creating objects that create |
280 | | * worker threads of their own). |
281 | | * |
282 | | * If you need to set up the environment for a child process, you can |
283 | | * use g_get_environ() to get an environment array, modify that with |
284 | | * g_environ_setenv() and g_environ_unsetenv(), and then pass that |
285 | | * array directly to execvpe(), g_spawn_async(), or the like. |
286 | | * |
287 | | * Returns: %FALSE if the environment variable couldn't be set. |
288 | | * |
289 | | * Since: 2.4 |
290 | | */ |
291 | | gboolean |
292 | | g_setenv (const gchar *variable, |
293 | | const gchar *value, |
294 | | gboolean overwrite) |
295 | 0 | { |
296 | 0 | gint result; |
297 | | #ifndef HAVE_SETENV |
298 | | gchar *string; |
299 | | #endif |
300 | |
|
301 | 0 | g_return_val_if_fail (variable != NULL, FALSE); |
302 | 0 | g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE); |
303 | 0 | g_return_val_if_fail (value != NULL, FALSE); |
304 | | |
305 | 0 | #ifndef G_DISABLE_CHECKS |
306 | | /* FIXME: This will be upgraded to a g_warning() in a future release of GLib. |
307 | | * See https://gitlab.gnome.org/GNOME/glib/issues/715 */ |
308 | 0 | if (g_thread_n_created () > 0) |
309 | 0 | g_debug ("setenv()/putenv() are not thread-safe and should not be used after threads are created"); |
310 | 0 | #endif |
311 | |
|
312 | 0 | #ifdef HAVE_SETENV |
313 | 0 | result = setenv (variable, value, overwrite); |
314 | | #else |
315 | | if (!overwrite && getenv (variable) != NULL) |
316 | | return TRUE; |
317 | | |
318 | | /* This results in a leak when you overwrite existing |
319 | | * settings. It would be fairly easy to fix this by keeping |
320 | | * our own parallel array or hash table. |
321 | | */ |
322 | | string = g_strconcat (variable, "=", value, NULL); |
323 | | result = putenv (string); |
324 | | #endif |
325 | 0 | return result == 0; |
326 | 0 | } |
327 | | |
328 | | #ifdef HAVE__NSGETENVIRON |
329 | | #define environ (*_NSGetEnviron()) |
330 | | #else |
331 | | /* According to the Single Unix Specification, environ is not |
332 | | * in any system header, although unistd.h often declares it. |
333 | | */ |
334 | | extern char **environ; |
335 | | #endif |
336 | | |
337 | | /** |
338 | | * g_unsetenv: |
339 | | * @variable: (type filename): the environment variable to remove, must |
340 | | * not contain '=' |
341 | | * |
342 | | * Removes an environment variable from the environment. |
343 | | * |
344 | | * Note that on some systems, when variables are overwritten, the |
345 | | * memory used for the previous variables and its value isn't reclaimed. |
346 | | * |
347 | | * You should be mindful of the fact that environment variable handling |
348 | | * in UNIX is not thread-safe, and your program may crash if one thread |
349 | | * calls g_unsetenv() while another thread is calling getenv(). (And note |
350 | | * that many functions, such as gettext(), call getenv() internally.) This |
351 | | * function is only safe to use at the very start of your program, before |
352 | | * creating any other threads (or creating objects that create worker |
353 | | * threads of their own). |
354 | | * |
355 | | * If you need to set up the environment for a child process, you can |
356 | | * use g_get_environ() to get an environment array, modify that with |
357 | | * g_environ_setenv() and g_environ_unsetenv(), and then pass that |
358 | | * array directly to execvpe(), g_spawn_async(), or the like. |
359 | | * |
360 | | * Since: 2.4 |
361 | | */ |
362 | | void |
363 | | g_unsetenv (const gchar *variable) |
364 | 0 | { |
365 | 0 | g_return_if_fail (variable != NULL); |
366 | 0 | g_return_if_fail (strchr (variable, '=') == NULL); |
367 | | |
368 | 0 | #ifndef G_DISABLE_CHECKS |
369 | | /* FIXME: This will be upgraded to a g_warning() in a future release of GLib. |
370 | | * See https://gitlab.gnome.org/GNOME/glib/issues/715 */ |
371 | 0 | if (g_thread_n_created () > 0) |
372 | 0 | g_debug ("unsetenv() is not thread-safe and should not be used after threads are created"); |
373 | 0 | #endif |
374 | |
|
375 | 0 | #ifdef HAVE_UNSETENV |
376 | 0 | unsetenv (variable); |
377 | | #else /* !HAVE_UNSETENV */ |
378 | | /* Mess directly with the environ array. |
379 | | * This seems to be the only portable way to do this. |
380 | | */ |
381 | | g_environ_unsetenv_internal (environ, variable, FALSE); |
382 | | #endif /* !HAVE_UNSETENV */ |
383 | 0 | } |
384 | | |
385 | | /** |
386 | | * g_listenv: |
387 | | * |
388 | | * Gets the names of all variables set in the environment. |
389 | | * |
390 | | * Programs that want to be portable to Windows should typically use |
391 | | * this function and g_getenv() instead of using the environ array |
392 | | * from the C library directly. On Windows, the strings in the environ |
393 | | * array are in system codepage encoding, while in most of the typical |
394 | | * use cases for environment variables in GLib-using programs you want |
395 | | * the UTF-8 encoding that this function and g_getenv() provide. |
396 | | * |
397 | | * Returns: (array zero-terminated=1) (element-type filename) (transfer full): |
398 | | * a %NULL-terminated list of strings which must be freed with |
399 | | * g_strfreev(). |
400 | | * |
401 | | * Since: 2.8 |
402 | | */ |
403 | | gchar ** |
404 | | g_listenv (void) |
405 | 0 | { |
406 | 0 | gchar **result, *eq; |
407 | 0 | gint len, i, j; |
408 | |
|
409 | 0 | len = g_strv_length (environ); |
410 | 0 | result = g_new0 (gchar *, len + 1); |
411 | |
|
412 | 0 | j = 0; |
413 | 0 | for (i = 0; i < len; i++) |
414 | 0 | { |
415 | 0 | eq = strchr (environ[i], '='); |
416 | 0 | if (eq) |
417 | 0 | result[j++] = g_strndup (environ[i], eq - environ[i]); |
418 | 0 | } |
419 | |
|
420 | 0 | result[j] = NULL; |
421 | |
|
422 | 0 | return result; |
423 | 0 | } |
424 | | |
425 | | /** |
426 | | * g_get_environ: |
427 | | * |
428 | | * Gets the list of environment variables for the current process. |
429 | | * |
430 | | * The list is %NULL terminated and each item in the list is of the |
431 | | * form 'NAME=VALUE'. |
432 | | * |
433 | | * This is equivalent to direct access to the 'environ' global variable, |
434 | | * except portable. |
435 | | * |
436 | | * The return value is freshly allocated and it should be freed with |
437 | | * g_strfreev() when it is no longer needed. |
438 | | * |
439 | | * Returns: (array zero-terminated=1) (element-type filename) (transfer full): |
440 | | * the list of environment variables |
441 | | * |
442 | | * Since: 2.28 |
443 | | */ |
444 | | gchar ** |
445 | | g_get_environ (void) |
446 | 0 | { |
447 | 0 | return g_strdupv (environ); |
448 | 0 | } |
449 | | |
450 | | /* Win32 implementation {{{1 */ |
451 | | #else /* G_OS_WIN32 */ |
452 | | |
453 | | const gchar * |
454 | | g_getenv (const gchar *variable) |
455 | | { |
456 | | GQuark quark; |
457 | | gchar *value; |
458 | | wchar_t dummy[2], *wname, *wvalue; |
459 | | DWORD len; |
460 | | |
461 | | g_return_val_if_fail (variable != NULL, NULL); |
462 | | g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), NULL); |
463 | | |
464 | | /* On Windows NT, it is relatively typical that environment |
465 | | * variables contain references to other environment variables. If |
466 | | * so, use ExpandEnvironmentStrings(). (In an ideal world, such |
467 | | * environment variables would be stored in the Registry as |
468 | | * REG_EXPAND_SZ type values, and would then get automatically |
469 | | * expanded before a program sees them. But there is broken software |
470 | | * that stores environment variables as REG_SZ values even if they |
471 | | * contain references to other environment variables.) |
472 | | */ |
473 | | |
474 | | wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL); |
475 | | |
476 | | len = GetEnvironmentVariableW (wname, dummy, 2); |
477 | | |
478 | | if (len == 0) |
479 | | { |
480 | | g_free (wname); |
481 | | if (GetLastError () == ERROR_ENVVAR_NOT_FOUND) |
482 | | return NULL; |
483 | | |
484 | | quark = g_quark_from_static_string (""); |
485 | | return g_quark_to_string (quark); |
486 | | } |
487 | | else if (len == 1) |
488 | | len = 2; |
489 | | |
490 | | wvalue = g_new (wchar_t, len); |
491 | | |
492 | | if (GetEnvironmentVariableW (wname, wvalue, len) != len - 1) |
493 | | { |
494 | | g_free (wname); |
495 | | g_free (wvalue); |
496 | | return NULL; |
497 | | } |
498 | | |
499 | | if (wcschr (wvalue, L'%') != NULL) |
500 | | { |
501 | | wchar_t *tem = wvalue; |
502 | | |
503 | | len = ExpandEnvironmentStringsW (wvalue, dummy, 2); |
504 | | |
505 | | if (len > 0) |
506 | | { |
507 | | wvalue = g_new (wchar_t, len); |
508 | | |
509 | | if (ExpandEnvironmentStringsW (tem, wvalue, len) != len) |
510 | | { |
511 | | g_free (wvalue); |
512 | | wvalue = tem; |
513 | | } |
514 | | else |
515 | | g_free (tem); |
516 | | } |
517 | | } |
518 | | |
519 | | value = g_utf16_to_utf8 (wvalue, -1, NULL, NULL, NULL); |
520 | | |
521 | | g_free (wname); |
522 | | g_free (wvalue); |
523 | | |
524 | | quark = g_quark_from_string (value); |
525 | | g_free (value); |
526 | | |
527 | | return g_quark_to_string (quark); |
528 | | } |
529 | | |
530 | | gboolean |
531 | | g_setenv (const gchar *variable, |
532 | | const gchar *value, |
533 | | gboolean overwrite) |
534 | | { |
535 | | gboolean retval; |
536 | | wchar_t *wname, *wvalue, *wassignment; |
537 | | gchar *tem; |
538 | | |
539 | | g_return_val_if_fail (variable != NULL, FALSE); |
540 | | g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE); |
541 | | g_return_val_if_fail (value != NULL, FALSE); |
542 | | g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), FALSE); |
543 | | g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE); |
544 | | |
545 | | if (!overwrite && g_getenv (variable) != NULL) |
546 | | return TRUE; |
547 | | |
548 | | /* We want to (if possible) set both the environment variable copy |
549 | | * kept by the C runtime and the one kept by the system. |
550 | | * |
551 | | * We can't use only the C runtime's putenv or _wputenv() as that |
552 | | * won't work for arbitrary Unicode strings in a "non-Unicode" app |
553 | | * (with main() and not wmain()). In a "main()" app the C runtime |
554 | | * initializes the C runtime's environment table by converting the |
555 | | * real (wide char) environment variables to system codepage, thus |
556 | | * breaking those that aren't representable in the system codepage. |
557 | | * |
558 | | * As the C runtime's putenv() will also set the system copy, we do |
559 | | * the putenv() first, then call SetEnvironmentValueW ourselves. |
560 | | */ |
561 | | |
562 | | wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL); |
563 | | wvalue = g_utf8_to_utf16 (value, -1, NULL, NULL, NULL); |
564 | | tem = g_strconcat (variable, "=", value, NULL); |
565 | | wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL); |
566 | | |
567 | | g_free (tem); |
568 | | _wputenv (wassignment); |
569 | | g_free (wassignment); |
570 | | |
571 | | retval = (SetEnvironmentVariableW (wname, wvalue) != 0); |
572 | | |
573 | | g_free (wname); |
574 | | g_free (wvalue); |
575 | | |
576 | | return retval; |
577 | | } |
578 | | |
579 | | void |
580 | | g_unsetenv (const gchar *variable) |
581 | | { |
582 | | wchar_t *wname, *wassignment; |
583 | | gchar *tem; |
584 | | |
585 | | g_return_if_fail (variable != NULL); |
586 | | g_return_if_fail (strchr (variable, '=') == NULL); |
587 | | g_return_if_fail (g_utf8_validate (variable, -1, NULL)); |
588 | | |
589 | | wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL); |
590 | | tem = g_strconcat (variable, "=", NULL); |
591 | | wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL); |
592 | | |
593 | | g_free (tem); |
594 | | _wputenv (wassignment); |
595 | | g_free (wassignment); |
596 | | |
597 | | SetEnvironmentVariableW (wname, NULL); |
598 | | |
599 | | g_free (wname); |
600 | | } |
601 | | |
602 | | gchar ** |
603 | | g_listenv (void) |
604 | | { |
605 | | gchar **result, *eq; |
606 | | gint len = 0, j; |
607 | | wchar_t *p, *q; |
608 | | |
609 | | p = (wchar_t *) GetEnvironmentStringsW (); |
610 | | if (p != NULL) |
611 | | { |
612 | | q = p; |
613 | | while (*q) |
614 | | { |
615 | | q += wcslen (q) + 1; |
616 | | len++; |
617 | | } |
618 | | } |
619 | | result = g_new0 (gchar *, len + 1); |
620 | | |
621 | | j = 0; |
622 | | q = p; |
623 | | while (*q) |
624 | | { |
625 | | result[j] = g_utf16_to_utf8 (q, -1, NULL, NULL, NULL); |
626 | | if (result[j] != NULL) |
627 | | { |
628 | | eq = strchr (result[j], '='); |
629 | | if (eq && eq > result[j]) |
630 | | { |
631 | | *eq = '\0'; |
632 | | j++; |
633 | | } |
634 | | else |
635 | | g_free (result[j]); |
636 | | } |
637 | | q += wcslen (q) + 1; |
638 | | } |
639 | | result[j] = NULL; |
640 | | FreeEnvironmentStringsW (p); |
641 | | |
642 | | return result; |
643 | | } |
644 | | |
645 | | gchar ** |
646 | | g_get_environ (void) |
647 | | { |
648 | | gunichar2 *strings; |
649 | | gchar **result; |
650 | | gint i, n; |
651 | | |
652 | | strings = GetEnvironmentStringsW (); |
653 | | for (n = 0, i = 0; strings[n]; i++) |
654 | | n += wcslen (strings + n) + 1; |
655 | | |
656 | | result = g_new (char *, i + 1); |
657 | | for (n = 0, i = 0; strings[n]; i++) |
658 | | { |
659 | | result[i] = g_utf16_to_utf8 (strings + n, -1, NULL, NULL, NULL); |
660 | | n += wcslen (strings + n) + 1; |
661 | | } |
662 | | FreeEnvironmentStringsW (strings); |
663 | | result[i] = NULL; |
664 | | |
665 | | return result; |
666 | | } |
667 | | |
668 | | #endif /* G_OS_WIN32 */ |
669 | | |
670 | | #ifdef G_OS_WIN32 |
671 | | |
672 | | /* Binary compatibility versions. Not for newly compiled code. */ |
673 | | |
674 | | _GLIB_EXTERN const gchar *g_getenv_utf8 (const gchar *variable); |
675 | | _GLIB_EXTERN gboolean g_setenv_utf8 (const gchar *variable, |
676 | | const gchar *value, |
677 | | gboolean overwrite); |
678 | | _GLIB_EXTERN void g_unsetenv_utf8 (const gchar *variable); |
679 | | |
680 | | const gchar * |
681 | | g_getenv_utf8 (const gchar *variable) |
682 | | { |
683 | | return g_getenv (variable); |
684 | | } |
685 | | |
686 | | gboolean |
687 | | g_setenv_utf8 (const gchar *variable, |
688 | | const gchar *value, |
689 | | gboolean overwrite) |
690 | | { |
691 | | return g_setenv (variable, value, overwrite); |
692 | | } |
693 | | |
694 | | void |
695 | | g_unsetenv_utf8 (const gchar *variable) |
696 | | { |
697 | | g_unsetenv (variable); |
698 | | } |
699 | | |
700 | | #endif |
701 | | |
702 | | /* Epilogue {{{1 */ |
703 | | /* vim: set foldmethod=marker: */ |