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