Bug 1869043 allow a device to be specified with MediaTrackGraph::NotifyWhenDeviceStar...
[gecko.git] / mozglue / interposers / env_interposer.cpp
blobd8c11b5d354c69416829fc6d074b4aa06f7c895a
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include <pthread.h>
6 #include <string.h>
7 #include <unistd.h>
9 #include "InterposerHelper.h"
11 // The interposers in this file cover all the functions used to access the
12 // environment (getenv(), putenv(), setenv(), unsetenv() and clearenv()). They
13 // all use the mutex below for synchronization to prevent races that caused
14 // startup crashes, see bug 1752703.
15 static pthread_mutex_t gEnvLock = PTHREAD_MUTEX_INITIALIZER;
17 static char* internal_getenv(const char* aName) {
18 if (environ == nullptr || aName[0] == '\0') {
19 return nullptr;
22 size_t len = strlen(aName);
23 for (char** env_ptr = environ; *env_ptr != nullptr; ++env_ptr) {
24 if ((aName[0] == (*env_ptr)[0]) && (strncmp(aName, *env_ptr, len) == 0) &&
25 ((*env_ptr)[len] == '=')) {
26 return *env_ptr + len + 1;
30 return nullptr;
33 extern "C" {
35 MFBT_API char* getenv(const char* name) {
36 pthread_mutex_lock(&gEnvLock);
37 char* result = internal_getenv(name);
38 pthread_mutex_unlock(&gEnvLock);
40 return result;
43 MFBT_API int putenv(char* string) {
44 static const auto real_putenv = GET_REAL_SYMBOL(putenv);
46 pthread_mutex_lock(&gEnvLock);
47 int result = real_putenv(string);
48 pthread_mutex_unlock(&gEnvLock);
49 return result;
52 MFBT_API int setenv(const char* name, const char* value, int replace) {
53 static const auto real_setenv = GET_REAL_SYMBOL(setenv);
55 pthread_mutex_lock(&gEnvLock);
56 int result = real_setenv(name, value, replace);
57 pthread_mutex_unlock(&gEnvLock);
58 return result;
61 MFBT_API int unsetenv(const char* name) {
62 static const auto real_unsetenv = GET_REAL_SYMBOL(unsetenv);
64 pthread_mutex_lock(&gEnvLock);
65 int result = real_unsetenv(name);
66 pthread_mutex_unlock(&gEnvLock);
67 return result;
70 MFBT_API int clearenv(void) {
71 static const auto real_clearenv = GET_REAL_SYMBOL(clearenv);
73 pthread_mutex_lock(&gEnvLock);
74 int result = real_clearenv();
75 pthread_mutex_unlock(&gEnvLock);
76 return result;
79 } // extern "C"