summaryrefslogtreecommitdiff
path: root/glib
diff options
context:
space:
mode:
authorSebastian Wilhelmi <wilhelmi@ira.uka.de>2000-04-19 08:43:52 +0000
committerSebastian Wilhelmi <wilhelmi@src.gnome.org>2000-04-19 08:43:52 +0000
commite366512775000ce20eed18ead840de45271c2662 (patch)
tree212378b95f7844b70579ad61ee904f2d3ac3b034 /glib
parent70ce489b36056f0a3a8283ca7477577662c8bd53 (diff)
downloadglib-e366512775000ce20eed18ead840de45271c2662.tar.gz
Changed the win32 part of this function to be thread safe and to make the
2000-04-19 Sebastian Wilhelmi <wilhelmi@ira.uka.de> * gutils.c (g_getenv): Changed the win32 part of this function to be thread safe and to make the returned environment string persistent to match the UN*X behavior. This is again a response to Bug #8983. * glib.h (G_LOCK_NAME): Removed parentheses around the lock name, as that seems to cause problems for some compilers and really isn't necessary.
Diffstat (limited to 'glib')
-rw-r--r--glib/glib.h2
-rw-r--r--glib/gutils.c77
2 files changed, 56 insertions, 23 deletions
diff --git a/glib/glib.h b/glib/glib.h
index a371ec061..6c13c11b2 100644
--- a/glib/glib.h
+++ b/glib/glib.h
@@ -3130,7 +3130,7 @@ void g_static_rw_lock_free (GStaticRWLock* lock);
* G_TRYLOCK() respectively.
*/
extern void glib_dummy_decl (void);
-#define G_LOCK_NAME(name) (g__ ## name ## _lock)
+#define G_LOCK_NAME(name) g__ ## name ## _lock
#ifdef G_THREADS_ENABLED
# define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
# define G_LOCK_DEFINE(name) \
diff --git a/glib/gutils.c b/glib/gutils.c
index 30c3bb755..7e99bb0b6 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -379,38 +379,71 @@ g_getenv (const gchar *variable)
return getenv (variable);
#else
- gchar *v;
- guint k;
- static gchar *p = NULL;
- static gint l;
+ G_LOCK_DEFINE_STATIC (getenv);
+ struct env_struct
+ {
+ gchar *key;
+ gchar *value;
+ } *env;
+ static GArray *environs = NULL;
+ gchar *system_env;
+ guint length, i;
gchar dummy[2];
g_return_val_if_fail (variable != NULL, NULL);
- v = getenv (variable);
- if (!v)
- return NULL;
-
- /* On Windows NT, it is relatively typical that environment variables
- * contain references to other environment variables. Handle that by
- * calling ExpandEnvironmentStrings.
+ G_LOCK (getenv);
+
+ if (!environs)
+ environs = g_array_new (FALSE, FALSE, sizeof (struct env_struct));
+
+ /* First we try to find the envinronment variable inside the already
+ * found ones.
*/
- /* First check how much space we need */
- k = ExpandEnvironmentStrings (v, dummy, 2);
- /* Then allocate that much, and actualy do the expansion */
- if (p == NULL)
+ for (i = 0; i < environs->len; i++)
{
- p = g_malloc (k);
- l = k;
+ env = &g_array_index (environs, struct env_struct, i);
+ if (strcmp (env->key, variable) == 0)
+ {
+ g_assert (env->value);
+ G_UNLOCK (getenv);
+ return env->value;
+ }
}
- else if (k > l)
+
+ /* If not found, we ask the system */
+
+ system_env = getenv (variable);
+ if (!system_env)
{
- p = g_realloc (p, k);
- l = k;
+ G_UNLOCK (getenv);
+ return NULL;
}
- ExpandEnvironmentStrings (v, p, k);
- return p;
+
+ /* On Windows NT, it is relatively typical that environment variables
+ * contain references to other environment variables. Handle that by
+ * calling ExpandEnvironmentStrings.
+ */
+
+ g_array_set_size (environs, environs->len + 1);
+
+ env = &g_array_index (environs, struct env_struct, environs->len - 1);
+
+ /* First check how much space we need */
+ length = ExpandEnvironmentStrings (system_env, dummy, 2);
+
+ /* Then allocate that much, and actualy do the expansion and insert
+ * the new found pair into our buffer
+ */
+
+ env->value = g_malloc (length);
+ env->key = g_strdup (variable);
+
+ ExpandEnvironmentStrings (system_env, env->value, length);
+
+ G_UNLOCK (getenv);
+ return env->value;
#endif
}