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