#include <fcntl.h>
struct owned_ptr;
-__private_extern__ char *__findenv(const char *, int *, char **);
-__private_extern__ int __setenv(const char *, const char *, int, int, char ***, struct owned_ptr *);
-__private_extern__ void __unsetenv(const char *, char **, struct owned_ptr *);
+extern char *__findenv_locked(const char *, int *, char **);
+extern int __setenv_locked(const char *, const char *, int, int, char ***, struct owned_ptr *);
+extern void __unsetenv_locked(const char *, char **, struct owned_ptr *);
-__private_extern__ struct owned_ptr *__env_owned;
-__private_extern__ int __init__env_owned(int);
+extern void __environ_lock(void);
+extern void __environ_unlock(void);
+
+extern struct owned_ptr *__env_owned;
+extern int __init__env_owned_locked(int);
/*
* _cthread_init_routine used to be called from crt1.o to initialize threads.
* Initialize the process's __env_owned structure
*/
__private_extern__ int
-__init__env_owned(int should_set_errno)
+__init__env_owned_locked(int should_set_errno)
{
int save;
* -1 - like 0, except we copy of the name=value string in name
*/
__private_extern__ int
-__setenv(name, value, rewrite, copy, environp, owned)
+__setenv_locked(name, value, rewrite, copy, environp, owned)
const char *name;
const char *value;
int rewrite, copy;
int offset;
int oindex;
- if ((c = __findenv(name, &offset, *environp))) { /* find if already exists */
+ if ((c = __findenv_locked(name, &offset, *environp))) { /* find if already exists */
char *e;
if (!rewrite)
return (0);
}
__private_extern__ void
-__unsetenv(const char *name, char **environ, struct owned_ptr *owned)
+__unsetenv_locked(const char *name, char **environ, struct owned_ptr *owned)
{
char **p;
int offset;
int oindex;
- while (__findenv(name, &offset, environ)) { /* if set multiple times */
+ while (__findenv_locked(name, &offset, environ)) { /* if set multiple times */
/* if we malloc-ed it, free it first */
if (_owned_ptr_search(owned, environ[offset], &oindex) == 0) {
_owned_ptr_delete(owned, oindex);
* _copyenv -- SPI that copies a NULL-tereminated char * array in a newly
* allocated buffer, compatible with the other SPI env routines. If env
* is NULL, a char * array composed of a single NULL is returned. NULL
- * is returned on error. (This isn't needed anymore, as __setenv will
+ * is returned on error. (This isn't needed anymore, as __setenv_locked will
* automatically make a copy.)
*/
char **
int
_setenvp(const char *name, const char *value, int rewrite, char ***envp, void *state)
{
- if (__init__env_owned(1)) return (-1);
- return (__setenv(name, value, rewrite, 1, envp, (state ? (struct owned_ptr *)state : __env_owned)));
+ __environ_lock();
+ if (__init__env_owned_locked(1)) {
+ __environ_unlock();
+ return (-1);
+ }
+ int ret = __setenv_locked(name, value, rewrite, 1, envp,
+ (state ? (struct owned_ptr *)state : __env_owned));
+ __environ_unlock();
+ return ret;
}
/*
int
_unsetenvp(const char *name, char ***envp, void *state)
{
- if (__init__env_owned(1)) return (-1);
- __unsetenv(name, *envp, (state ? (struct owned_ptr *)state : __env_owned));
+ __environ_lock();
+ if (__init__env_owned_locked(1)) {
+ __environ_unlock();
+ return (-1);
+ }
+ __unsetenv_locked(name, *envp, (state ? (struct owned_ptr *)state : __env_owned));
+ __environ_unlock();
return 0;
}
const char *value;
int rewrite;
{
-#ifdef LEGACY_CRT1_ENVIRON
int ret;
-#endif /* LEGACY_CRT1_ENVIRON */
/* no null ptr or empty str */
if(name == NULL || *name == 0) {
}
#endif /* __DARWIN_UNIX03 */
- if (*value == '=') /* no `=' in value */
- ++value;
- if (__init__env_owned(1)) return (-1);
+ __environ_lock();
+ if (__init__env_owned_locked(1)) {
+ __environ_unlock();
+ return (-1);
+ }
+ ret = __setenv_locked(name, value, rewrite, 1, _NSGetEnviron(), __env_owned);
#ifdef LEGACY_CRT1_ENVIRON
- ret = __setenv(name, value, rewrite, 1, _NSGetEnviron(), __env_owned);
_saved_environ = *_NSGetEnviron();
- return ret;
-#else /* !LEGACY_CRT1_ENVIRON */
- return (__setenv(name, value, rewrite, 1, _NSGetEnviron(), __env_owned));
#endif /* !LEGACY_CRT1_ENVIRON */
+ __environ_unlock();
+
+ return ret;
+}
+
+static inline __attribute__((always_inline)) int
+_unsetenv(const char *name, int should_set_errno)
+{
+ __environ_lock();
+ if (__init__env_owned_locked(should_set_errno)) {
+ __environ_unlock();
+ return (-1);
+ }
+ __unsetenv_locked(name, *_NSGetEnviron(), __env_owned);
+ __environ_unlock();
+ return 0;
}
/*
*/
#if __DARWIN_UNIX03
int
-#else /* !__DARWIN_UNIX03 */
-void
-#endif /* __DARWIN_UNIX03 */
-unsetenv(name)
- const char *name;
+unsetenv(const char *name)
{
-#if __DARWIN_UNIX03
/* no null ptr or empty str */
if(name == NULL || *name == 0) {
errno = EINVAL;
errno = EINVAL;
return (-1);
}
- if (__init__env_owned(1)) return (-1);
+ return _unsetenv(name, 1);
+}
#else /* !__DARWIN_UNIX03 */
+void
+unsetenv(const char *name)
+{
/* no null ptr or empty str */
if(name == NULL || *name == 0)
return;
- if (__init__env_owned(0)) return;
-#endif /* __DARWIN_UNIX03 */
- __unsetenv(name, *_NSGetEnviron(), __env_owned);
-#if __DARWIN_UNIX03
- return 0;
-#endif /* __DARWIN_UNIX03 */
+ _unsetenv(name, 0);
}
+#endif /* __DARWIN_UNIX03 */