mirror of
git://git.savannah.gnu.org/libtool.git
synced 2025-03-19 15:50:25 +08:00
* 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:
parent
92ee62a8dc
commit
05ba011011
21
ChangeLog
21
ChangeLog
@ -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
|
||||
|
@ -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>
|
||||
|
552
libltdl/ltdl.c
552
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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
22
ltconfig.in
22
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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user