mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-29 19:30:36 +02:00
Warn about mutation of ‘environ’ when multi-threaded.
This is an amendment to 84bf840322
.
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.
* NEWS: Update.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
parent
b8031fc965
commit
7b7340b2d9
2 changed files with 21 additions and 12 deletions
2
NEWS
2
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)
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue