Use _NSGetEnviron() instead of environ where required

OS X would otherwise crash with a segfault when linked statically to
some libraries.
This commit is contained in:
Sebastian Hahn 2012-02-14 12:21:03 +01:00 committed by Nick Mathewson
parent efcdc930fb
commit efb7b9dec1
4 changed files with 30 additions and 4 deletions

View File

@ -292,6 +292,7 @@ dnl Check for functions before libevent, since libevent-1.2 apparently
dnl exports strlcpy without defining it in a header.
AC_CHECK_FUNCS(
_NSGetEnviron \
accept4 \
clock_gettime \
flock \
@ -622,6 +623,7 @@ dnl These headers are not essential
AC_CHECK_HEADERS(
arpa/inet.h \
crt_externs.h \
grp.h \
ifaddrs.h \
inttypes.h \

View File

@ -51,6 +51,9 @@
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_CRT_EXTERNS_H
#include <crt_externs.h>
#endif
#ifndef HAVE_GETTIMEOFDAY
#ifdef HAVE_FTIME
@ -1659,6 +1662,26 @@ make_path_absolute(char *fname)
#endif
}
#ifndef HAVE__NSGETENVIRON
/* FreeBSD needs this; it doesn't seem to hurt other platforms. */
extern char **environ;
#endif
/** Return the current environment. This is a portable replacement for
* 'environ'. */
char **
get_environment(void)
{
#ifdef HAVE__NSGETENVIRON
/* This is for compatibility between OSX versions. Otherwise (for example)
* when we do a mostly-static build on OSX 10.7, the resulting binary won't
* work on OSX 10.6. */
return *_NSGetEnviron();
#else
return environ;
#endif
}
/** Set *addr to the IP address (in dotted-quad notation) stored in c.
* Return 1 on success, 0 if c is badly formatted. (Like inet_aton(c,addr),
* but works on Windows and Solaris.)

View File

@ -581,6 +581,8 @@ char *get_user_homedir(const char *username);
int get_parent_directory(char *fname);
char *make_path_absolute(char *fname);
char **get_environment(void);
int spawn_func(void (*func)(void *), void *data);
void spawn_exit(void) ATTR_NORETURN;

View File

@ -1076,8 +1076,6 @@ set_managed_proxy_environment(LPVOID *envp, const managed_proxy_t *mp)
#else /* _WIN32 */
extern char **environ;
/** Prepare the environment <b>envp</b> of managed proxy <b>mp</b>.
* <b>envp</b> is allocated on the heap and should be freed by the
* caller after its use. */
@ -1090,7 +1088,8 @@ set_managed_proxy_environment(char ***envp, const managed_proxy_t *mp)
char *transports_to_launch=NULL;
char *bindaddr=NULL;
int environ_size=0;
char **environ_tmp = environ;
char **environ_tmp = get_environment();
char **environ_save = environ_tmp;
int n_envs = mp->is_server ? ENVIRON_SIZE_SERVER : ENVIRON_SIZE_CLIENT;
@ -1098,7 +1097,7 @@ set_managed_proxy_environment(char ***envp, const managed_proxy_t *mp)
environ_size++;
environ_tmp++;
}
environ_tmp = environ;
environ_tmp = environ_save;
/* allocate enough space for our env. vars and a NULL pointer */
*envp = tor_malloc(sizeof(char*)*(environ_size+n_envs+1));