From 05ba0110119d9a94a96bdfac83f9e1f732bbabb7 Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Sun, 24 Jan 1999 14:24:17 +0000 Subject: [PATCH] * doc/libtool.texi (libltdl): list supported dlopen mechanisms, added function lt_dlopenext(), removed reference to LTDL_PRELOADED_SYMBOLS in LTDL_SET_PRELOADED_SYMBOLS * libltdl/ltdl.c: partially reverted Alexandre's dynamic string allocation change (it was not necessary and the code was unreadable), cleanups, removed usr_search_path_size, renamed usr_search_path to user_search_path, in find_module() also check for moved modules, merged find_file() and find_library(), added lt_dlopenext(), in lt_dladdsearchdir() no longer reset the search path if 'search_dir' == NULL and don't use realloc() (might not be available on all platforms), removed __P((void)) in the declaration of lt_dlgetsearchpath() * libltdl/ltdl.h: added lt_dlopenext() * ltconfig.in: AIX archive commands were broken, fixed a MAJOR bug in global_symbol_pipe which caused "demo-shared.test;demo-make.test" to fail (libtool must not extract undefined symbols of libraries, i.e. symcode must not contain 'U') * tests/Makefile.am (clean-local): "make distclean" in cdemo, too --- ChangeLog | 21 ++ doc/libtool.texi | 61 +++-- libltdl/ltdl.c | 552 ++++++++++++++++++++-------------------------- libltdl/ltdl.h | 1 + ltconfig.in | 22 +- tests/Makefile.am | 1 + 6 files changed, 315 insertions(+), 343 deletions(-) diff --git a/ChangeLog b/ChangeLog index e87531a6..22120726 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +1999-01-24 Thomas Tanner + + * doc/libtool.texi (libltdl): list supported dlopen mechanisms, + added function lt_dlopenext(), removed reference to + LTDL_PRELOADED_SYMBOLS in LTDL_SET_PRELOADED_SYMBOLS + * libltdl/ltdl.c: partially reverted Alexandre's dynamic string + allocation change (it was not necessary and the code was unreadable), + cleanups, removed usr_search_path_size, renamed usr_search_path + to user_search_path, in find_module() also check for moved + modules, merged find_file() and find_library(), + added lt_dlopenext(), in lt_dladdsearchdir() no longer reset + the search path if 'search_dir' == NULL and don't use realloc() + (might not be available on all platforms), + removed __P((void)) in the declaration of lt_dlgetsearchpath() + * libltdl/ltdl.h: added lt_dlopenext() + * ltconfig.in: AIX archive commands were broken, + fixed a MAJOR bug in global_symbol_pipe which caused + "demo-shared.test;demo-make.test" to fail (libtool must not extract + undefined symbols of libraries, i.e. symcode must not contain 'U') + * tests/Makefile.am (clean-local): "make distclean" in cdemo, too + 1999-01-22 Alexandre Oliva * Makefile.am (ltconfig, ltmain.sh): add ChangeLog Revision to diff --git a/doc/libtool.texi b/doc/libtool.texi index 0264fbdd..10b9c21a 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -2536,6 +2536,22 @@ distributed with applications that need dlopening functionality. On some platforms, whose dynamic linkers are too limited for a simple implementation of @file{libltdl} services, it requires GNU DLD. +@noindent +Libltdl supports currently the following dynamic linking mechanims: + +@itemize @bullet +@item +dlopen (Solaris, Linux and various BSD flavors) +@item +shl_load (HP-UX) +@item +LoadLibrary (Win16 and Win32) +@item +GNU DLD (emulates dynamic linking for static libraries) +@item +libtool's dlpreopen (see @pxref{Dlpreopening}) +@end itemize + @menu * Libltdl's interface:: How to use libltdl in your programs. * Modules for libltdl:: Creating modules that can be @code{dlopen}ed. @@ -2561,21 +2577,19 @@ Note that libltdl is not threadsafe, i.e. a multithreaded application has to use a mutex for libltdl. @noindent -The following types are defined by libltdl: +The following types are defined in @file{ltdl.h}: @table @code @item lt_ptr_t @code{lt_ptr_t} is a generic pointer. @item lt_dlhandle -@code{lt_dlhandle} is a module "handle" used by @code{lt_dlopen}, -@code{lt_dlclose} and @code{lt_dlsym}. Every dlopened module has -a handle associated with it. +@code{lt_dlhandle} is a module "handle". +Every dlopened module has a handle associated with it. @item lt_dlsymlist @code{lt_dlsymlist} is a symbol list for dlpreopened modules. -This structure is described in @pxref{Dlpreopening} and is -used by @code{lt_dlpreload} and @code{lt_dlpreload_default}. +This structure is described in @pxref{Dlpreopening}. @end table @noindent @@ -2596,7 +2610,7 @@ Return 0 on success, otherwise the number of errors. @end deftypefun @deftypefun lt_dlhandle lt_dlopen (const char *@var{filename}) -Open the module whose name is derived from @var{filename} and return a +Open the module with the file name @var{filename} and return a handle for it. @code{lt_dlopen} is able to open libtool dynamic modules, preloaded static modules and native dynamic libraries. @@ -2630,21 +2644,24 @@ e.g. "/usr/lib/mypkg:/lib/foo". If the same module is loaded several times, the same handle is returned. If @code{lt_dlopen} fails for any reason, it returns NULL. +@end deftypefun -@code{lt_dlopen} will preferentially open libtool modules. Therefore, -if the @var{filename} does not end with the libtool archive extension, -@samp{".la"}, @code{lt_dlopen} will automatically search for a libtool -module by appending @samp{".la"} to the @var{filename}. If this fails, -it assumes the @var{filename} refers to a native dynamic library, so -tries to locate a library with the given name. If even this fails, -@code{lt_dlopen} will try to append to @var{filename} the extension used -for native dynamic libraries in the host platform, e.g., @samp{".so"}, -@samp{".sl"}, etc. +@deftypefun lt_dlhandle lt_dlopenext (const char *@var{filename}) +The same as @code{lt_dlopen}, except that it tries to append +different file name extensions to the file name. +If the file with the file name @var{filename} cannot be found +libltdl tries to append the following extensions: -This lookup strategy was designed to allow programs that have knowledge -about native dynamic libraries naming conventions to be able to dlopen -such libraries directly, and to allow programs that don't have this -knowledge to let libltdl take care of this for them. +@enumerate 1 +@item the libtool archive extension @samp{.la} +@item the extension used for native dynamic libraries on the host platform, +e.g., @samp{.so}, @samp{.sl}, etc. +@end enumerate + +This lookup strategy was designed to allow programs that don't +have knowledge about native dynamic libraries naming conventions +to be able to @code{dlopen} such libraries as well as libtool modules +transparently. @end deftypefun @deftypefun int lt_dlclose (lt_dlhandle @var{handle}) @@ -2687,8 +2704,8 @@ Return 0 on success. @defmac LTDL_SET_PRELOADED_SYMBOLS() Set the default list of preloaded symbols. -Should be used together with @code{LTDL_PRELOADED_SYMBOLS} -in your program to initialize libltdl's list of preloaded modules. +Should be used in your program to initialize libltdl's +list of preloaded modules. @example #include diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index a655cd48..522bac7b 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -72,9 +72,11 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define LTDL_SYMBOL_LENGTH 128 #undef LTDL_SYMBOL_OVERHEAD -/* This accounts for the _LTX_ separator and the string terminator */ -#define LTDL_SYMBOL_OVERHEAD 6 +/* This accounts for the _LTX_ separator */ +#define LTDL_SYMBOL_OVERHEAD 5 +static const char *objdir = LTDL_OBJDIR "/"; +static const char *shlib_ext = LTDL_SHLIB_EXT; static const char *unknown_error = "unknown error"; static const char *dlopen_not_supported_error = "dlopen support not available"; @@ -86,6 +88,11 @@ static const char *invalid_handle_error = "invalid handle"; static const char *buffer_overflow_error = "internal buffer overflow"; static const char *shutdown_error = "library already shutdown"; +#ifndef HAVE_PRELOADED_SYMBOLS +/* If libtool won't define it, we'd better do */ +const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } }; +#endif + static const char *last_error = 0; typedef struct lt_dltype_t { @@ -540,7 +547,7 @@ presym_init () return 0; } -static int /* not all compilers support void */ +static int presym_free_symlists () { lt_dlsymlists_t *lists = preloaded_symbols; @@ -658,8 +665,7 @@ presym = { LTDL_TYPE_TOP, 0, presym_init, presym_exit, #undef LTDL_TYPE_TOP #define LTDL_TYPE_TOP &presym -static char *usr_search_path; -static int usr_search_path_size = 0; +static char *user_search_path = 0; static lt_dlhandle handles = 0; static int initialized = 0; @@ -678,9 +684,7 @@ lt_dlinit () return 0; } handles = 0; - if (usr_search_path) - free(usr_search_path); - usr_search_path = 0; /* empty search path */ + user_search_path = 0; /* empty search path */ while (*type) { if ((*type)->mod_init()) @@ -719,11 +723,6 @@ lt_dlpreload_default (preloaded) return 0; } -#ifndef HAVE_PRELOADED_SYMBOLS -/* If libtool won't define it, we'd better do */ -const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } }; -#endif - int lt_dlexit () { @@ -755,6 +754,22 @@ lt_dlexit () return errors; } +static int +trim (dest, s) + char *dest; + const char *s; +{ + char *i = strrchr(s, '\''); + int len = strlen(s); + + if (len > 3 && s[0] == '\'') { + strncpy(dest, &s[1], (i - s) - 1); + dest[len-3] = '\0'; + } else + *dest = '\0'; + return 0; +} + static int tryall_dlopen (handle, filename) lt_dlhandle *handle; @@ -775,164 +790,130 @@ tryall_dlopen (handle, filename) return 0; } - (*handle)->filename = strdup(filename); - if (!(*handle)->filename) + cur = *handle; + cur->filename = strdup(filename); + if (!cur->filename) return 1; while (type) { - if (type->lib_open(*handle, filename) == 0) + if (type->lib_open(cur, filename) == 0) break; type = type->next; } if (!type) { - free((*handle)->filename); + free(cur->filename); return 1; } - (*handle)->type = type; + cur->type = type; last_error = saved_error; return 0; } static int -find_module (handle, dir, dlname, old_name) +find_module (handle, dir, libdir, dlname, old_name, installed) lt_dlhandle *handle; const char *dir; + const char *libdir; const char *dlname; const char *old_name; + int installed; { - /* search for old library first; if it was dlpreopened, we - want the preopened version of it, even if a dlopenable - module is available */ - if (old_name && tryall_dlopen(handle, old_name) == 0) + char filename[LTDL_FILENAME_MAX]; + + /* try to open the old library first; if it was dlpreopened, + we want the preopened version of it, even if a dlopenable + module is available */ + if (*old_name && tryall_dlopen(handle, old_name) == 0) return 0; - - /* search a module */ - if (dlname) { - char *filename = malloc(strlen(dir)+1+strlen(dlname)+1); - - if (!filename) { - last_error = memory_error; - return 1; + /* try to open the dynamic library */ + if (*dlname) { + /* try to open the installed module */ + if (installed && + strlen(libdir)+1+strlen(dlname) < LTDL_FILENAME_MAX) { + strcpy(filename, libdir); + strcat(filename, "/"); + strcat(filename, dlname); + if (tryall_dlopen(handle, filename) == 0) + return 0; } - strcpy(filename, dir); - strcat(filename, "/"); - strcat(filename, dlname); - if (tryall_dlopen(handle, filename) == 0) { - free(filename); - return 0; + /* try to open the not-installed module */ + if (!installed && + strlen(dir)+strlen(objdir)+strlen(dlname) + < LTDL_FILENAME_MAX) { + strcpy(filename, dir); + strcat(filename, objdir); + strcat(filename, dlname); + if (tryall_dlopen(handle, filename) == 0) + return 0; + } + /* hmm, maybe it was moved to another directory */ + if (strlen(dir)+strlen(dlname) < LTDL_FILENAME_MAX) { + strcpy(filename, dir); + strcat(filename, dlname); + if (tryall_dlopen(handle, filename) == 0) + return 0; } - free(filename); } last_error = file_not_found_error; return 1; } -#undef LTDL_CHECK_SIZE -#define LTDL_CHECK_SIZE(buf_, size_, need_, ret) do { \ - char **pbuf = &buf_; int *psize = &size_, need = need_; \ - if (need > *psize) { \ - if (*pbuf) \ - free(*pbuf); \ - *pbuf = malloc(need); \ - if (!*pbuf) { \ - last_error = memory_error; \ - return ret; \ - } \ - } \ -} while(0) - -static int -find_library (handle, basename, search_path) - lt_dlhandle *handle; +static lt_ptr_t +find_file (basename, search_path, pdir, handle) const char *basename; const char *search_path; + char *pdir; + lt_dlhandle *handle; { - char *filename = 0; - int size = 0; + /* when handle != NULL search a library, otherwise a file */ + /* return NULL on failure, otherwise the file/handle */ + + char filename[LTDL_FILENAME_MAX]; const char *cur, *next; - int baselen; + FILE *file; + int lendir; - if (!search_path || !strlen(search_path)) { - last_error = file_not_found_error; - return 1; - } - cur = search_path; - baselen = strlen(basename); - while (cur) { - int lendir; - next = strchr(cur, ':'); - if (next) - lendir = next-cur; - else - lendir = strlen(cur); - if (lendir == 0) - continue; - LTDL_CHECK_SIZE(filename, size, \ - lendir + 1 + baselen + 1, 1); - strncpy(filename, cur, lendir); - if (next) - cur = next+1; - else - cur = 0; - filename[lendir] = '/'; - strncpy(filename+lendir+1, basename, baselen+1); - if (tryall_dlopen(handle, filename) == 0) { - free(filename); - return 0; - } - } - free(filename); - last_error = file_not_found_error; - return 1; -} - -static FILE * -find_file (basename, search_path, pdir) - const char *basename; - const char *search_path; - const char **pdir; -{ - char *filename = 0; - int size = 0; - const char *cur, *next; - FILE *file; - int baselen; - int overhead; - if (!search_path || !strlen(search_path)) { last_error = file_not_found_error; return 0; } cur = search_path; - baselen = strlen(basename); - overhead = strlen(LTDL_OBJDIR)+1; - if (baselen > overhead) - overhead = baselen; while (cur) { - int lendir; next = strchr(cur, ':'); - if (next) - lendir = next-cur; - else - lendir = strlen(cur); - if (lendir == 0) - continue; - LTDL_CHECK_SIZE(filename, size, \ - lendir + 1 + overhead + 1, 0); - strncpy(filename, cur, lendir); - if (next) + if (next) { + if (next - cur + 1 >= LTDL_FILENAME_MAX) { + last_error = buffer_overflow_error; + return 0; + } + strncpy(filename, cur, next - cur); + filename[next - cur] = '\0'; cur = next+1; - else + } else { + if (strlen(cur)+1 >= LTDL_FILENAME_MAX) { + last_error = buffer_overflow_error; + return 0; + } + strcpy(filename, cur); cur = 0; - filename[lendir] = '/'; - strncpy(filename+lendir+1, basename, baselen+1); - file = fopen(filename, LTDL_READTEXT_MODE); - if (file) { - filename[lendir+1] = '\0'; - *pdir = filename; - return file; + } + if (!*filename) + continue; + strcat(filename, "/"); + lendir = strlen(filename); + if (lendir+strlen(basename) < LTDL_FILENAME_MAX) { + strcat(filename, basename); + if (handle) { + if (tryall_dlopen(handle, filename) == 0) + return (lt_ptr_t) handle; + } else { + file = fopen(filename, LTDL_READTEXT_MODE); + if (file) { + filename[lendir+1] = '\0'; + strcpy(pdir, filename); + return (lt_ptr_t) file; + } + } } } - free(filename); last_error = file_not_found_error; return 0; } @@ -956,247 +937,214 @@ unload_deplibs(handle) return 0; } -#undef LTDL_TRIM -#define LTDL_TRIM(dest_, s_) do { \ - char **dest = &(dest_); \ - char *s = (s_); \ - int len = strlen(s); \ - \ - if (*dest) \ - free(*dest); \ - *dest = 0; \ - \ - if (len > 3 && s[0] == '\'' \ - && s[len-1] == '\n' && s[len-2] == '\'') { \ - *dest = malloc(len-2); \ - if (!*dest) \ - goto trim_raise_memory_error; \ - strncpy(*dest, &s[1], len - 3); \ - (*dest)[len-3] = '\0'; \ - } \ -} while(0) - lt_dlhandle lt_dlopen (filename) const char *filename; { - lt_dlhandle handle = 0; - char *dir = 0, *name = 0; + lt_dlhandle handle; + char dir[LTDL_FILENAME_MAX]; const char *basename, *ext; const char *saved_error = last_error; + char *name = 0; + if (!filename) { + last_error = file_not_found_error; + return 0; + } basename = strrchr(filename, '/'); - if (basename) { + if (basename) basename++; - dir = malloc(basename - filename + strlen(LTDL_OBJDIR) + 1); - if (!dir) { - last_error = memory_error; - return 0; - } - strncpy(dir, filename, basename-filename); - dir[basename-filename] = '\0'; - } else + else basename = filename; - + if (basename - filename >= LTDL_FILENAME_MAX) { + last_error = buffer_overflow_error; + return 0; + } + strncpy(dir, filename, basename - filename); + dir[basename - filename] = '\0'; /* check whether we open a libtool module (.la extension) */ ext = strrchr(basename, '.'); if (ext && strcmp(ext, ".la") == 0) { - char *dlname = 0, *old_name = 0; - char *libdir = 0, *deplibs = 0; + char dlname[LTDL_FILENAME_MAX], old_name[LTDL_FILENAME_MAX]; + char libdir[LTDL_FILENAME_MAX], deplibs[LTDL_FILENAME_MAX]; char tmp[LTDL_FILENAME_MAX]; FILE *file; int i; + /* if we can't find the installed flag, it is probably an installed libtool archive, produced with an old version of libtool */ int installed=1; + dlname[0] = old_name[0] = libdir[0] = deplibs[0] = '\0'; + /* extract the module name from the file name */ if (strlen(basename) >= sizeof(tmp)) { last_error = buffer_overflow_error; return 0; } - strcpy(tmp, basename); - tmp[ext - basename] = '\0'; /* canonicalize the module name */ for (i = 0; i < ext - basename; i++) - if (!isalnum(tmp[i])) + if (isalnum(basename[i])) + tmp[i] = basename[i]; + else tmp[i] = '_'; + tmp[ext - basename] = '\0'; name = strdup(tmp); if (!name) { last_error = memory_error; return 0; } + file = fopen(filename, LTDL_READTEXT_MODE); - if (!file && !dir) { + if (!file) + last_error = file_not_found_error; + if (!file && !*dir) { /* try other directories */ - file = find_file(basename, usr_search_path, &dir); + file = (FILE*) find_file(basename, + user_search_path, + dir, 0); if (!file) - file = find_file(basename, + file = (FILE*) find_file(basename, getenv("LTDL_LIBRARY_PATH"), - &dir); + dir, 0); #ifdef LTDL_SHLIBPATH_VAR if (!file) - file = find_file(basename, + file = (FILE*) find_file(basename, getenv(LTDL_SHLIBPATH_VAR), - &dir); + dir, 0); #endif } if (!file) { - goto clean_up_dir; + free(name); + return 0; } while (!feof(file)) { if (!fgets(tmp, sizeof(tmp), file)) break; if (tmp[0] == '\n' || tmp[0] == '#') - ; - else + continue; if (strncmp(tmp, "dlname=", 7) == 0) - LTDL_TRIM(dlname, &tmp[7]); + trim(dlname, &tmp[7]); else if (strncmp(tmp, "old_library=", 12) == 0) - LTDL_TRIM(old_name, &tmp[12]); + trim(old_name, &tmp[12]); else if (strncmp(tmp, "libdir=", 7) == 0) - LTDL_TRIM(libdir, &tmp[7]); + trim(libdir, &tmp[7]); else if (strncmp(tmp, "dl_dependency_libs=", 20) == 0) - LTDL_TRIM(deplibs, &tmp[20]); + trim(deplibs, &tmp[20]); else if (strcmp(tmp, "installed=yes\n") == 0) installed = 1; else if (strcmp(tmp, "installed=no\n") == 0) installed = 0; - else - if (0) { - trim_raise_memory_error: - fclose(file); - goto handle_raise_memory_error; - } } fclose(file); handle = (lt_dlhandle) malloc(sizeof(lt_dlhandle_t)); if (!handle) { - handle_raise_memory_error: last_error = memory_error; - goto clean_up_vars; + free(name); + return 0; } handle->usage = 0; - if (deplibs && load_deplibs(handle, deplibs)) { - clean_up_handle: + if (load_deplibs(handle, deplibs)) { free(handle); - handle = 0; - goto clean_up_vars; + free(name); + return 0; } - if (installed) { - if (find_module(&handle, libdir, dlname, old_name)) { - clean_up_deplibs: - unload_deplibs(handle); - goto clean_up_handle; - } - } else { - /* We dir is non-NULL, it has enough space for - LTDL_OBJDIR: it was reserved in the - beginning of the function or within - find_file */ - if (dir) - strcat(dir, LTDL_OBJDIR); - if (find_module(&handle, - dir ? dir : LTDL_OBJDIR, - dlname, old_name)) - goto clean_up_deplibs; + if (find_module(&handle, dir, libdir, + dlname, old_name, installed)) { + unload_deplibs(handle); + free(handle); + free(name); + return 0; } - clean_up_vars: - if (dlname) - free(dlname); - if (old_name) - free(old_name); - if (libdir) - free(libdir); - if (deplibs) - free(deplibs); - if (!handle) - goto clean_up_dir; } else { - /* try to append libtool library extension */ - char *newfilename = malloc(strlen(filename)+4); - if (!newfilename) { - last_error = memory_error; - goto clean_up_dir; - } - strcpy(newfilename, filename); - strcat(newfilename, ".la"); - handle = lt_dlopen(newfilename); - free(newfilename); - if (handle) - goto restore_error; - /* not a libtool module */ handle = (lt_dlhandle) malloc(sizeof(lt_dlhandle_t)); if (!handle) { last_error = memory_error; - goto clean_up_dir; + return 0; } handle->usage = 0; - if (tryall_dlopen(&handle, filename) - && (dir - || (find_library(&handle, basename, usr_search_path) - && find_library(&handle, basename, - getenv("LTDL_LIBRARY_PATH")) + if (tryall_dlopen(&handle, filename) && (*dir + || (find_file(basename, user_search_path, 0, &handle) + && find_file(basename, getenv("LTDL_LIBRARY_PATH"), + 0, &handle) #ifdef LTDL_SHLIBPATH_VAR - && find_library(&handle, basename, - getenv(LTDL_SHLIBPATH_VAR)) -#endif - ))) { -#ifdef LTDL_SHLIB_EXT - newfilename = malloc(strlen(filename) + - strlen(LTDL_SHLIB_EXT) + 1); - if (!newfilename) { - last_error = memory_error; - goto clean_up_hand; - } - strcpy(newfilename, filename); - strcat(newfilename, LTDL_SHLIB_EXT); - basename = newfilename + (basename - filename); - if (tryall_dlopen(&handle, newfilename) - && (dir - || (find_library(&handle, basename, usr_search_path) - && find_library(&handle, basename, - getenv("LTDL_LIBRARY_PATH")) -#ifdef LTDL_SHLIBPATH_VAR - && find_library(&handle, basename, - getenv(LTDL_SHLIBPATH_VAR)) -#endif - ))) { -#endif - clean_up_hand: - free(handle); - handle = 0; - goto clean_up_dir; -#ifdef LTDL_SHLIB_EXT - } + && find_file(basename, getenv(LTDL_SHLIBPATH_VAR), + 0, &handle) #endif + ))) { + free(handle); + return 0; } } if (!handle->usage) { handle->usage = 1; + handle->name = name; handle->next = handles; handles = handle; - handle->name = name; - name = 0; } - restore_error: last_error = saved_error; - clean_up_dir: - if (dir) - free(dir); - if (name) - free(name); return handle; } +lt_dlhandle +lt_dlopenext (filename) + const char *filename; +{ + lt_dlhandle handle; + char tmp[LTDL_FILENAME_MAX]; + int len; + const char *saved_error = last_error; + + if (!filename) { + last_error = file_not_found_error; + return 0; + } + len = strlen(filename); + if (!len) { + last_error = file_not_found_error; + return 0; + } + /* try the normal file name */ + handle = lt_dlopen(filename); + if (handle) + return handle; + /* try "filename.la" */ + if (len+3 >= sizeof(tmp)) { + last_error = buffer_overflow_error; + return 0; + } + strcpy(tmp, filename); + strcat(tmp, ".la"); + handle = lt_dlopen(tmp); + if (handle) { + last_error = saved_error; + return handle; + } +#ifdef LTDL_SHLIB_EXT + /* try "filename.EXT" */ + tmp[len-1] = '\0'; + if (len+strlen(shlib_ext) >= sizeof(tmp)) { + last_error = buffer_overflow_error; + return 0; + } + strcat(tmp, shlib_ext); + handle = lt_dlopen(tmp); + if (handle) { + last_error = saved_error; + return handle; + } +#endif + return 0; +} + int lt_dlclose (handle) lt_dlhandle handle; @@ -1258,7 +1206,7 @@ lt_dlsym (handle, symbol) if (lensym + LTDL_SYMBOL_OVERHEAD < LTDL_SYMBOL_LENGTH) sym = lsym; else - sym = malloc(lensym + LTDL_SYMBOL_OVERHEAD); + sym = malloc(lensym + LTDL_SYMBOL_OVERHEAD + 1); if (!sym) { last_error = buffer_overflow_error; return 0; @@ -1305,33 +1253,26 @@ int lt_dladdsearchdir (search_dir) const char *search_dir; { - if (!search_dir) { - if (usr_search_path) - free(usr_search_path); - usr_search_path = 0; /* reset the search path */ + if (!search_dir || !strlen(search_dir)) return 0; - } - if (!strlen(search_dir)) - return 0; - if (!usr_search_path) { - usr_search_path_size = strlen(search_dir)+1; - usr_search_path = malloc(usr_search_path_size); - if (!usr_search_path) { + if (!user_search_path) { + user_search_path = strdup(search_dir); + if (!user_search_path) { last_error = memory_error; return 1; } - strcpy(usr_search_path, search_dir); } else { - int new_size = usr_search_path_size + strlen(search_dir) + 1; - char *new_search_path = realloc(usr_search_path, new_size); + char *new_search_path = (char*) + malloc(strlen(user_search_path) + + strlen(search_dir) + 1); if (!new_search_path) { last_error = memory_error; return 1; } - usr_search_path = new_search_path; - usr_search_path_size = new_size; - strcat(usr_search_path, ":"); - strcat(usr_search_path, search_dir); + strcat(new_search_path, ":"); + strcat(new_search_path, search_dir); + free(user_search_path); + user_search_path = new_search_path; } return 0; } @@ -1340,22 +1281,19 @@ int lt_dlsetsearchpath (search_path) const char *search_path; { - if (usr_search_path) - free(usr_search_path); - usr_search_path = 0; /* reset the search path */ - if (!search_path || !strlen(search_path)) { + if (user_search_path) + free(user_search_path); + user_search_path = 0; /* reset the search path */ + if (!search_path || !strlen(search_path)) return 0; - } - usr_search_path = strdup(search_path); - if (usr_search_path) - usr_search_path_size = strlen(usr_search_path)+1; - else + user_search_path = strdup(search_path); + if (!user_search_path) return 1; return 0; } const char * -lt_dlgetsearchpath __P((void)) +lt_dlgetsearchpath () { - return usr_search_path; + return user_search_path; } diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h index dbe1a0e6..07af535f 100644 --- a/libltdl/ltdl.h +++ b/libltdl/ltdl.h @@ -79,6 +79,7 @@ _LTDLL_EXTERN int lt_dlpreload __P((const lt_dlsymlist *preloaded)); _LTDLL_EXTERN int lt_dlpreload_default __P((const lt_dlsymlist *preloaded)); _LTDLL_EXTERN int lt_dlexit __P((void)); _LTDLL_EXTERN lt_dlhandle lt_dlopen __P((const char *filename)); +_LTDLL_EXTERN lt_dlhandle lt_dlopenext __P((const char *filename)); _LTDLL_EXTERN int lt_dlclose __P((lt_dlhandle handle)); _LTDLL_EXTERN lt_ptr_t lt_dlsym __P((lt_dlhandle handle, const char *name)); _LTDLL_EXTERN const char *lt_dlerror __P((void)); diff --git a/ltconfig.in b/ltconfig.in index 5b93f339..14a6447d 100755 --- a/ltconfig.in +++ b/ltconfig.in @@ -1146,7 +1146,7 @@ else fi archive_cmds='$CC -shared ${wl}-bnoentry -o $objdir/$soname $libobjs $deplibs' else - archive_cmds='$NM $libobjs | $global_symbol_pipe | sed '\''s/.* //'\' | sort | uniq' > $lib.exp else cat $export_symbols > $lib.exp~ + archive_cmds='$NM $libobjs | $global_symbol_pipe | sed '\''s/.* //'\' | sort | uniq' > $lib.exp~ $CC -o $objdir/$soname $libobjs $deplibs ${wl}-bE:$lib.exp ${wl}-bM:SRE ${wl}-bnoentry' archive_sym_cmds='$CC -o $objdir/$soname $libobjs $deplibs ${wl}-bE:$export_symbols ${wl}-bM:SRE ${wl}-bnoentry' hardcode_direct=yes @@ -1407,7 +1407,7 @@ echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. -symcode='[BCDEGRSTU]' +symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' @@ -1418,29 +1418,23 @@ symxfrm='\1 \1' # Define system-specific variables. case "$host_os" in aix*) - symcode='[BCDTU]' + symcode='[BCDT]' + ;; +cygwin32* | mingw32*) + symcode='[ABCDGISTW]' ;; irix*) - # Cannot use undefined symbols on IRIX because inlined functions mess us up. symcode='[BCDEGRST]' ;; solaris*) - symcode='[BDTU]' + symcode='[BDT]' ;; esac # If we're using GNU nm, then use its standard symbol codes. if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then - symcode='[ABCDGISTUW]' -fi - -case "$host_os" in -cygwin32* | mingw32*) - # We do not want undefined symbols on cygwin32. The user must - # arrange to define them via -l arguments. symcode='[ABCDGISTW]' - ;; -esac +fi # Try without a prefix undercore, then with it. for ac_symprfx in "" "_"; do diff --git a/tests/Makefile.am b/tests/Makefile.am index a6243801..776755cf 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -34,5 +34,6 @@ EXTRA_DIST = defs $(TESTS) # We need to remove any files that the above tests created. clean-local: -test -f ../demo/Makefile && cd ../demo && $(MAKE) distclean + -test -f ../cdemo/Makefile && cd ../cdemo && $(MAKE) distclean -test -f ../mdemo/Makefile && cd ../mdemo && $(MAKE) distclean rm -rf _inst