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