The changes to load EGL drivers by pattern matching had the side effect of not
looking in the directories specified by LD_LIBRARY_PATH or -rpath or ldconfig.
This patch changes the search to first look in the directories listed in
LD_LIBRARY_PATH.  To do that it moves the possible addition of a path prefix
from make_library_path() into open_library().

  This patch doesn't add searches in the -rpath or ldconfig directories.
Those would be more difficult (or impossible) to determine in a portable manner.

  The patch also tightens up the library suffix test with a specific
match for the suffix
at the end of the EGL_DRIVER name.

-- 

 Mike Stroyan - Software Architect
 LunarG, Inc.  - The Graphics Experts
 Cell:  (970) 219-7905
 Email: m...@lunarg.com
 Website: http://www.lunarg.com
From 59b7ddbe02fa75045c8037768127a2cfe87a7c8f Mon Sep 17 00:00:00 2001
From: Mike Stroyan <m...@eclipse.(none)>
Date: Sun, 31 Jan 2010 17:58:41 -0700
Subject: [PATCH] Make egl look in library search path for drivers.  Use full suffix test.

---
 src/egl/main/egldriver.c |  144 ++++++++++++++++++++++++++++++++--------------
 1 files changed, 100 insertions(+), 44 deletions(-)

diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index df36369..a801fae 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -56,7 +56,7 @@ close_library(HMODULE lib)
 static const char *
 library_suffix(void)
 {
-   return "dll";
+   return ".dll";
 }
 
 
@@ -64,10 +64,18 @@ static EGLBoolean
 make_library_path(char *buf, unsigned int size, const char *name)
 {
    EGLBoolean need_suffix;
-   const char *suffix = ".dll";
+   const char *suffix = library_suffix();
    int ret;
 
-   need_suffix = (strchr(name, '.') == NULL);
+   /* match the suffix */
+   if (suffix) {
+      size_t name_len = strlen(name);
+      size_t suffix_len = strlen(suffix);
+      need_suffix = (name_len < suffix_len
+         || strcmp(name + name_len - suffix_len, suffix) != 0);
+   } else {
+      need_suffix = EGL_FALSE;
+   }
    ret = snprintf(buf, size, "%s%s", name, (need_suffix) ? suffix : "");
 
    return ((unsigned int) ret < size);
@@ -84,7 +92,25 @@ typedef void * lib_handle;
 static void *
 open_library(const char *filename)
 {
-   return dlopen(filename, RTLD_LAZY);
+   void *handle;
+
+   /* first try opening without an explicit directory to allow search path */
+   handle = dlopen(filename, RTLD_LAZY);
+   if (handle) {
+      return handle;
+   }
+
+   /* if plain file unfound try adding _EGL_DRIVER_SEARCH_DIR directory */
+   if (strchr(filename, '/') == NULL) {
+      char path[1024];
+      int ret;
+      ret = snprintf(path, sizeof(path), "%s%s",
+            _EGL_DRIVER_SEARCH_DIR"/", filename);
+      if ((unsigned int) ret < sizeof(path)) {
+         return dlopen(path, RTLD_LAZY);
+      }
+   }
+   return NULL;
 }
 
 static void
@@ -97,23 +123,27 @@ close_library(void *lib)
 static const char *
 library_suffix(void)
 {
-   return "so";
+   return ".so";
 }
 
 
 static EGLBoolean
 make_library_path(char *buf, unsigned int size, const char *name)
 {
-   EGLBoolean need_dir, need_suffix;
-   const char *suffix = ".so";
+   EGLBoolean need_suffix;
+   const char *suffix = library_suffix();
    int ret;
 
-   need_dir = (strchr(name, '/') == NULL);
-   need_suffix = (strchr(name, '.') == NULL);
-
-   ret = snprintf(buf, size, "%s%s%s",
-         (need_dir) ? _EGL_DRIVER_SEARCH_DIR"/" : "", name,
-         (need_suffix) ? suffix : "");
+   /* match the suffix */
+   if (suffix) {
+      size_t name_len = strlen(name);
+      size_t suffix_len = strlen(suffix);
+      need_suffix = (name_len < suffix_len
+         || strcmp(name + name_len - suffix_len, suffix) != 0);
+   } else {
+      need_suffix = EGL_FALSE;
+   }
+   ret = snprintf(buf, size, "%s%s", name, (need_suffix) ? suffix : "");
 
    return ((unsigned int) ret < size);
 }
@@ -333,6 +363,48 @@ _eglPreloadUserDriver(void)
 #endif
 }
 
+#if defined(_EGL_PLATFORM_POSIX)
+/**
+ * Preload display drivers found in a particular directory.
+ */
+static void
+_eglPreloadDisplayDriversFromDir(const char *prefix, const char *suffix, const char *dir)
+{
+   char path[1024];
+   DIR *dirp;
+   struct dirent *dirent;
+
+   dirp = opendir(dir);
+   if (!dirp)
+      return;
+
+   while ((dirent = readdir(dirp))) {
+      _EGLDriver *drv;
+
+      /* match the prefix */
+      if (strncmp(dirent->d_name, prefix, strlen(prefix)) != 0)
+         continue;
+
+      /* match the suffix */
+      if (suffix) {
+         size_t d_name_len = strlen(dirent->d_name);
+         size_t suffix_len = strlen(suffix);
+         if (d_name_len < suffix_len)
+            continue;
+         if (strcmp(dirent->d_name + d_name_len - suffix_len, suffix) != 0)
+            continue;
+      }
+
+      snprintf(path, sizeof(path), "%s/%s", dir, dirent->d_name);
+
+      drv = _eglLoadDriver(path, NULL);
+      if (drv)
+         _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
+   }
+
+   closedir(dirp);
+}
+#endif
 
 /**
  * Preload display drivers.
@@ -347,10 +419,9 @@ static EGLBoolean
 _eglPreloadDisplayDrivers(void)
 {
 #if defined(_EGL_PLATFORM_POSIX)
-   const char *dpy, *suffix;
-   char path[1024], prefix[32];
-   DIR *dirp;
-   struct dirent *dirent;
+   const char *dpy;
+   char *libpath, *saveptr, *dir;
+   char prefix[32];
 
    dpy = getenv("EGL_DISPLAY");
    if (!dpy || !dpy[0])
@@ -359,36 +430,21 @@ _eglPreloadDisplayDrivers(void)
       return EGL_FALSE;
 
    snprintf(prefix, sizeof(prefix), "egl_%s_", dpy);
-   suffix = library_suffix();
-
-   dirp = opendir(_EGL_DRIVER_SEARCH_DIR);
-   if (!dirp)
-      return EGL_FALSE;
 
-   while ((dirent = readdir(dirp))) {
-      _EGLDriver *drv;
-      const char *p;
-
-      /* match the prefix */
-      if (strncmp(dirent->d_name, prefix, strlen(prefix)) != 0)
-         continue;
-
-      /* match the suffix */
-      p = strrchr(dirent->d_name, '.');
-      if ((p && !suffix) || (!p && suffix))
-         continue;
-      else if (p && suffix && strcmp(p + 1, suffix) != 0)
-         continue;
-
-      snprintf(path, sizeof(path),
-            _EGL_DRIVER_SEARCH_DIR"/%s", dirent->d_name);
-
-      drv = _eglLoadDriver(path, NULL);
-      if (drv)
-         _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
+   /* Try loading drivers from LD_LIBRARY_PATH as well as _EGL_DRIVER_SEARCH_DIR */
+   libpath = getenv("LD_LIBRARY_PATH");
+   /* Copy before strtok_r modifies libpath. */
+   if (libpath) libpath = strdup(libpath);
+   if (libpath) {
+      dir = strtok_r(libpath, ":", &saveptr);
+      while (dir) {
+         _eglPreloadDisplayDriversFromDir(prefix, library_suffix(), dir);
+         dir = strtok_r(NULL, ":", &saveptr);
+      }
+      free(libpath);
    }
 
-   closedir(dirp);
+   _eglPreloadDisplayDriversFromDir(prefix, library_suffix(), _EGL_DRIVER_SEARCH_DIR);
 
    return (_eglGlobal.NumDrivers > 0);
 #else /* _EGL_PLATFORM_POSIX */
-- 
1.6.3.3

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to