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