From: Olivier Dion <olivier.d...@polymtl.ca>

This is an amendment to 84bf84032208e21d20ad13f3033d4fca3a512014.

The warning was only emitted for calling `environ', even if only reading
and no mutation occurred.

However, it is correct  to read the environment in a
multi-threaded process.  It is however unsafe to mutate it.

The same logic also applies to `putenv'.

* libguile/posix.c
  (maybe_warn_about_environ_mutation): New private procedure ...
  (scm_environ): ... called here when mutating the environment ...
  (scm_putenv): ... and here.

Signed-off-by: Olivier Dion <olivier.d...@polymtl.ca>
---
 libguile/posix.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index 61b5523af..d111b8942 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1705,6 +1705,18 @@ SCM_DEFINE (scm_uname, "uname", 0, 0, 0,
 #undef FUNC_NAME
 #endif /* HAVE_UNAME */
 
+static void maybe_warn_about_environ_mutation (void)
+{
+  /* Mutating `environ' directly in a multi-threaded program is
+     undefined behavior.  */
+  if (scm_ilength (scm_all_threads ()) != 1)
+    scm_display
+      (scm_from_latin1_string
+       ("warning: mutating the process environment while multiple threads are 
running;\n"
+        "         further behavior unspecified.\n"),
+       scm_current_warning_port ());
+}
+
 SCM_DEFINE (scm_environ, "environ", 0, 1, 0, 
             (SCM env),
            "If @var{env} is omitted, return the current environment (in the\n"
@@ -1716,22 +1728,13 @@ SCM_DEFINE (scm_environ, "environ", 0, 1, 0,
            "then the return value is unspecified.")
 #define FUNC_NAME s_scm_environ
 {
-  /* Accessing `environ' directly in a multi-threaded program is
-     undefined behavior since at anytime it could point to anything else
-     while reading it.  Not only that, but all accesses are protected by
-     an internal mutex of libc.  Thus, it is only truly safe to modify
-     the environment directly in a single-threaded program.  */
-  if (scm_ilength (scm_all_threads ()) != 1)
-    scm_display
-      (scm_from_latin1_string
-       ("warning: call to environ while multiple threads are running;\n"
-        "         further behavior unspecified.\n"),
-       scm_current_warning_port ());
-
   if (SCM_UNBNDP (env))
     return scm_makfromstrs (-1, environ);
   else
     {
+      /* Mutating the environment in a multi-threaded program is hazardous. */
+      maybe_warn_about_environ_mutation();
+
       /* Arrange to not use GC-allocated storage for what goes into
          'environ' as libc might reallocate it behind our back.  */
 #if HAVE_CLEARENV
@@ -1951,6 +1954,9 @@ SCM_DEFINE (scm_putenv, "putenv", 1, 0, 0,
   int rv;
   char *c_str = scm_to_locale_string (str);
 
+  /* Mutating the environment in a multi-threaded program is hazardous. */
+  maybe_warn_about_environ_mutation();
+
   /* Leave C_STR in the environment.  */
 
   /* Gnulib's `putenv' module honors the semantics described above.  */
-- 
2.48.1


Reply via email to