Changed the win32 part of this function to be thread safe and to make the
authorSebastian Wilhelmi <wilhelmi@ira.uka.de>
Wed, 19 Apr 2000 08:43:52 +0000 (08:43 +0000)
committerSebastian Wilhelmi <wilhelmi@src.gnome.org>
Wed, 19 Apr 2000 08:43:52 +0000 (08:43 +0000)
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.

12 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
glib.h
glib/glib.h
glib/gutils.c
gutils.c

index e3dfb8b..bfb2bed 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+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.
+
 Wed Apr 19 08:32:32 2000  Tim Janik  <timj@gtk.org>
 
         * gscanner.c (g_scanner_new): make sure that
index e3dfb8b..bfb2bed 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
 Wed Apr 19 08:32:32 2000  Tim Janik  <timj@gtk.org>
 
         * gscanner.c (g_scanner_new): make sure that
index e3dfb8b..bfb2bed 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
 Wed Apr 19 08:32:32 2000  Tim Janik  <timj@gtk.org>
 
         * gscanner.c (g_scanner_new): make sure that
index e3dfb8b..bfb2bed 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
 Wed Apr 19 08:32:32 2000  Tim Janik  <timj@gtk.org>
 
         * gscanner.c (g_scanner_new): make sure that
index e3dfb8b..bfb2bed 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
 Wed Apr 19 08:32:32 2000  Tim Janik  <timj@gtk.org>
 
         * gscanner.c (g_scanner_new): make sure that
index e3dfb8b..bfb2bed 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
 Wed Apr 19 08:32:32 2000  Tim Janik  <timj@gtk.org>
 
         * gscanner.c (g_scanner_new): make sure that
index e3dfb8b..bfb2bed 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
 Wed Apr 19 08:32:32 2000  Tim Janik  <timj@gtk.org>
 
         * gscanner.c (g_scanner_new): make sure that
index e3dfb8b..bfb2bed 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
 Wed Apr 19 08:32:32 2000  Tim Janik  <timj@gtk.org>
 
         * gscanner.c (g_scanner_new): make sure that
diff --git a/glib.h b/glib.h
index a371ec0..6c13c11 100644 (file)
--- a/glib.h
+++ b/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)          \
index a371ec0..6c13c11 100644 (file)
@@ -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)          \
index 30c3bb7..7e99bb0 100644 (file)
@@ -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
 }
 
index 30c3bb7..7e99bb0 100644 (file)
--- a/gutils.c
+++ b/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
 }