diff --git a/NEWS b/NEWS index ff4c977de..e7641c008 100644 --- a/NEWS +++ b/NEWS @@ -86,6 +86,8 @@ every line in a file. in turn, would trigger warnings from 'primitive-fork' and 'environ' suggesting they are being called in a multi-threaded context, when in fact user code did not create any thread. +** Calling 'environ' without arguments in a multi-threaded program is OK + This used to trigger a warning, unduly. Changes in 3.0.10 (since 3.0.9) diff --git a/libguile/posix.c b/libguile/posix.c index 61b5523af..dde77b8ee 100644 --- a/libguile/posix.c +++ b/libguile/posix.c @@ -1705,6 +1705,19 @@ 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 +1729,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 +1955,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. */