Changeset: f85e828384eb for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f85e828384eb
Modified Files:
        monetdb5/mal/mal_linker.mx
Branch: Mar2011
Log Message:

loadLibrary: simplify dlopening of libraries

Rely more on dlopen to load a library, instead of first checking if a
file exists, before opening.  Unfortunately, we cannot just give dlopen
the base name of the library we want to open, such that it can figure
out the file extension itself, because we don't have a search path setup
for our module dirs.

On Darwin, a module (bundle) is something distinct from a dynamic
library, and hence also has a different extension.  This patch makes
finding modules on Darwin working again, which means the server can find
its modules again and startup.


diffs (147 lines):

diff --git a/monetdb5/mal/mal_linker.mx b/monetdb5/mal/mal_linker.mx
--- a/monetdb5/mal/mal_linker.mx
+++ b/monetdb5/mal/mal_linker.mx
@@ -121,7 +121,6 @@
 static int maxfiles = MAXMODULES;
 static int lastfile = 0;
 
-static char *MSP_locate_file(const char *filename);
 @-
 Search for occurrence of the function in the library identified by the 
filename.
 @c
@@ -217,39 +216,84 @@
        int mode = RTLD_NOW | RTLD_GLOBAL;
        char nme[MAXPATHLEN];
        void *handle = NULL;
-       str fullname, s;
+       str s;
        int idx;
        const char *errmsg;
+       char *mod_path = GDKgetenv("monet_mod_path");
+
+       /* AIX requires RTLD_MEMBER to load a module that is a member of an
+        * archive.  */
+#ifdef RTLD_MEMBER
+       mode |= RTLD_MEMBER;
+#endif
 
        for (idx = 0; filesLoaded[idx].filename && idx < lastfile; idx++)
                if (strcmp(filesLoaded[idx].filename, filename) == 0)
                        /* already loaded */
                        return MAL_SUCCEED;
-@-
-Use the search path provided in the configuration file
-@c
-       s = strrchr(filename, DIR_SEP);
-       snprintf(nme, MAXPATHLEN, "_%s", s ? s + 1 : filename);
-       fullname = MSP_locate_file(nme);
 
-       if (fullname == NULL) {
-               if( flag)
-                       throw(LOADER, "loadLibrary", RUNTIME_FILE_NOT_FOUND 
":%s", filename);
+       /* ignore any path given */
+       if ((s = strrchr(filename, DIR_SEP)) == NULL)
+               s = filename;
+
+       if (mod_path != NULL) {
+               while (*mod_path == PATH_SEP)
+                       mod_path++;
+               if (*mod_path == 0)
+                       mod_path = NULL;
+       }
+       if (mod_path == NULL) {
+               if (flag)
+                       throw(LOADER, "loadLibrary", RUNTIME_FILE_NOT_FOUND 
":%s", s);
                return MAL_SUCCEED;
        }
 
-/* AIX requires RTLD_MEMBER to load a module that is a member of an archive.  
*/
-#ifdef RTLD_MEMBER
-       mode |= RTLD_MEMBER;
+       while (*mod_path) {
+               char *p;
+
+               if ((p = strchr(mod_path, PATH_SEP)) != NULL)
+                       *p = '\0';
+               /* try hardcoded SO_EXT if that is the same for modules */
+#ifdef _AIX
+               snprintf(nme, MAXPATHLEN, "%s%c%s_%s%s(%s_%s.0)",
+                               mod_path, DIR_SEP, SO_PREFIX, s, SO_EXT, 
SO_PREFIX, s);
+#else
+               snprintf(nme, MAXPATHLEN, "%s%c%s_%s%s",
+                               mod_path, DIR_SEP, SO_PREFIX, s, SO_EXT);
 #endif
+               handle = dlopen(nme, mode);
+               /* try .so */
+               if (handle == NULL && strcmp(SO_EXT, ".so") != 0) {
+                       snprintf(nme, MAXPATHLEN, "%s%c%s_%s.so",
+                                       mod_path, DIR_SEP, SO_PREFIX, s);
+                       handle = dlopen(nme, mode);
+               }
+#ifdef __APPLE__
+               /* try .bundle */
+               if (handle == NULL && strcmp(SO_EXT, ".bundle") != 0) {
+                       snprintf(nme, MAXPATHLEN, "%s%c%s_%s.bundle",
+                                       mod_path, DIR_SEP, SO_PREFIX, s);
+                       handle = dlopen(nme, mode);
+               }
+#endif
+               if (handle != NULL) {
+                       if (p != NULL)
+                               *p = PATH_SEP;
+                       break;
+               }
 
-       handle = dlopen(fullname, mode);
+               if (p == NULL)
+                       break;
+               *p = PATH_SEP;
+               mod_path = p + 1;
+       }
+
        if (handle == NULL) {
                errmsg = dlerror();
                if (!errmsg) 
-                       errmsg = "(no error from dlerror())";
-               GDKfree(fullname);
-               throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR " '%s' from 
within file '%s'", errmsg, filename);
+                       errmsg = "could not locate or open library";
+               if (flag)
+                       throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR " '%s' 
from within file '%s'", errmsg, filename);
        }
 
        mal_set_lock(mal_contextLock, "loadModule");
@@ -257,7 +301,7 @@
                showException(MAL,"loadModule", "internal error, too many 
modules loaded");
        } else {
                filesLoaded[lastfile].filename = GDKstrdup(filename);
-               filesLoaded[lastfile].fullname = fullname;
+               filesLoaded[lastfile].fullname = GDKstrdup(nme);
                filesLoaded[lastfile].handle = handle;
                lastfile ++;
        }
@@ -461,24 +505,4 @@
        /* no directory semantics (yet) */
        return locate_file(filename, SQL_EXT, recurse);
 }
-
-static char *
-MSP_locate_file(const char *filename)
-{
-       char *lib_name = GDKmalloc(strlen(filename) + strlen(SO_PREFIX) + 1);
-       char *fullname;
-
-       strcpy(lib_name, SO_PREFIX);
-       strcpy(lib_name + strlen(SO_PREFIX), filename);
-
-       fullname = locate_file(lib_name, SO_EXT, 0);
-#ifdef _AIX
-       fullname = GDKrealloc(fullname, strlen(fullname) + strlen(lib_name) + 
5);
-       strcat(fullname, "(");
-       strcat(fullname, lib_name);
-       strcat(fullname, ".0)");
-#endif
-       GDKfree(lib_name);
-       return fullname;
-}
 @}
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to