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