From d17291ad67d1a9ae2af9833387e6e5902c0e21c6 Mon Sep 17 00:00:00 2001
From: Ben Boeckel <ben.boeckel@kitware.com>
Date: Thu, 21 Mar 2019 13:11:57 -0400
Subject: [PATCH] DynamicLoader: support loading libraries using flags

---
 DynamicLoader.cxx    | 48 +++++++++++++++++++++++++++++++++++++-------
 DynamicLoader.hxx.in | 10 ++++++++-
 2 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/DynamicLoader.cxx b/DynamicLoader.cxx
index 2dc22c24..fbe92989 100644
--- a/DynamicLoader.cxx
+++ b/DynamicLoader.cxx
@@ -26,6 +26,28 @@
 // Each part of the ifdef contains a complete implementation for
 // the static methods of DynamicLoader.
 
+#define CHECK_OPEN_FLAGS(var, supported, ret)                                 \
+  do {                                                                        \
+    /* Check for unknown flags. */                                            \
+    if ((var & AllOpenFlags) != var) {                                        \
+      return ret;                                                             \
+    }                                                                         \
+                                                                              \
+    /* Check for unsupported flags. */                                        \
+    if ((var & (supported)) != var) {                                         \
+      return ret;                                                             \
+    }                                                                         \
+  } while (0)
+
+namespace KWSYS_NAMESPACE {
+
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
+  const std::string& libname)
+{
+  return DynamicLoader::OpenLibrary(libname, 0);
+}
+}
+
 #if !KWSYS_SUPPORTS_SHARED_LIBS
 // Implementation for environments without dynamic libs
 #  include <string.h> // for strerror()
@@ -33,7 +55,7 @@
 namespace KWSYS_NAMESPACE {
 
 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
-  const std::string& libname)
+  const std::string& libname, int flags)
 {
   return 0;
 }
@@ -68,8 +90,10 @@ const char* DynamicLoader::LastError()
 namespace KWSYS_NAMESPACE {
 
 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
-  const std::string& libname)
+  const std::string& libname, int flags)
 {
+  CHECK_OPEN_FLAGS(flags, 0, 0);
+
   return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L);
 }
 
@@ -131,8 +155,10 @@ const char* DynamicLoader::LastError()
 namespace KWSYS_NAMESPACE {
 
 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
-  const std::string& libname)
+  const std::string& libname, int flags)
 {
+  CHECK_OPEN_FLAGS(flags, 0, 0);
+
   NSObjectFileImageReturnCode rc;
   NSObjectFileImage image = 0;
 
@@ -189,8 +215,10 @@ const char* DynamicLoader::LastError()
 namespace KWSYS_NAMESPACE {
 
 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
-  const std::string& libname)
+  const std::string& libname, int flags)
 {
+  CHECK_OPEN_FLAGS(flags, 0, NULL);
+
   return LoadLibraryW(Encoding::ToWindowsExtendedPath(libname).c_str());
 }
 
@@ -290,8 +318,10 @@ namespace KWSYS_NAMESPACE {
 static image_id last_dynamic_err = B_OK;
 
 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
-  const std::string& libname)
+  const std::string& libname, int flags)
 {
+  CHECK_OPEN_FLAGS(flags, 0, 0);
+
   // image_id's are integers, errors are negative. Add one just in case we
   //  get a valid image_id of zero (is that even possible?).
   image_id rc = load_add_on(libname.c_str());
@@ -368,8 +398,10 @@ const char* DynamicLoader::LastError()
 namespace KWSYS_NAMESPACE {
 
 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
-  const std::string& libname)
+  const std::string& libname, int flags)
 {
+  CHECK_OPEN_FLAGS(flags, 0, NULL);
+
   char* name = (char*)calloc(1, libname.size() + 1);
   dld_init(program_invocation_name);
   strncpy(name, libname.c_str(), libname.size());
@@ -412,8 +444,10 @@ const char* DynamicLoader::LastError()
 namespace KWSYS_NAMESPACE {
 
 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
-  const std::string& libname)
+  const std::string& libname, int flags)
 {
+  CHECK_OPEN_FLAGS(flags, 0, NULL);
+
   return dlopen(libname.c_str(), RTLD_LAZY);
 }
 
diff --git a/DynamicLoader.hxx.in b/DynamicLoader.hxx.in
index 08f2790a..f3674fe5 100644
--- a/DynamicLoader.hxx.in
+++ b/DynamicLoader.hxx.in
@@ -66,10 +66,18 @@ public:
   // Return type from DynamicLoader::GetSymbolAddress.
   typedef void (*SymbolPointer)();
 
+  enum OpenFlags
+  {
+    AllOpenFlags = 0
+  };
+
   /** Load a dynamic library into the current process.
    * The returned LibraryHandle can be used to access the symbols in the
-   * library. */
+   * library. The optional second argument is a set of flags to use when
+   * opening the library. If unrecognized or unsupported flags are specified,
+   * the library is not opened. */
   static LibraryHandle OpenLibrary(const std::string&);
+  static LibraryHandle OpenLibrary(const std::string&, int);
 
   /** Attempt to detach a dynamic library from the
    * process.  A value of true is returned if it is successful. */
-- 
GitLab