From 1b1e23825966d6e8cfe5b07edcd56dfa71a1d972 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Wed, 3 Feb 2016 07:33:56 -0800
Subject: [PATCH] Better dynamic linking

---
 Makefile                     |  2 +-
 src/core/support/env_linux.c | 24 +++++++-----------------
 templates/Makefile.template  |  2 +-
 3 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/Makefile b/Makefile
index f186416186..ba928aebd6 100644
--- a/Makefile
+++ b/Makefile
@@ -340,7 +340,7 @@ endif
 endif
 
 ifeq ($(SYSTEM),Linux)
-LIBS = rt m pthread
+LIBS = dl rt m pthread
 LDFLAGS += -pthread
 endif
 
diff --git a/src/core/support/env_linux.c b/src/core/support/env_linux.c
index b5832a5917..442cd8298e 100644
--- a/src/core/support/env_linux.c
+++ b/src/core/support/env_linux.c
@@ -42,33 +42,23 @@
 
 #include "src/core/support/env.h"
 
+#include <dlfcn.h>
 #include <stdlib.h>
 
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
+#include <grpc/support/useful.h>
 
 #include "src/core/support/string.h"
 
-/* Declare weak symbols for versions of secure_getenv that *may* be
- * on a users machine. Older libc's call this __secure_getenv, even
- * older don't support the functionality.
- *
- * If a symbol is not present, these will be equal to NULL.
- */
-char *__attribute__((weak)) secure_getenv(const char *name);
-char *__attribute__((weak)) __secure_getenv(const char *name);
-
 char *gpr_getenv(const char *name) {
-  static char *(*getenv_func)(const char *) = secure_getenv;
+  typedef char *(*getenv_type)(const char *);
+  static getenv_type getenv_func = NULL;
   /* Check to see which getenv variant is supported (go from most
    * to least secure) */
-  if (getenv_func == NULL) {
-    getenv_func = __secure_getenv;
-    if (getenv_func == NULL) {
-      gpr_log(GPR_DEBUG,
-              "No secure_getenv. Please consider upgrading your libc.");
-      getenv_func = getenv;
-    }
+  const char *names[] = {"secure_getenv", "__secure_getenv", "getenv"};
+  for (size_t i = 0; getenv_func == NULL && i < GPR_ARRAY_SIZE(names); i++) {
+    getenv_func = (getenv_type)dlsym(RTLD_DEFAULT, names[i]);
   }
   char *result = getenv_func(name);
   return result == NULL ? result : gpr_strdup(result);
diff --git a/templates/Makefile.template b/templates/Makefile.template
index a3d3780449..dee6761fcc 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -253,7 +253,7 @@
   endif
 
   ifeq ($(SYSTEM),Linux)
-  LIBS = rt m pthread
+  LIBS = dl rt m pthread
   LDFLAGS += -pthread
   endif
 
-- 
GitLab