diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 15847a79ae49..9df510b85bd2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -130,6 +130,7 @@ void DisableCoreDumper(); void DumpProcessMap(); bool FileExists(const char *filename); const char *GetEnv(const char *name); +bool SetEnv(const char *name, const char *value); const char *GetPwd(); u32 GetUid(); void ReExec(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc index cd651935b68d..ef185571ada1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc @@ -264,6 +264,20 @@ const char *GetEnv(const char *name) { return 0; // Not found. } +// Does not compile for Go because dlsym() requires -ldl +#ifndef SANITIZER_GO +bool SetEnv(const char *name, const char *value) { + void *f = dlsym(RTLD_NEXT, "setenv"); + if (f == 0) + return false; + typedef int(*setenv_ft)(const char *name, const char *value, int overwrite); + setenv_ft setenv_f; + CHECK_EQ(sizeof(setenv_f), sizeof(f)); + internal_memcpy(&setenv_f, &f, sizeof(f)); + return setenv_f(name, value, 1) == 0; +} +#endif + #ifdef __GLIBC__ extern "C" { diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc index 035c11fa4622..0560fb57b7c4 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -185,6 +186,14 @@ TEST_F(ThreadListerTest, ResetMakesNewThreadsKnown) { ASSERT_TRUE(HasElement(threads_after_extra, extra_tid)); } +TEST(SanitizerCommon, SetEnvTest) { + const char kEnvName[] = "ENV_FOO"; + SetEnv(kEnvName, "value"); + EXPECT_STREQ("value", getenv(kEnvName)); + unsetenv(kEnvName); + EXPECT_EQ(0, getenv(kEnvName)); +} + } // namespace __sanitizer #endif // __linux__