diff options
author | Sebastian Wilhelmi <wilhelmi@ira.uka.de> | 2000-04-19 08:43:52 +0000 |
---|---|---|
committer | Sebastian Wilhelmi <wilhelmi@src.gnome.org> | 2000-04-19 08:43:52 +0000 |
commit | e366512775000ce20eed18ead840de45271c2662 (patch) | |
tree | 212378b95f7844b70579ad61ee904f2d3ac3b034 /glib | |
parent | 70ce489b36056f0a3a8283ca7477577662c8bd53 (diff) | |
download | glib-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.h | 2 | ||||
-rw-r--r-- | glib/gutils.c | 77 |
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 } |