* 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
This commit is contained in:
Thomas Tanner 1999-01-24 14:24:17 +00:00
parent 92ee62a8dc
commit 05ba011011
6 changed files with 315 additions and 343 deletions

View File

@ -1,3 +1,24 @@
1999-01-24 Thomas Tanner <tanner@gmx.de>
* 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 <oliva@dcc.unicamp.br>
* Makefile.am (ltconfig, ltmain.sh): add ChangeLog Revision to

View File

@ -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 <ltdl.h>

View File

@ -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;
}

View File

@ -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));

View File

@ -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

View File

@ -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