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/. */
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') {
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;
35 MFBT_API
char* getenv(const char* name
) {
36 pthread_mutex_lock(&gEnvLock
);
37 char* result
= internal_getenv(name
);
38 pthread_mutex_unlock(&gEnvLock
);
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
);
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
);
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
);
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
);