diff options
author | Karl Williamson <khw@cpan.org> | 2020-03-06 14:18:45 -0700 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2020-03-11 09:52:12 -0600 |
commit | 24f3e849b5ce9f3bf6b6be5d3e730562e927aa79 (patch) | |
tree | 2aeee9a5124aea2f9617971dc2f3421fd8a0e858 /iperlsys.h | |
parent | 2bc5f86adf5f1c0feb76d83e1a627e5649e6beab (diff) | |
download | perl-24f3e849b5ce9f3bf6b6be5d3e730562e927aa79.tar.gz |
Add thread safety to some environment accesses
The previous commit added a mutex specifically for protecting against
simultaneous accesses of the environment. This commit changes the
normal getenv, putenv, and clearenv functions to use it, to avoid races.
This makes the code simpler in places where we've gotten burned and
added stuff to avoid races. Other places where we haven't known we were
getting burned could have existed until now. Now that comes
automatically, and we can remove the special cases we earlier stumbled
over.
getenv() returns a pointer to static memory, which can be overwritten at
any moment from another thread, or even another getenv from the same
thread. This commit changes the accesses to be under control of a
mutex, and in the case of getenv, a mortalized copy is created so that
there is no possible race.
Diffstat (limited to 'iperlsys.h')
-rw-r--r-- | iperlsys.h | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/iperlsys.h b/iperlsys.h index d4ecb734a6..8cdc8ce797 100644 --- a/iperlsys.h +++ b/iperlsys.h @@ -562,10 +562,18 @@ struct IPerlEnvInfo (*PL_Env->pGetChildIO)(PL_Env, ptr) #endif -#else /* PERL_IMPLICIT_SYS */ - -#define PerlEnv_putenv(str) putenv((str)) -#define PerlEnv_getenv(str) getenv((str)) +#else /* below is ! PERL_IMPLICIT_SYS */ +# ifdef USE_ITHREADS + + /* Use the comma operator to return 0/non-zero, while avoiding putting + * this in an inline function */ +# define PerlEnv_putenv(str) (ENV_LOCK, (putenv(str) \ + ? (ENV_UNLOCK, 1) \ + : (ENV_UNLOCK, 0))) +# else +# define PerlEnv_putenv(str) putenv(str) +# endif +#define PerlEnv_getenv(str) mortal_getenv(str) #define PerlEnv_getenv_len(str,l) getenv_len((str), (l)) #ifdef HAS_ENVGETENV # define PerlEnv_ENVgetenv(str) ENVgetenv((str)) @@ -588,7 +596,9 @@ struct IPerlEnvInfo #define PerlEnv_get_childdir() win32_get_childdir() #define PerlEnv_free_childdir(d) win32_free_childdir((d)) #else -#define PerlEnv_clearenv() clearenv() +#define PerlEnv_clearenv(str) (ENV_LOCK, (clearenv(str) \ + ? (ENV_UNLOCK, 1) \ + : (ENV_UNLOCK, 0))) #define PerlEnv_get_childenv() get_childenv() #define PerlEnv_free_childenv(e) free_childenv((e)) #define PerlEnv_get_childdir() get_childdir() |