diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
commit | 9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /mozglue/interposers/env_interposer.cpp | |
parent | Initial commit. (diff) | |
download | thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.tar.xz thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | mozglue/interposers/env_interposer.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/mozglue/interposers/env_interposer.cpp b/mozglue/interposers/env_interposer.cpp new file mode 100644 index 0000000000..d8c11b5d35 --- /dev/null +++ b/mozglue/interposers/env_interposer.cpp @@ -0,0 +1,79 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <pthread.h> +#include <string.h> +#include <unistd.h> + +#include "InterposerHelper.h" + +// The interposers in this file cover all the functions used to access the +// environment (getenv(), putenv(), setenv(), unsetenv() and clearenv()). They +// all use the mutex below for synchronization to prevent races that caused +// startup crashes, see bug 1752703. +static pthread_mutex_t gEnvLock = PTHREAD_MUTEX_INITIALIZER; + +static char* internal_getenv(const char* aName) { + if (environ == nullptr || aName[0] == '\0') { + return nullptr; + } + + size_t len = strlen(aName); + for (char** env_ptr = environ; *env_ptr != nullptr; ++env_ptr) { + if ((aName[0] == (*env_ptr)[0]) && (strncmp(aName, *env_ptr, len) == 0) && + ((*env_ptr)[len] == '=')) { + return *env_ptr + len + 1; + } + } + + return nullptr; +} + +extern "C" { + +MFBT_API char* getenv(const char* name) { + pthread_mutex_lock(&gEnvLock); + char* result = internal_getenv(name); + pthread_mutex_unlock(&gEnvLock); + + return result; +} + +MFBT_API int putenv(char* string) { + static const auto real_putenv = GET_REAL_SYMBOL(putenv); + + pthread_mutex_lock(&gEnvLock); + int result = real_putenv(string); + pthread_mutex_unlock(&gEnvLock); + return result; +} + +MFBT_API int setenv(const char* name, const char* value, int replace) { + static const auto real_setenv = GET_REAL_SYMBOL(setenv); + + pthread_mutex_lock(&gEnvLock); + int result = real_setenv(name, value, replace); + pthread_mutex_unlock(&gEnvLock); + return result; +} + +MFBT_API int unsetenv(const char* name) { + static const auto real_unsetenv = GET_REAL_SYMBOL(unsetenv); + + pthread_mutex_lock(&gEnvLock); + int result = real_unsetenv(name); + pthread_mutex_unlock(&gEnvLock); + return result; +} + +MFBT_API int clearenv(void) { + static const auto real_clearenv = GET_REAL_SYMBOL(clearenv); + + pthread_mutex_lock(&gEnvLock); + int result = real_clearenv(); + pthread_mutex_unlock(&gEnvLock); + return result; +} + +} // extern "C" |