[tor-commits] [tor/master] Use _NSGetEnviron() instead of environ where required

nickm at torproject.org nickm at torproject.org
Tue Feb 14 16:15:30 UTC 2012


commit efb7b9dec135594718b765234bc1f745855f60d2
Author: Sebastian Hahn <sebastian at torproject.org>
Date:   Tue Feb 14 12:21:03 2012 +0100

    Use _NSGetEnviron() instead of environ where required
    
    OS X would otherwise crash with a segfault when linked statically to
    some libraries.
---
 configure.in        |    2 ++
 src/common/compat.c |   23 +++++++++++++++++++++++
 src/common/compat.h |    2 ++
 src/or/transports.c |    7 +++----
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/configure.in b/configure.in
index b39d156..7b6d8fb 100644
--- a/configure.in
+++ b/configure.in
@@ -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 \
diff --git a/src/common/compat.c b/src/common/compat.c
index 64c0668..f25a8ac 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -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.)
diff --git a/src/common/compat.h b/src/common/compat.h
index fa1ef90..65e6cb4 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -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;
 
diff --git a/src/or/transports.c b/src/or/transports.c
index d279d7a..6d9b352 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -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));



More information about the tor-commits mailing list