Prechádzať zdrojové kódy

More reliable and hopefully less crashy way of determining libp3dtool location

rdb 11 rokov pred
rodič
commit
f68e8cdee4
1 zmenil súbory, kde vykonal 31 pridanie a 11 odobranie
  1. 31 11
      dtool/src/dtoolutil/executionEnvironment.cxx

+ 31 - 11
dtool/src/dtoolutil/executionEnvironment.cxx

@@ -55,15 +55,17 @@
 #ifdef IS_FREEBSD
 #ifdef IS_FREEBSD
 extern char **environ;
 extern char **environ;
 
 
-// For Link_map and dlinfo.
-#include <link.h>
-#include <dlfcn.h>
-
 // This is for sysctl.
 // This is for sysctl.
 #include <sys/types.h>
 #include <sys/types.h>
 #include <sys/sysctl.h>
 #include <sys/sysctl.h>
 #endif
 #endif
 
 
+#if defined(IS_LINUX) || defined(IS_OSX)
+// For link_map and dlinfo.
+#include <link.h>
+#include <dlfcn.h>
+#endif
+
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
 #include "Python.h"
 #include "Python.h"
 #endif
 #endif
@@ -507,7 +509,7 @@ ns_get_binary_name() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ExecutionEnvironment::ns_get_dtool_name
 //     Function: ExecutionEnvironment::ns_get_dtool_name
 //       Access: Private
 //       Access: Private
-//  Description: Returns the name of the libdtool DLL that
+//  Description: Returns the name of the libp3dtool DLL that
 //               is used in this program, if it can be determined.  The
 //               is used in this program, if it can be determined.  The
 //               nonstatic implementation.
 //               nonstatic implementation.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -646,14 +648,34 @@ read_args() {
       const char *buffer = _dyld_get_image_name(i);
       const char *buffer = _dyld_get_image_name(i);
       const char *tail = strrchr(buffer, '/');
       const char *tail = strrchr(buffer, '/');
       if (tail && (strcmp(tail, "/libp3dtool." PANDA_ABI_VERSION_STR ".dylib") == 0
       if (tail && (strcmp(tail, "/libp3dtool." PANDA_ABI_VERSION_STR ".dylib") == 0
-                || strcmp(tail, "/libp3dtool.dylib") == 0
-                || strcmp(tail, "/libdtool.dylib") == 0)) {
+                || strcmp(tail, "/libp3dtool.dylib") == 0)) {
         _dtool_name = buffer;
         _dtool_name = buffer;
       }
       }
     }
     }
   }
   }
 #endif
 #endif
 
 
+#if defined(IS_FREEBSD) || defined(IS_LINUX)
+  // FreeBSD and Linux have a function to get the origin of a loaded library.
+
+  char origin[PATH_MAX + 1];
+
+  if (_dtool_name.empty()) {
+    void *dtool_handle = dlopen("libp3dtool.so." PANDA_ABI_VERSION_STR, RTLD_NOW | RTLD_NOLOAD);
+    if (dtool_handle != NULL && dlinfo(dtool_handle, RTLD_DI_ORIGIN, origin) != -1) {
+      _dtool_name = origin;
+      _dtool_name += "/libp3dtool.so." PANDA_ABI_VERSION_STR;
+    } else {
+      // Try the version of libp3dtool.so without ABI suffix.
+      dtool_handle = dlopen("libp3dtool.so", RTLD_NOW | RTLD_NOLOAD);
+      if (dtool_handle != NULL && dlinfo(dtool_handle, RTLD_DI_ORIGIN, origin) != -1) {
+        _dtool_name = origin;
+        _dtool_name += "/libp3dtool.so";
+      }
+    }
+  }
+#endif
+
 #if defined(IS_FREEBSD)
 #if defined(IS_FREEBSD)
   // On FreeBSD, we can use dlinfo to get the linked libraries.
   // On FreeBSD, we can use dlinfo to get the linked libraries.
 
 
@@ -665,8 +687,7 @@ read_args() {
       char *tail = strrchr(map->l_name, '/');
       char *tail = strrchr(map->l_name, '/');
       char *head = strchr(map->l_name, '/');
       char *head = strchr(map->l_name, '/');
       if (tail && head && (strcmp(tail, "/libp3dtool.so." PANDA_ABI_VERSION_STR) == 0
       if (tail && head && (strcmp(tail, "/libp3dtool.so." PANDA_ABI_VERSION_STR) == 0
-                        || strcmp(tail, "/libp3dtool.so") == 0
-                        || strcmp(tail, "/libdtool.so") == 0)) {
+                        || strcmp(tail, "/libp3dtool.so") == 0)) {
         _dtool_name = head;
         _dtool_name = head;
       }
       }
       map = map->l_next;
       map = map->l_next;
@@ -690,8 +711,7 @@ read_args() {
       char *tail = strrchr(buffer, '/');
       char *tail = strrchr(buffer, '/');
       char *head = strchr(buffer, '/');
       char *head = strchr(buffer, '/');
       if (tail && head && (strcmp(tail, "/libp3dtool.so." PANDA_ABI_VERSION_STR) == 0
       if (tail && head && (strcmp(tail, "/libp3dtool.so." PANDA_ABI_VERSION_STR) == 0
-                        || strcmp(tail, "/libp3dtool.so") == 0
-                        || strcmp(tail, "/libdtool.so") == 0)) {
+                        || strcmp(tail, "/libp3dtool.so") == 0)) {
         _dtool_name = head;
         _dtool_name = head;
       }
       }
     }
     }