mirror of
git://git.savannah.gnu.org/libtool.git
synced 2024-11-21 01:40:57 +08:00
* NEWS: Updated.
* doc/libtool.texi (User defined module data): Document it all. * ltdl.m4: Check for memcpy, or else bcopy. * ltdl.c (lt_caller_data): New type. (lt_dl_handle_struct): Add an lt_caller_data field. (lt_dlcaller_register, lt_dlcaller_set_data, lt_dlcaller_get_data): New functions. (rpl_memcpy): A minimal fallback implementation. (rpl_realloc): A realloc implemented with lt_dlmalloc and lt_dlfree. (LT_DLMALLOC, LT_DLFREE, LT_DLREALLOC, LT_DLMEM_REASSIGN): New memory handling convenience macros. Use them appropriately throughout the rest of this file. * ltdl.h (lt_dlcaller_register, lt_dlcaller_set_data, lt_dlcaller_get_data): Prototyped.
This commit is contained in:
parent
c821715109
commit
bd96d1928a
18
ChangeLog
18
ChangeLog
@ -1,3 +1,21 @@
|
|||||||
|
2001-01-05 Gary V. Vaughan <gvv@techie.com>
|
||||||
|
|
||||||
|
* NEWS: Updated.
|
||||||
|
* doc/libtool.texi (User defined module data): Document it all.
|
||||||
|
* ltdl.m4: Check for memcpy, or else bcopy.
|
||||||
|
* ltdl.c (lt_caller_data): New type.
|
||||||
|
(lt_dl_handle_struct): Add an lt_caller_data field.
|
||||||
|
(lt_dlcaller_register, lt_dlcaller_set_data,
|
||||||
|
lt_dlcaller_get_data): New functions.
|
||||||
|
(rpl_memcpy): A minimal fallback implementation.
|
||||||
|
(rpl_realloc): A realloc implemented with lt_dlmalloc and
|
||||||
|
lt_dlfree.
|
||||||
|
(LT_DLMALLOC, LT_DLFREE, LT_DLREALLOC, LT_DLMEM_REASSIGN):
|
||||||
|
New memory handling convenience macros. Use them
|
||||||
|
appropriately throughout the rest of this file.
|
||||||
|
* ltdl.h (lt_dlcaller_register, lt_dlcaller_set_data,
|
||||||
|
lt_dlcaller_get_data): Prototyped.
|
||||||
|
|
||||||
2001-01-04 Gary V. Vaughan <gvv@techie.com>
|
2001-01-04 Gary V. Vaughan <gvv@techie.com>
|
||||||
|
|
||||||
* libltdl/ltdl.h: formatting change.
|
* libltdl/ltdl.h: formatting change.
|
||||||
|
2
NEWS
2
NEWS
@ -13,6 +13,8 @@ New in 1.3d: 2000-??-??; CVS version 1.3c, Libtool team:
|
|||||||
* Libtool now allows you to link shared libraries against static code.
|
* Libtool now allows you to link shared libraries against static code.
|
||||||
* New functions in libltdl:
|
* New functions in libltdl:
|
||||||
lt_dlgetinfo, lt_dlforeach provide access to module specific data in handles.
|
lt_dlgetinfo, lt_dlforeach provide access to module specific data in handles.
|
||||||
|
lt_dlcaller_register, lt_dlcaller_set_data and lt_dlcaller_get_data provide
|
||||||
|
management for user storage of per module data.
|
||||||
lt_dlloader_next, lt_dlloader_name, lt_dlloader_find, lt_dlloader_add and
|
lt_dlloader_next, lt_dlloader_name, lt_dlloader_find, lt_dlloader_add and
|
||||||
lt_dlloader_remove can be used for adding new types of module loaders.
|
lt_dlloader_remove can be used for adding new types of module loaders.
|
||||||
lt_dladderror, lt_dlseterror integrate user module loaders with lt_dlerror.
|
lt_dladderror, lt_dlseterror integrate user module loaders with lt_dlerror.
|
||||||
|
389
doc/libtool.texi
389
doc/libtool.texi
@ -165,8 +165,9 @@ Using libltdl
|
|||||||
|
|
||||||
* Libltdl interface:: How to use libltdl in your programs.
|
* Libltdl interface:: How to use libltdl in your programs.
|
||||||
* Modules for libltdl:: Creating modules that can be @code{dlopen}ed.
|
* Modules for libltdl:: Creating modules that can be @code{dlopen}ed.
|
||||||
* Distributing libltdl:: How to distribute libltdl with your package.
|
* User defined module data:: Associating data with loaded modules.
|
||||||
* Module loaders for libltdl:: Creating user defined module loaders.
|
* Module loaders for libltdl:: Creating user defined module loaders.
|
||||||
|
* Distributing libltdl:: How to distribute libltdl with your package.
|
||||||
|
|
||||||
Using libtool with other languages
|
Using libtool with other languages
|
||||||
|
|
||||||
@ -2634,8 +2635,9 @@ distribution terms that you use for the rest of that program.
|
|||||||
@menu
|
@menu
|
||||||
* Libltdl interface:: How to use libltdl in your programs.
|
* Libltdl interface:: How to use libltdl in your programs.
|
||||||
* Modules for libltdl:: Creating modules that can be @code{dlopen}ed.
|
* Modules for libltdl:: Creating modules that can be @code{dlopen}ed.
|
||||||
* Distributing libltdl:: How to distribute libltdl with your package.
|
* User defined module data:: Associating data with loaded modules.
|
||||||
* Module loaders for libltdl:: Creating user defined module loaders.
|
* Module loaders for libltdl:: Creating user defined module loaders.
|
||||||
|
* Distributing libltdl:: How to distribute libltdl with your package.
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Libltdl interface
|
@node Libltdl interface
|
||||||
@ -2684,16 +2686,6 @@ The following types are defined in @file{ltdl.h}:
|
|||||||
Every lt_dlopened module has a handle associated with it.
|
Every lt_dlopened module has a handle associated with it.
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
@deftypefn {Type} {struct} lt_dlinfo @{ @w{char *@var{filename};} @w{char *@var{name};} @w{int @var{ref_count};} @}
|
|
||||||
@code{lt_dlinfo} is used to store information about a module.
|
|
||||||
The @var{filename} attribute is a null-terminated character string of the
|
|
||||||
real module file name. If the module is a libtool module then @var{name}
|
|
||||||
is its module name (e.g. @code{"libfoo"} for @code{"dir/libfoo.la"}),
|
|
||||||
otherwise it is set to @code{NULL}.
|
|
||||||
The @var{ref_count} attribute is a reference counter that describes how often
|
|
||||||
the same module is currently loaded.
|
|
||||||
@end deftypefn
|
|
||||||
|
|
||||||
@deftp {Type} lt_dlsymlist
|
@deftp {Type} lt_dlsymlist
|
||||||
@code{lt_dlsymlist} is a symbol list for dlpreopened modules.
|
@code{lt_dlsymlist} is a symbol list for dlpreopened modules.
|
||||||
This structure is described in @pxref{Dlpreopening}.
|
This structure is described in @pxref{Dlpreopening}.
|
||||||
@ -2863,21 +2855,6 @@ function, return -1 and set an error message for retrieval with
|
|||||||
@code{lt_dlerror}.
|
@code{lt_dlerror}.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
@deftypefun {const lt_dlinfo *}lt_dlgetinfo (lt_dlhandle @var{handle})
|
|
||||||
Return a pointer to a struct that contains some information about
|
|
||||||
the module @var{handle}. The contents of the struct must not be modified.
|
|
||||||
Return @code{NULL} on failure.
|
|
||||||
@end deftypefun
|
|
||||||
|
|
||||||
@deftypefun int lt_dlforeach (int (*@var{func})(lt_dlhandle @var{handle}, lt_ptr @var{data}), lt_ptr @var{data})
|
|
||||||
For each loaded module call the function @var{func}. The argument
|
|
||||||
@var{handle} is the handle of one of the loaded modules, @var{data} is
|
|
||||||
the @var{data} argument passed to @code{lt_dlforeach}.
|
|
||||||
As soon as @var{func} returns a non-zero value for one of the handles,
|
|
||||||
@code{lt_dlforeach} will stop calling @var{func} and immediately return 1.
|
|
||||||
Otherwise 0 is returned.
|
|
||||||
@end deftypefun
|
|
||||||
|
|
||||||
@deftypevar {lt_ptr (*) (size_t @var{size})} lt_dlmalloc
|
@deftypevar {lt_ptr (*) (size_t @var{size})} lt_dlmalloc
|
||||||
@deftypevarx {void (*) (lt_ptr @var{ptr})} lt_dlfree
|
@deftypevarx {void (*) (lt_ptr @var{ptr})} lt_dlfree
|
||||||
These variables are set to @code{malloc} and @code{free}, by default,
|
These variables are set to @code{malloc} and @code{free}, by default,
|
||||||
@ -2953,143 +2930,121 @@ foo1_la_LDFLAGS = -module
|
|||||||
...
|
...
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@node Distributing libltdl
|
|
||||||
@section How to distribute libltdl with your package
|
|
||||||
|
|
||||||
Even though libltdl is installed together with libtool, you may wish to
|
@node User defined module data
|
||||||
include libltdl in the distribution of your package, for the convenience
|
@section Data associated with loaded modules
|
||||||
of users of your package that don't have libtool or libltdl installed.
|
|
||||||
In this case, you must decide whether to manually add the @code{ltdl}
|
|
||||||
objects to your package, or else which flavor of libltdl you want to use:
|
|
||||||
a convenience library or an installable libtool library.
|
|
||||||
|
|
||||||
The most simplistic way to add @code{libltdl} to your package is to copy
|
Some of the internal information about each loaded module that is
|
||||||
the source files, @file{ltdl.c} and @file{ltdl.h}, to a source directory
|
maintained by libltdl is available to the user, in the form of this
|
||||||
withing your package and to build and link them along with the rest of
|
structure:
|
||||||
your sources. To help you do this, the m4 macros for autoconf are
|
|
||||||
available in @file{ltdl.m4}. You must ensure that they are available in
|
|
||||||
@file{aclocal.m4} before you run autoconf -- by appending the contents
|
|
||||||
of @file{ltdl.m4} to @file{acinclude.m4}, if you are using automake, or
|
|
||||||
to @file{aclocal.m4} if you are not. Having made the macros available,
|
|
||||||
you must add a call to the @samp{AC_LIB_LTDL} macro to your package's
|
|
||||||
@file{configure.in} to perform the configure time checks required to
|
|
||||||
build @file{ltdl.o} correctly. This method has problems if you then try
|
|
||||||
to link the package binaries with an installed libltdl, or a library
|
|
||||||
which depends on libltdl: you may have problems with duplicate symbol
|
|
||||||
definitions.
|
|
||||||
|
|
||||||
One advantage of the convenience library is that it is not installed, so
|
@deftypefn {Type} {struct} lt_dlinfo @{ @w{char *@var{filename};} @w{char *@var{name};} @w{int @var{ref_count};} @}
|
||||||
the fact that you use libltdl will not be apparent to the user, and it
|
@code{lt_dlinfo} is used to store information about a module.
|
||||||
will not overwrite a pre-installed version of libltdl a user might have.
|
The @var{filename} attribute is a null-terminated character string of
|
||||||
On the other hand, if you want to upgrade libltdl for any reason
|
the real module file name. If the module is a libtool module then
|
||||||
(e.g. a bugfix) you'll have to recompile your package instead of just
|
@var{name} is its module name (e.g. @code{"libfoo"} for
|
||||||
replacing an installed version of libltdl.
|
@code{"dir/libfoo.la"}), otherwise it is set to @code{NULL}. The
|
||||||
However, if your programs or libraries are linked with other libraries
|
@var{ref_count} attribute is a reference counter that describes how
|
||||||
that use such a pre-installed version of libltdl, you may get linker
|
often the same module is currently loaded.
|
||||||
errors or run-time crashes. Another problem is that you cannot link the
|
@end deftypefn
|
||||||
convenience library into more than one libtool library, then link a
|
|
||||||
single program with these libraries, because you may get duplicate
|
|
||||||
symbols. In general you can safely use the convenience library in programs
|
|
||||||
which don't depend on other libraries that might use libltdl too.
|
|
||||||
In order to enable this flavor of libltdl, you should add the
|
|
||||||
line @samp{AC_LIBLTDL_CONVENIENCE} to your @file{configure.in},
|
|
||||||
@emph{before} @samp{AC_PROG_LIBTOOL}.
|
|
||||||
|
|
||||||
In order to select the installable version of libltdl, you should add a
|
The following function will return a pointer to libltdl's internal copy
|
||||||
call of the macro @samp{AC_LIBLTDL_INSTALLABLE} to your
|
of this structure for the given @var{handle}:
|
||||||
@file{configure.in} @emph{before} @samp{AC_PROG_LIBTOOL}. This macro
|
|
||||||
will check whether libltdl is already installed and, if not, request the
|
|
||||||
libltdl embedded in your package to be built and installed. Note,
|
|
||||||
however, that no version checking is performed. The user may override
|
|
||||||
the test and determine that the libltdl embedded must be installed,
|
|
||||||
regardless of the existence of another version, using the configure
|
|
||||||
switch @samp{--enable-ltdl-install}.
|
|
||||||
|
|
||||||
In order to embed libltdl into your package, just add @samp{--ltdl} to
|
@deftypefun {const lt_dlinfo *} lt_dlgetinfo (@w{lt_dlhandle @var{handle}})
|
||||||
the @code{libtoolize} command line. It will copy the libltdl sources
|
Return a pointer to a struct that contains some information about
|
||||||
to a subdirectory @samp{libltdl} in your package.
|
the module @var{handle}. The contents of the struct must not be modified.
|
||||||
Both macros accept an optional argument to specify the location
|
Return @code{NULL} on failure.
|
||||||
of the @samp{libltdl} directory. By the default both macros assume that it
|
@end deftypefun
|
||||||
is @samp{$@{top_srcdir@}/libltdl}.
|
|
||||||
|
|
||||||
Whatever macro you use, it is up to you to ensure that your
|
Furthermore, in order to save you from having to keep a list of the
|
||||||
@file{configure.in} will configure libltdl, using
|
handles of all the modules you have loaded, this function will supply
|
||||||
@samp{AC_CONFIG_SUBDIRS}, and that your @file{Makefile}s will start
|
the @var{handle} for each loaded module to a given callback:
|
||||||
sub-makes within libltdl's directory, using automake's @var{SUBDIRS},
|
|
||||||
for example. Both macros define the shell variables @var{LIBLTDL}, to
|
|
||||||
the link flag that you should use to link with libltdl, and
|
|
||||||
@var{INCLTDL}, to the preprocessor flag that you should use to compile
|
|
||||||
with programs that include @file{ltdl.h}. It is up to you to use
|
|
||||||
@samp{AC_SUBST} to ensure that this variable will be available in
|
|
||||||
@file{Makefile}s, or add them to variables that are @samp{AC_SUBST}ed by
|
|
||||||
default, such as @var{LIBS} and @var{CPPFLAGS}.
|
|
||||||
|
|
||||||
If you're using the convenience libltdl, @var{LIBLTDL} will be the
|
@deftypefun int lt_dlforeach (@w{int (*@var{func}) (lt_dlhandle @var{handle}, lt_ptr @var{data})}, @w{lt_ptr @var{data}})
|
||||||
pathname for the convenience version of libltdl and @var{INCLTDL} will be
|
For each loaded module call the function @var{func}. The argument
|
||||||
@samp{-I} followed by the directory that contains libltdl, both starting
|
@var{handle} is the handle of one of the loaded modules, @var{data} is
|
||||||
with @samp{$@{top_builddir@}/} or @samp{$@{top_srcdir@}/}, respectively.
|
the @var{data} argument passed to @code{lt_dlforeach}.
|
||||||
|
As soon as @var{func} returns a non-zero value for one of the handles,
|
||||||
|
@code{lt_dlforeach} will stop calling @var{func} and immediately return 1.
|
||||||
|
Otherwise 0 is returned.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
If you request an installed version of libltdl and one is
|
Of course, you would still need to maintain your own list of loaded
|
||||||
found@footnote{Even if libltdl is installed,
|
module handles to parallel the list maintained by libltdl if there are
|
||||||
@samp{AC_LIBLTDL_INSTALLABLE} may fail to detect it, if libltdl depends
|
any other data that you need to associate with each handle for the
|
||||||
on symbols provided by libraries other than the C library. In this
|
purposes of your application. However, if you use the following
|
||||||
case, it will needlessly build and install libltdl.}, @var{LIBLTDL} will
|
@sc{api} calls to associate your application data with individual module
|
||||||
be set to @samp{-lltdl} and @var{INCLTDL} will be empty (which is just a
|
handles as they are loaded there is actually no need to do that. You
|
||||||
blind assumption that @file{ltdl.h} is somewhere in the include path if
|
must first obtain a unique caller id from libltdl which you subsequently
|
||||||
libltdl is in the library path). If an installable version of libltdl
|
use to retrieve the data you stored earlier. This allows for different
|
||||||
must be built, its pathname, starting with @samp{$@{top_builddir@}/},
|
libraries that each wish to store their own data against loaded modules
|
||||||
will be stored in @var{LIBLTDL}, and @var{INCLTDL} will be set just like
|
to do so without interfering with one another's data.
|
||||||
in the case of convenience library.
|
|
||||||
|
|
||||||
So, when you want to link a program with libltdl, be it a convenience,
|
@deftp {Type} lt_dlcaller_id
|
||||||
installed or installable library, just compile with @samp{$(INCLTDL)}
|
The opaque type used to hold individual data set keys.
|
||||||
and link it with @samp{$(LIBLTDL)}, using libtool.
|
@end deftp
|
||||||
|
|
||||||
You should probably also add @samp{AC_LIBTOOL_DLOPEN} to your
|
@deftypefun lt_dlcaller_id lt_dlcaller_register (void)
|
||||||
@file{configure.in} @emph{before} @samp{AC_PROG_LIBTOOL}, otherwise
|
Use this to obtain a unique key to store and retrieve individual sets of
|
||||||
libtool will assume no dlopening mechanism is supported, and revert to
|
per module data.
|
||||||
dlpreopening, which is probably not what you want.
|
@end deftypefun
|
||||||
|
|
||||||
Avoid using the @code{-static} or @code{-all-static} switches when
|
@deftypefun lt_ptr lt_dlcaller_set_data (@w{lt_dlcaller_id @var{key}}, @w{lt_dlhandle @var{handle}}, @w{lt_ptr @var{data}})
|
||||||
linking programs with libltdl. This will not work on all platforms,
|
Set @var{data} as the set of data uniquely associated with @var{key} and
|
||||||
because the dlopening functions may not be available for static linking.
|
@var{handle} for later retrieval. This function returns the @var{data}
|
||||||
|
previously associated with @var{key} and @var{handle} if any. A result of
|
||||||
|
0, may indicate that a diagnostic for the last error (if any) is available
|
||||||
|
from @code{lt_dlerror()}.
|
||||||
|
|
||||||
The following example shows you how to embed the convenience libltdl in
|
For example, to correctly remove some associated data:
|
||||||
your package. In order to use the installable variant just replace
|
|
||||||
@samp{AC_LIBLTDL_CONVENIENCE} with @samp{AC_LIBLTDL_INSTALLABLE}. We
|
|
||||||
assume that libltdl was embedded using @samp{libtoolize --ltdl}.
|
|
||||||
|
|
||||||
configure.in:
|
|
||||||
@example
|
@example
|
||||||
...
|
lt_ptr stale = lt_dlcaller_set_data (key, handle, 0);
|
||||||
dnl Enable building of the convenience library
|
if (stale == NULL)
|
||||||
dnl and set LIBLTDL accordingly
|
@{
|
||||||
AC_LIBLTDL_CONVENIENCE
|
char *error_msg = lt_dlerror ();
|
||||||
dnl Substitute INCLTDL and LIBLTDL in the Makefiles
|
|
||||||
AC_SUBST(INCLTDL)
|
if (error_msg != NULL)
|
||||||
AC_SUBST(LIBLTDL)
|
@{
|
||||||
dnl Check for dlopen support
|
my_error_handler (error_msg);
|
||||||
AC_LIBTOOL_DLOPEN
|
return STATUS_FAILED;
|
||||||
dnl Configure libtool
|
@}
|
||||||
AC_PROG_LIBTOOL
|
@}
|
||||||
dnl Configure libltdl
|
else
|
||||||
AC_CONFIG_SUBDIRS(libltdl)
|
@{
|
||||||
...
|
free (stale);
|
||||||
|
@}
|
||||||
|
@end example
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun lt_ptr lt_dlcaller_get_data (@w{lt_dlcaller_id @var{key}}, @w{lt_dlhandle @var{handle}})
|
||||||
|
Return the address of the data associated with @var{key} and
|
||||||
|
@var{handle}, or else @code{NULL} if there is none.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
The preceding functions can be combined with @code{lt_dlforeach} to
|
||||||
|
implement search and apply operations without the need for your
|
||||||
|
application to track the modules that have been loaded and unloaded:
|
||||||
|
|
||||||
|
@example
|
||||||
|
int
|
||||||
|
my_dlcaller_callback (lt_dlhandle handle, lt_ptr key_ptr)
|
||||||
|
@{
|
||||||
|
struct my_module_data *my_data;
|
||||||
|
|
||||||
|
my_data = lt_dlcaller_get_data (handle, (lt_dlcaller_id) *key_ptr);
|
||||||
|
|
||||||
|
return process (my_data);
|
||||||
|
@}
|
||||||
|
|
||||||
|
int
|
||||||
|
my_dlcaller_foreach (lt_dlcaller_id key)
|
||||||
|
@{
|
||||||
|
lt_dlforeach (my_dlcaller_callback, (lt_ptr) &key);
|
||||||
|
@}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Makefile.am:
|
|
||||||
@example
|
|
||||||
...
|
|
||||||
SUBDIRS = libltdl
|
|
||||||
|
|
||||||
INCLUDES = $(INCLTDL)
|
|
||||||
|
|
||||||
myprog_LDFLAGS = -export-dynamic
|
|
||||||
# The quotes around -dlopen below fool automake <= 1.4 into accepting it
|
|
||||||
myprog_LDADD = $(LIBLTDL) "-dlopen" self "-dlopen" foo1.la
|
|
||||||
myprog_DEPENDENCIES = $(LIBLTDL) foo1.la
|
|
||||||
...
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@node Module loaders for libltdl
|
@node Module loaders for libltdl
|
||||||
@section How to create and register new module loaders
|
@section How to create and register new module loaders
|
||||||
@ -3337,6 +3292,144 @@ if (lt_dlseterror (LTDL_ERROR_NO_MEMORY) != 0)
|
|||||||
@end example
|
@end example
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
|
@node Distributing libltdl
|
||||||
|
@section How to distribute libltdl with your package
|
||||||
|
|
||||||
|
Even though libltdl is installed together with libtool, you may wish to
|
||||||
|
include libltdl in the distribution of your package, for the convenience
|
||||||
|
of users of your package that don't have libtool or libltdl installed.
|
||||||
|
In this case, you must decide whether to manually add the @code{ltdl}
|
||||||
|
objects to your package, or else which flavor of libltdl you want to use:
|
||||||
|
a convenience library or an installable libtool library.
|
||||||
|
|
||||||
|
The most simplistic way to add @code{libltdl} to your package is to copy
|
||||||
|
the source files, @file{ltdl.c} and @file{ltdl.h}, to a source directory
|
||||||
|
withing your package and to build and link them along with the rest of
|
||||||
|
your sources. To help you do this, the m4 macros for autoconf are
|
||||||
|
available in @file{ltdl.m4}. You must ensure that they are available in
|
||||||
|
@file{aclocal.m4} before you run autoconf -- by appending the contents
|
||||||
|
of @file{ltdl.m4} to @file{acinclude.m4}, if you are using automake, or
|
||||||
|
to @file{aclocal.m4} if you are not. Having made the macros available,
|
||||||
|
you must add a call to the @samp{AC_LIB_LTDL} macro to your package's
|
||||||
|
@file{configure.in} to perform the configure time checks required to
|
||||||
|
build @file{ltdl.o} correctly. This method has problems if you then try
|
||||||
|
to link the package binaries with an installed libltdl, or a library
|
||||||
|
which depends on libltdl: you may have problems with duplicate symbol
|
||||||
|
definitions.
|
||||||
|
|
||||||
|
One advantage of the convenience library is that it is not installed, so
|
||||||
|
the fact that you use libltdl will not be apparent to the user, and it
|
||||||
|
will not overwrite a pre-installed version of libltdl a user might have.
|
||||||
|
On the other hand, if you want to upgrade libltdl for any reason
|
||||||
|
(e.g. a bugfix) you'll have to recompile your package instead of just
|
||||||
|
replacing an installed version of libltdl.
|
||||||
|
However, if your programs or libraries are linked with other libraries
|
||||||
|
that use such a pre-installed version of libltdl, you may get linker
|
||||||
|
errors or run-time crashes. Another problem is that you cannot link the
|
||||||
|
convenience library into more than one libtool library, then link a
|
||||||
|
single program with these libraries, because you may get duplicate
|
||||||
|
symbols. In general you can safely use the convenience library in programs
|
||||||
|
which don't depend on other libraries that might use libltdl too.
|
||||||
|
In order to enable this flavor of libltdl, you should add the
|
||||||
|
line @samp{AC_LIBLTDL_CONVENIENCE} to your @file{configure.in},
|
||||||
|
@emph{before} @samp{AC_PROG_LIBTOOL}.
|
||||||
|
|
||||||
|
In order to select the installable version of libltdl, you should add a
|
||||||
|
call of the macro @samp{AC_LIBLTDL_INSTALLABLE} to your
|
||||||
|
@file{configure.in} @emph{before} @samp{AC_PROG_LIBTOOL}. This macro
|
||||||
|
will check whether libltdl is already installed and, if not, request the
|
||||||
|
libltdl embedded in your package to be built and installed. Note,
|
||||||
|
however, that no version checking is performed. The user may override
|
||||||
|
the test and determine that the libltdl embedded must be installed,
|
||||||
|
regardless of the existence of another version, using the configure
|
||||||
|
switch @samp{--enable-ltdl-install}.
|
||||||
|
|
||||||
|
In order to embed libltdl into your package, just add @samp{--ltdl} to
|
||||||
|
the @code{libtoolize} command line. It will copy the libltdl sources
|
||||||
|
to a subdirectory @samp{libltdl} in your package.
|
||||||
|
Both macros accept an optional argument to specify the location
|
||||||
|
of the @samp{libltdl} directory. By the default both macros assume that it
|
||||||
|
is @samp{$@{top_srcdir@}/libltdl}.
|
||||||
|
|
||||||
|
Whatever macro you use, it is up to you to ensure that your
|
||||||
|
@file{configure.in} will configure libltdl, using
|
||||||
|
@samp{AC_CONFIG_SUBDIRS}, and that your @file{Makefile}s will start
|
||||||
|
sub-makes within libltdl's directory, using automake's @var{SUBDIRS},
|
||||||
|
for example. Both macros define the shell variables @var{LIBLTDL}, to
|
||||||
|
the link flag that you should use to link with libltdl, and
|
||||||
|
@var{INCLTDL}, to the preprocessor flag that you should use to compile
|
||||||
|
with programs that include @file{ltdl.h}. It is up to you to use
|
||||||
|
@samp{AC_SUBST} to ensure that this variable will be available in
|
||||||
|
@file{Makefile}s, or add them to variables that are @samp{AC_SUBST}ed by
|
||||||
|
default, such as @var{LIBS} and @var{CPPFLAGS}.
|
||||||
|
|
||||||
|
If you're using the convenience libltdl, @var{LIBLTDL} will be the
|
||||||
|
pathname for the convenience version of libltdl and @var{INCLTDL} will be
|
||||||
|
@samp{-I} followed by the directory that contains libltdl, both starting
|
||||||
|
with @samp{$@{top_builddir@}/} or @samp{$@{top_srcdir@}/}, respectively.
|
||||||
|
|
||||||
|
If you request an installed version of libltdl and one is
|
||||||
|
found@footnote{Even if libltdl is installed,
|
||||||
|
@samp{AC_LIBLTDL_INSTALLABLE} may fail to detect it, if libltdl depends
|
||||||
|
on symbols provided by libraries other than the C library. In this
|
||||||
|
case, it will needlessly build and install libltdl.}, @var{LIBLTDL} will
|
||||||
|
be set to @samp{-lltdl} and @var{INCLTDL} will be empty (which is just a
|
||||||
|
blind assumption that @file{ltdl.h} is somewhere in the include path if
|
||||||
|
libltdl is in the library path). If an installable version of libltdl
|
||||||
|
must be built, its pathname, starting with @samp{$@{top_builddir@}/},
|
||||||
|
will be stored in @var{LIBLTDL}, and @var{INCLTDL} will be set just like
|
||||||
|
in the case of convenience library.
|
||||||
|
|
||||||
|
So, when you want to link a program with libltdl, be it a convenience,
|
||||||
|
installed or installable library, just compile with @samp{$(INCLTDL)}
|
||||||
|
and link it with @samp{$(LIBLTDL)}, using libtool.
|
||||||
|
|
||||||
|
You should probably also add @samp{AC_LIBTOOL_DLOPEN} to your
|
||||||
|
@file{configure.in} @emph{before} @samp{AC_PROG_LIBTOOL}, otherwise
|
||||||
|
libtool will assume no dlopening mechanism is supported, and revert to
|
||||||
|
dlpreopening, which is probably not what you want.
|
||||||
|
|
||||||
|
Avoid using the @code{-static} or @code{-all-static} switches when
|
||||||
|
linking programs with libltdl. This will not work on all platforms,
|
||||||
|
because the dlopening functions may not be available for static linking.
|
||||||
|
|
||||||
|
The following example shows you how to embed the convenience libltdl in
|
||||||
|
your package. In order to use the installable variant just replace
|
||||||
|
@samp{AC_LIBLTDL_CONVENIENCE} with @samp{AC_LIBLTDL_INSTALLABLE}. We
|
||||||
|
assume that libltdl was embedded using @samp{libtoolize --ltdl}.
|
||||||
|
|
||||||
|
configure.in:
|
||||||
|
@example
|
||||||
|
...
|
||||||
|
dnl Enable building of the convenience library
|
||||||
|
dnl and set LIBLTDL accordingly
|
||||||
|
AC_LIBLTDL_CONVENIENCE
|
||||||
|
dnl Substitute INCLTDL and LIBLTDL in the Makefiles
|
||||||
|
AC_SUBST(INCLTDL)
|
||||||
|
AC_SUBST(LIBLTDL)
|
||||||
|
dnl Check for dlopen support
|
||||||
|
AC_LIBTOOL_DLOPEN
|
||||||
|
dnl Configure libtool
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
dnl Configure libltdl
|
||||||
|
AC_CONFIG_SUBDIRS(libltdl)
|
||||||
|
...
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Makefile.am:
|
||||||
|
@example
|
||||||
|
...
|
||||||
|
SUBDIRS = libltdl
|
||||||
|
|
||||||
|
INCLUDES = $(INCLTDL)
|
||||||
|
|
||||||
|
myprog_LDFLAGS = -export-dynamic
|
||||||
|
# The quotes around -dlopen below fool automake <= 1.4 into accepting it
|
||||||
|
myprog_LDADD = $(LIBLTDL) "-dlopen" self "-dlopen" foo1.la
|
||||||
|
myprog_DEPENDENCIES = $(LIBLTDL) foo1.la
|
||||||
|
...
|
||||||
|
@end example
|
||||||
|
|
||||||
@node Other languages
|
@node Other languages
|
||||||
@chapter Using libtool with other languages
|
@chapter Using libtool with other languages
|
||||||
@cindex C, not using
|
@cindex C, not using
|
||||||
|
395
libltdl/ltdl.c
395
libltdl/ltdl.c
@ -98,6 +98,20 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|||||||
#undef LT_SYMBOL_OVERHEAD
|
#undef LT_SYMBOL_OVERHEAD
|
||||||
#define LT_SYMBOL_OVERHEAD 5
|
#define LT_SYMBOL_OVERHEAD 5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* --- TYPE DEFINITIONS -- */
|
||||||
|
|
||||||
|
|
||||||
|
/* This type is used for the array of caller data sets in each handler. */
|
||||||
|
typedef struct {
|
||||||
|
lt_dlcaller_id key;
|
||||||
|
lt_ptr data;
|
||||||
|
} lt_caller_data;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
|
/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
|
||||||
|
|
||||||
@ -122,6 +136,7 @@ struct lt_dlhandle_struct {
|
|||||||
lt_dlhandle *deplibs; /* dependencies */
|
lt_dlhandle *deplibs; /* dependencies */
|
||||||
lt_module module; /* system module handle */
|
lt_module module; /* system module handle */
|
||||||
lt_ptr system; /* system specific data */
|
lt_ptr system; /* system specific data */
|
||||||
|
lt_caller_data *caller_data; /* per caller associated data */
|
||||||
int flags; /* various boolean stats */
|
int flags; /* various boolean stats */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,11 +159,29 @@ static const char shlib_ext[] = LTDL_SHLIB_EXT;
|
|||||||
static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
|
static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* --- MEMORY HANDLING --- */
|
||||||
|
|
||||||
|
|
||||||
LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size))
|
LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size))
|
||||||
= (lt_ptr (*) LT_PARAMS((size_t))) malloc;
|
= (lt_ptr (*) LT_PARAMS((size_t))) malloc;
|
||||||
LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr))
|
LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr))
|
||||||
= (void (*) LT_PARAMS((lt_ptr))) free;
|
= (void (*) LT_PARAMS((lt_ptr))) free;
|
||||||
|
|
||||||
|
static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr,
|
||||||
|
size_t size));
|
||||||
|
|
||||||
|
#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
|
||||||
|
#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
|
||||||
|
#define LT_DLFREE(p) \
|
||||||
|
LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
|
||||||
|
|
||||||
|
#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
|
||||||
|
if ((p) != (q)) { lt_dlfree (p); (p) = (q); } \
|
||||||
|
} LT_STMT_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* --- ERROR MESSAGES --- */
|
/* --- ERROR MESSAGES --- */
|
||||||
@ -177,26 +210,20 @@ lt_dladderror (diagnostic)
|
|||||||
const char *diagnostic;
|
const char *diagnostic;
|
||||||
{
|
{
|
||||||
int index = errorcode - LT_ERROR_MAX;
|
int index = errorcode - LT_ERROR_MAX;
|
||||||
const char **temp = 0;
|
const char **temp = 0;
|
||||||
|
|
||||||
/* realloc is not entirely portable, so simulate it using
|
temp = LT_DLREALLOC (const char *, user_error_strings, 1 + index);
|
||||||
lt_dlmalloc and lt_dlfree. */
|
|
||||||
temp = (const char **) lt_dlmalloc ((1+index) * sizeof (const char*));
|
|
||||||
if (temp == 0)
|
if (temp == 0)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Build the new vector in the memory addressed by temp. */
|
|
||||||
temp[index] = diagnostic;
|
|
||||||
while (--index >= 0)
|
|
||||||
{
|
{
|
||||||
temp[index] = user_error_strings[index];
|
user_error_strings = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
lt_dlfree (user_error_strings);
|
user_error_strings[index] = diagnostic;
|
||||||
user_error_strings = temp;
|
|
||||||
|
|
||||||
return errorcode++;
|
return errorcode++;
|
||||||
}
|
}
|
||||||
@ -240,7 +267,7 @@ strdup(str)
|
|||||||
|
|
||||||
if (str)
|
if (str)
|
||||||
{
|
{
|
||||||
tmp = (char*) lt_dlmalloc (1+ strlen (str));
|
tmp = LT_DLMALLOC (char, 1+ strlen (str));
|
||||||
if (tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
strcpy(tmp, str);
|
strcpy(tmp, str);
|
||||||
@ -330,6 +357,78 @@ strrchr(str, ch)
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* NOTE: Neither bcopy nor the memcpy implementation below can
|
||||||
|
reliably handle copying in overlapping areas of memory, so
|
||||||
|
do not rely on this behaviour when invoking memcpy later. */
|
||||||
|
#if ! HAVE_MEMCPY
|
||||||
|
|
||||||
|
# if HAVE_BCOPY
|
||||||
|
# define memcpy(dest, src, size) bcopy (src, dest, size)
|
||||||
|
# else
|
||||||
|
# define memcpy rpl_memcpy
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
memcpy (dest, src, size)
|
||||||
|
char *dest;
|
||||||
|
const char *src;
|
||||||
|
size_t size;
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
dest[i] = src[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
|
||||||
|
``realloc is not entirely portable''
|
||||||
|
In any case we want to use the allocator supplied by the user without
|
||||||
|
burdening them with an lt_dlrealloc function pointer to maintain.
|
||||||
|
Instead implement our own version (with known boundary conditions)
|
||||||
|
using lt_dlmalloc and lt_dlfree. */
|
||||||
|
static lt_ptr
|
||||||
|
rpl_realloc (ptr, size)
|
||||||
|
lt_ptr ptr;
|
||||||
|
size_t size;
|
||||||
|
{
|
||||||
|
if (size < 1)
|
||||||
|
{
|
||||||
|
/* For zero or less bytes, free the original memory */
|
||||||
|
if (ptr != 0)
|
||||||
|
{
|
||||||
|
lt_dlfree (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (lt_ptr) 0;
|
||||||
|
}
|
||||||
|
else if (ptr == 0)
|
||||||
|
{
|
||||||
|
/* Allow reallocation of a NULL pointer. */
|
||||||
|
return lt_dlmalloc (size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Allocate a new block, copy and free the old block. */
|
||||||
|
lt_ptr mem = lt_dlmalloc (size);
|
||||||
|
|
||||||
|
if (mem)
|
||||||
|
{
|
||||||
|
memcpy (mem, ptr, size);
|
||||||
|
lt_dlfree (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note that the contents of PTR are not damaged if there is
|
||||||
|
insufficient memory to realloc. */
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -600,7 +699,7 @@ sys_wll_open (loader_data, filename)
|
|||||||
{
|
{
|
||||||
/* Append a `.' to stop Windows from adding an
|
/* Append a `.' to stop Windows from adding an
|
||||||
implicit `.dll' extension. */
|
implicit `.dll' extension. */
|
||||||
searchname = (char*) lt_dlmalloc (2+ strlen (filename));
|
searchname = LT_DLMALLOC (char, 2+ strlen (filename));
|
||||||
if (!searchname)
|
if (!searchname)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -611,7 +710,7 @@ sys_wll_open (loader_data, filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
module = LoadLibrary (searchname);
|
module = LoadLibrary (searchname);
|
||||||
lt_dlfree (searchname);
|
LT_DLFREE (searchname);
|
||||||
|
|
||||||
/* libltdl expects this function to fail if it is unable
|
/* libltdl expects this function to fail if it is unable
|
||||||
to physically load the library. Sadly, LoadLibrary
|
to physically load the library. Sadly, LoadLibrary
|
||||||
@ -791,7 +890,7 @@ sys_dld_open (loader_data, filename)
|
|||||||
if (dld_link (filename) != 0)
|
if (dld_link (filename) != 0)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (CANNOT_OPEN);
|
last_error = LT_DLSTRERROR (CANNOT_OPEN);
|
||||||
lt_dlfree(module);
|
LT_DLFREE (module);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,7 +907,7 @@ sys_dld_close (loader_data, module)
|
|||||||
last_error = LT_DLSTRERROR (CANNOT_CLOSE);
|
last_error = LT_DLSTRERROR (CANNOT_CLOSE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lt_dlfree (module);
|
LT_DLFREE (module);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -876,7 +975,7 @@ presym_free_symlists ()
|
|||||||
lt_dlsymlists_t *tmp = lists;
|
lt_dlsymlists_t *tmp = lists;
|
||||||
|
|
||||||
lists = lists->next;
|
lists = lists->next;
|
||||||
lt_dlfree (tmp);
|
LT_DLFREE (tmp);
|
||||||
}
|
}
|
||||||
preloaded_symbols = 0;
|
preloaded_symbols = 0;
|
||||||
|
|
||||||
@ -907,7 +1006,7 @@ presym_add_symlist (preloaded)
|
|||||||
lists = lists->next;
|
lists = lists->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = (lt_dlsymlists_t*) lt_dlmalloc (sizeof (lt_dlsymlists_t));
|
tmp = LT_DLMALLOC (lt_dlsymlists_t, 1);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -1135,8 +1234,7 @@ lt_dlexit ()
|
|||||||
++errors;
|
++errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
lt_dlfree (loader);
|
LT_DLMEM_REASSIGN (loader, next);
|
||||||
loader = next;
|
|
||||||
}
|
}
|
||||||
loaders = 0;
|
loaders = 0;
|
||||||
}
|
}
|
||||||
@ -1208,10 +1306,7 @@ tryall_dlopen (handle, filename)
|
|||||||
|
|
||||||
if (!loader)
|
if (!loader)
|
||||||
{
|
{
|
||||||
if (cur->info.filename)
|
LT_DLFREE (cur->info.filename);
|
||||||
{
|
|
||||||
lt_dlfree(cur->info.filename);
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1250,7 +1345,7 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
|
|||||||
if (installed && libdir)
|
if (installed && libdir)
|
||||||
{
|
{
|
||||||
len = strlen (libdir) + 1 + strlen (dlname);
|
len = strlen (libdir) + 1 + strlen (dlname);
|
||||||
filename = (char*) lt_dlmalloc (1+ len);
|
filename = LT_DLMALLOC (char, 1+ len);
|
||||||
|
|
||||||
if (!filename)
|
if (!filename)
|
||||||
{
|
{
|
||||||
@ -1260,7 +1355,7 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
|
|||||||
|
|
||||||
sprintf (filename, "%s/%s", libdir, dlname);
|
sprintf (filename, "%s/%s", libdir, dlname);
|
||||||
error = (tryall_dlopen (handle, filename) != 0);
|
error = (tryall_dlopen (handle, filename) != 0);
|
||||||
lt_dlfree (filename);
|
LT_DLFREE (filename);
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
@ -1272,7 +1367,7 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
|
|||||||
if (!installed)
|
if (!installed)
|
||||||
{
|
{
|
||||||
len = (dir ? strlen (dir) : 0) + strlen (objdir) + strlen (dlname);
|
len = (dir ? strlen (dir) : 0) + strlen (objdir) + strlen (dlname);
|
||||||
filename = (char*) lt_dlmalloc(1+ len);
|
filename = LT_DLMALLOC (char, 1+ len);
|
||||||
|
|
||||||
if (!filename)
|
if (!filename)
|
||||||
{
|
{
|
||||||
@ -1292,7 +1387,7 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
|
|||||||
strcat(filename, dlname);
|
strcat(filename, dlname);
|
||||||
|
|
||||||
error = tryall_dlopen (handle, filename) != 0;
|
error = tryall_dlopen (handle, filename) != 0;
|
||||||
lt_dlfree (filename);
|
LT_DLFREE (filename);
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -1302,7 +1397,7 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
|
|||||||
/* maybe it was moved to another directory */
|
/* maybe it was moved to another directory */
|
||||||
{
|
{
|
||||||
len = (dir ? strlen (dir) : 0) + strlen (dlname);
|
len = (dir ? strlen (dir) : 0) + strlen (dlname);
|
||||||
filename = (char*) lt_dlmalloc (1+ len);
|
filename = LT_DLMALLOC (char, 1+ len);
|
||||||
|
|
||||||
if (dir)
|
if (dir)
|
||||||
{
|
{
|
||||||
@ -1315,7 +1410,7 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
|
|||||||
strcat(filename, dlname);
|
strcat(filename, dlname);
|
||||||
|
|
||||||
error = (tryall_dlopen (handle, filename) != 0);
|
error = (tryall_dlopen (handle, filename) != 0);
|
||||||
lt_dlfree (filename);
|
LT_DLFREE (filename);
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -1408,13 +1503,9 @@ find_file (basename, search_path, pdir, handle)
|
|||||||
|
|
||||||
if (lendir + 1 + lenbase >= filenamesize)
|
if (lendir + 1 + lenbase >= filenamesize)
|
||||||
{
|
{
|
||||||
if (filename)
|
LT_DLFREE (filename);
|
||||||
{
|
|
||||||
lt_dlfree (filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
filenamesize = lendir + 1 + lenbase + 1;
|
filenamesize = lendir + 1 + lenbase + 1;
|
||||||
filename = (char*) lt_dlmalloc(filenamesize);
|
filename = LT_DLMALLOC (char, filenamesize);
|
||||||
|
|
||||||
if (!filename)
|
if (!filename)
|
||||||
{
|
{
|
||||||
@ -1442,10 +1533,7 @@ find_file (basename, search_path, pdir, handle)
|
|||||||
FILE *file = fopen (filename, LT_READTEXT_MODE);
|
FILE *file = fopen (filename, LT_READTEXT_MODE);
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
if (*pdir)
|
LT_DLFREE (*pdir);
|
||||||
{
|
|
||||||
lt_dlfree (*pdir);
|
|
||||||
}
|
|
||||||
|
|
||||||
filename[lendir] = '\0';
|
filename[lendir] = '\0';
|
||||||
*pdir = strdup(filename);
|
*pdir = strdup(filename);
|
||||||
@ -1466,8 +1554,8 @@ find_file (basename, search_path, pdir, handle)
|
|||||||
last_error = LT_DLSTRERROR (FILE_NOT_FOUND);
|
last_error = LT_DLSTRERROR (FILE_NOT_FOUND);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (filename) lt_dlfree (filename);
|
LT_DLFREE (filename);
|
||||||
if (canonical) lt_dlfree (canonical);
|
LT_DLFREE (canonical);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1537,13 +1625,13 @@ load_deplibs(handle, deplibs)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
names = (char**) lt_dlmalloc (depcount * sizeof (char*));
|
names = LT_DLMALLOC (char *, depcount * sizeof (char*));
|
||||||
if (!names)
|
if (!names)
|
||||||
{
|
{
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
handles = (lt_dlhandle*) lt_dlmalloc (depcount * sizeof (lt_dlhandle*));
|
handles = (lt_dlhandle*) LT_DLMALLOC (lt_dlhandle *, depcount);
|
||||||
if (!handles)
|
if (!handles)
|
||||||
{
|
{
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -1572,8 +1660,7 @@ load_deplibs(handle, deplibs)
|
|||||||
*end = 0; /* set a temporary string terminator */
|
*end = 0; /* set a temporary string terminator */
|
||||||
if (strncmp(p, "-l", 2) == 0)
|
if (strncmp(p, "-l", 2) == 0)
|
||||||
{
|
{
|
||||||
name = lt_dlmalloc(3+ /* "lib" */
|
name = LT_DLMALLOC (char, 3+ /* "lib" */ strlen (p+2) + 1);
|
||||||
strlen(p+2)+1);
|
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
sprintf (name, "lib%s", p+2);
|
sprintf (name, "lib%s", p+2);
|
||||||
@ -1625,15 +1712,15 @@ load_deplibs(handle, deplibs)
|
|||||||
cleanup_names:
|
cleanup_names:
|
||||||
for (i = 0; i < depcount; ++i)
|
for (i = 0; i < depcount; ++i)
|
||||||
{
|
{
|
||||||
lt_dlfree(names[i]);
|
LT_DLFREE (names[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (names) lt_dlfree(names);
|
LT_DLFREE (names);
|
||||||
if (handles) lt_dlfree(handles);
|
LT_DLFREE (handles);
|
||||||
|
|
||||||
/* restore the old search path */
|
/* restore the old search path */
|
||||||
if (user_search_path) lt_dlfree (user_search_path);
|
LT_DLFREE (user_search_path);
|
||||||
user_search_path = save_search_path;
|
user_search_path = save_search_path;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1671,14 +1758,11 @@ trim (dest, str)
|
|||||||
int len = strlen (str);
|
int len = strlen (str);
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
if (*dest)
|
LT_DLFREE (*dest);
|
||||||
{
|
|
||||||
lt_dlfree(*dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 3 && str[0] == '\'')
|
if (len > 3 && str[0] == '\'')
|
||||||
{
|
{
|
||||||
tmp = (char*) lt_dlmalloc(end - str);
|
tmp = LT_DLMALLOC (char, end - str);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -1704,10 +1788,10 @@ free_vars( dlname, oldname, libdir, deplibs)
|
|||||||
char *libdir;
|
char *libdir;
|
||||||
char *deplibs;
|
char *deplibs;
|
||||||
{
|
{
|
||||||
if (dlname) lt_dlfree(dlname);
|
LT_DLFREE (dlname);
|
||||||
if (oldname) lt_dlfree(oldname);
|
LT_DLFREE (oldname);
|
||||||
if (libdir) lt_dlfree(libdir);
|
LT_DLFREE (libdir);
|
||||||
if (deplibs) lt_dlfree(deplibs);
|
LT_DLFREE (deplibs);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1724,7 +1808,7 @@ lt_dlopen (filename)
|
|||||||
/* dlopen self? */
|
/* dlopen self? */
|
||||||
if (!filename)
|
if (!filename)
|
||||||
{
|
{
|
||||||
handle = (lt_dlhandle) lt_dlmalloc (sizeof (struct lt_dlhandle_struct));
|
handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
|
||||||
if (!handle)
|
if (!handle)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -1734,6 +1818,7 @@ lt_dlopen (filename)
|
|||||||
handle->info.ref_count = 0;
|
handle->info.ref_count = 0;
|
||||||
handle->depcount = 0;
|
handle->depcount = 0;
|
||||||
handle->deplibs = 0;
|
handle->deplibs = 0;
|
||||||
|
handle->caller_data = 0;
|
||||||
newhandle = handle;
|
newhandle = handle;
|
||||||
|
|
||||||
/* lt_dlclose()ing yourself is very bad! Disallow it. */
|
/* lt_dlclose()ing yourself is very bad! Disallow it. */
|
||||||
@ -1741,7 +1826,7 @@ lt_dlopen (filename)
|
|||||||
|
|
||||||
if (tryall_dlopen (&newhandle, 0) != 0)
|
if (tryall_dlopen (&newhandle, 0) != 0)
|
||||||
{
|
{
|
||||||
lt_dlfree(handle);
|
LT_DLFREE (handle);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
goto register_handle;
|
goto register_handle;
|
||||||
@ -1751,10 +1836,7 @@ lt_dlopen (filename)
|
|||||||
if (!canonical)
|
if (!canonical)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
if (handle)
|
LT_DLFREE (handle);
|
||||||
{
|
|
||||||
lt_dlfree(handle);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1764,7 +1846,7 @@ lt_dlopen (filename)
|
|||||||
if (basename)
|
if (basename)
|
||||||
{
|
{
|
||||||
++basename;
|
++basename;
|
||||||
dir = (char*) lt_dlmalloc (basename - canonical + 1);
|
dir = LT_DLMALLOC (char, basename - canonical + 1);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -1798,7 +1880,7 @@ lt_dlopen (filename)
|
|||||||
int installed = 1;
|
int installed = 1;
|
||||||
|
|
||||||
/* extract the module name from the file name */
|
/* extract the module name from the file name */
|
||||||
name = (char*) lt_dlmalloc(ext - basename + 1);
|
name = LT_DLMALLOC (char, ext - basename + 1);
|
||||||
if (!name)
|
if (!name)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -1863,7 +1945,7 @@ lt_dlopen (filename)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
line = (char*) lt_dlmalloc (LT_FILENAME_MAX);
|
line = LT_DLMALLOC (char, LT_FILENAME_MAX);
|
||||||
if (!line)
|
if (!line)
|
||||||
{
|
{
|
||||||
fclose (file);
|
fclose (file);
|
||||||
@ -1933,8 +2015,7 @@ lt_dlopen (filename)
|
|||||||
(last_libname = strrchr (dlname, ' ')) != NULL)
|
(last_libname = strrchr (dlname, ' ')) != NULL)
|
||||||
{
|
{
|
||||||
last_libname = strdup (last_libname + 1);
|
last_libname = strdup (last_libname + 1);
|
||||||
lt_dlfree (dlname);
|
LT_DLMEM_REASSIGN (dlname, last_libname);
|
||||||
dlname = last_libname;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1945,16 +2026,13 @@ lt_dlopen (filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fclose (file);
|
fclose (file);
|
||||||
lt_dlfree (line);
|
LT_DLFREE (line);
|
||||||
|
|
||||||
/* allocate the handle */
|
/* allocate the handle */
|
||||||
handle = (lt_dlhandle) lt_dlmalloc (sizeof (struct lt_dlhandle_struct));
|
handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
|
||||||
if (!handle || error)
|
if (!handle || error)
|
||||||
{
|
{
|
||||||
if (handle)
|
LT_DLFREE (handle);
|
||||||
{
|
|
||||||
lt_dlfree(handle);
|
|
||||||
}
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -1984,8 +2062,7 @@ lt_dlopen (filename)
|
|||||||
free_vars (dlname, old_name, libdir, deplibs);
|
free_vars (dlname, old_name, libdir, deplibs);
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
lt_dlfree (handle);
|
LT_DLFREE (handle);
|
||||||
handle = 0;
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1997,7 +2074,7 @@ lt_dlopen (filename)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* not a libtool module */
|
/* not a libtool module */
|
||||||
handle = (lt_dlhandle) lt_dlmalloc (sizeof (struct lt_dlhandle_struct));
|
handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
|
||||||
if (!handle)
|
if (!handle)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -2026,18 +2103,13 @@ lt_dlopen (filename)
|
|||||||
#endif
|
#endif
|
||||||
)) && tryall_dlopen (&newhandle, filename))
|
)) && tryall_dlopen (&newhandle, filename))
|
||||||
{
|
{
|
||||||
lt_dlfree (handle);
|
LT_DLFREE (handle);
|
||||||
handle = 0;
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register_handle:
|
register_handle:
|
||||||
if (newhandle != handle)
|
LT_DLMEM_REASSIGN (handle, newhandle);
|
||||||
{
|
|
||||||
lt_dlfree(handle);
|
|
||||||
handle = newhandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle->info.ref_count == 0)
|
if (handle->info.ref_count == 0)
|
||||||
{
|
{
|
||||||
@ -2051,9 +2123,9 @@ lt_dlopen (filename)
|
|||||||
last_error = saved_error;
|
last_error = saved_error;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (dir) lt_dlfree(dir);
|
LT_DLFREE (dir);
|
||||||
if (name) lt_dlfree(name);
|
LT_DLFREE (name);
|
||||||
if (canonical) lt_dlfree(canonical);
|
LT_DLFREE (canonical);
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
@ -2080,7 +2152,7 @@ lt_dlopenext (filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* try "filename.la" */
|
/* try "filename.la" */
|
||||||
tmp = (char*) lt_dlmalloc (len+4);
|
tmp = LT_DLMALLOC (char, len+4);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -2092,7 +2164,7 @@ lt_dlopenext (filename)
|
|||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
last_error = saved_error;
|
last_error = saved_error;
|
||||||
lt_dlfree (tmp);
|
LT_DLFREE (tmp);
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2100,8 +2172,8 @@ lt_dlopenext (filename)
|
|||||||
/* try "filename.EXT" */
|
/* try "filename.EXT" */
|
||||||
if (strlen(shlib_ext) > 3)
|
if (strlen(shlib_ext) > 3)
|
||||||
{
|
{
|
||||||
lt_dlfree (tmp);
|
LT_DLFREE (tmp);
|
||||||
tmp = (char*) lt_dlmalloc (len + strlen (shlib_ext) + 1);
|
tmp = LT_DLMALLOC (char, len + strlen (shlib_ext) + 1);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -2119,7 +2191,7 @@ lt_dlopenext (filename)
|
|||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
last_error = saved_error;
|
last_error = saved_error;
|
||||||
lt_dlfree (tmp);
|
LT_DLFREE (tmp);
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2132,7 +2204,7 @@ lt_dlopenext (filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
last_error = LT_DLSTRERROR (FILE_NOT_FOUND);
|
last_error = LT_DLSTRERROR (FILE_NOT_FOUND);
|
||||||
lt_dlfree (tmp);
|
LT_DLFREE (tmp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2179,17 +2251,10 @@ lt_dlclose (handle)
|
|||||||
error = handle->loader->module_close (data, handle->module);
|
error = handle->loader->module_close (data, handle->module);
|
||||||
error += unload_deplibs(handle);
|
error += unload_deplibs(handle);
|
||||||
|
|
||||||
if (handle->info.filename)
|
LT_DLFREE (handle->info.filename);
|
||||||
{
|
LT_DLFREE (handle->info.name);
|
||||||
lt_dlfree (handle->info.filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle->info.name)
|
LT_DLFREE (handle);
|
||||||
{
|
|
||||||
lt_dlfree (handle->info.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
lt_dlfree (handle);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -2243,7 +2308,7 @@ lt_dlsym (handle, symbol)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sym = (char*) lt_dlmalloc(lensym + LT_SYMBOL_OVERHEAD + 1);
|
sym = LT_DLMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sym)
|
if (!sym)
|
||||||
@ -2277,7 +2342,7 @@ lt_dlsym (handle, symbol)
|
|||||||
{
|
{
|
||||||
if (sym != lsym)
|
if (sym != lsym)
|
||||||
{
|
{
|
||||||
lt_dlfree(sym);
|
LT_DLFREE (sym);
|
||||||
}
|
}
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
@ -2298,7 +2363,7 @@ lt_dlsym (handle, symbol)
|
|||||||
address = handle->loader->find_sym (data, handle->module, sym);
|
address = handle->loader->find_sym (data, handle->module, sym);
|
||||||
if (sym != lsym)
|
if (sym != lsym)
|
||||||
{
|
{
|
||||||
lt_dlfree(sym);
|
LT_DLFREE (sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
@ -2334,7 +2399,7 @@ lt_dladdsearchdir (search_dir)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t len = strlen (user_search_path) + 1 + strlen (search_dir);
|
size_t len = strlen (user_search_path) + 1 + strlen (search_dir);
|
||||||
char *new_search_path = (char*) lt_dlmalloc (1+ len);
|
char *new_search_path = LT_DLMALLOC (char, 1+ len);
|
||||||
|
|
||||||
if (!new_search_path)
|
if (!new_search_path)
|
||||||
{
|
{
|
||||||
@ -2345,8 +2410,7 @@ lt_dladdsearchdir (search_dir)
|
|||||||
sprintf (new_search_path, "%s%c%s", user_search_path,
|
sprintf (new_search_path, "%s%c%s", user_search_path,
|
||||||
LT_PATHSEP_CHAR, search_dir);
|
LT_PATHSEP_CHAR, search_dir);
|
||||||
|
|
||||||
lt_dlfree (user_search_path);
|
LT_DLMEM_REASSIGN (user_search_path, new_search_path);
|
||||||
user_search_path = new_search_path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2356,11 +2420,7 @@ int
|
|||||||
lt_dlsetsearchpath (search_path)
|
lt_dlsetsearchpath (search_path)
|
||||||
const char *search_path;
|
const char *search_path;
|
||||||
{
|
{
|
||||||
if (user_search_path)
|
LT_DLFREE (user_search_path);
|
||||||
{
|
|
||||||
lt_dlfree (user_search_path);
|
|
||||||
user_search_path = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!search_path || !strlen (search_path))
|
if (!search_path || !strlen (search_path))
|
||||||
{
|
{
|
||||||
@ -2410,6 +2470,11 @@ lt_dlisresident (handle)
|
|||||||
return LT_DLIS_RESIDENT (handle);
|
return LT_DLIS_RESIDENT (handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* --- MODULE INFORMATION --- */
|
||||||
|
|
||||||
const lt_dlinfo *
|
const lt_dlinfo *
|
||||||
lt_dlgetinfo (handle)
|
lt_dlgetinfo (handle)
|
||||||
lt_dlhandle handle;
|
lt_dlhandle handle;
|
||||||
@ -2444,6 +2509,96 @@ lt_dlforeach (func, data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lt_dlcaller_id
|
||||||
|
lt_dlcaller_register ()
|
||||||
|
{
|
||||||
|
static unsigned last_caller_id = -1;
|
||||||
|
|
||||||
|
return ++last_caller_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define N_ELEMENTS(a) (sizeof(a) / sizeof(*(a)))
|
||||||
|
|
||||||
|
lt_ptr
|
||||||
|
lt_dlcaller_set_data (key, handle, data)
|
||||||
|
lt_dlcaller_id key;
|
||||||
|
lt_dlhandle handle;
|
||||||
|
lt_ptr data;
|
||||||
|
{
|
||||||
|
int n_elements = 0;
|
||||||
|
lt_ptr stale = (lt_ptr) 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (handle->caller_data)
|
||||||
|
n_elements = N_ELEMENTS (handle->caller_data);
|
||||||
|
|
||||||
|
for (i = 0; i < n_elements; ++i)
|
||||||
|
{
|
||||||
|
if (handle->caller_data[i].key == key)
|
||||||
|
{
|
||||||
|
stale = handle->caller_data[i].data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure that there is enough room in this handle's caller_data
|
||||||
|
array to accept a new element. */
|
||||||
|
if (i == n_elements)
|
||||||
|
{
|
||||||
|
lt_caller_data *temp
|
||||||
|
= LT_DLREALLOC (lt_caller_data, handle->caller_data, 1+ n_elements);
|
||||||
|
|
||||||
|
if (temp == 0)
|
||||||
|
{
|
||||||
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
|
return (lt_ptr) 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle->caller_data = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We only need this if we needed to allocate a new caller_data. */
|
||||||
|
handle->caller_data[i].key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->caller_data[i].data = data;
|
||||||
|
|
||||||
|
return stale;
|
||||||
|
}
|
||||||
|
|
||||||
|
lt_ptr
|
||||||
|
lt_dlcaller_get_data (key, handle)
|
||||||
|
lt_dlcaller_id key;
|
||||||
|
lt_dlhandle handle;
|
||||||
|
{
|
||||||
|
lt_ptr result = (lt_ptr) 0;
|
||||||
|
int n_elements = 0;
|
||||||
|
|
||||||
|
if (handle->caller_data)
|
||||||
|
n_elements = N_ELEMENTS (handle->caller_data);
|
||||||
|
|
||||||
|
/* Locate the index of the element with a matching KEY. */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < n_elements; ++i)
|
||||||
|
{
|
||||||
|
if (handle->caller_data[i].key == key)
|
||||||
|
{
|
||||||
|
result = handle->caller_data[i].data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* --- USER MODULE LOADER API --- */
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
lt_dlloader_add (place, dlloader, loader_name)
|
lt_dlloader_add (place, dlloader, loader_name)
|
||||||
lt_dlloader *place;
|
lt_dlloader *place;
|
||||||
@ -2462,7 +2617,7 @@ lt_dlloader_add (place, dlloader, loader_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new dlloader node with copies of the user callbacks. */
|
/* Create a new dlloader node with copies of the user callbacks. */
|
||||||
node = (lt_dlloader *) lt_dlmalloc (sizeof (lt_dlloader));
|
node = LT_DLMALLOC (lt_dlloader, 1);
|
||||||
if (node == 0)
|
if (node == 0)
|
||||||
{
|
{
|
||||||
last_error = LT_DLSTRERROR (NO_MEMORY);
|
last_error = LT_DLSTRERROR (NO_MEMORY);
|
||||||
@ -2571,10 +2726,7 @@ lt_dlloader_remove (loader_name)
|
|||||||
result = place->dlloader_exit (place->dlloader_data);
|
result = place->dlloader_exit (place->dlloader_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (place)
|
LT_DLFREE (place);
|
||||||
{
|
|
||||||
lt_dlfree (place);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -2626,4 +2778,3 @@ lt_dlloader_find (loader_name)
|
|||||||
|
|
||||||
return place;
|
return place;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,6 +208,15 @@ extern int lt_dlforeach LT_PARAMS((
|
|||||||
int (*func) (lt_dlhandle handle, lt_ptr data),
|
int (*func) (lt_dlhandle handle, lt_ptr data),
|
||||||
lt_ptr data));
|
lt_ptr data));
|
||||||
|
|
||||||
|
/* Associating user data with loaded modules. */
|
||||||
|
typedef unsigned lt_dlcaller_id;
|
||||||
|
|
||||||
|
extern lt_dlcaller_id lt_dlcaller_register LT_PARAMS((void));
|
||||||
|
extern lt_ptr lt_dlcaller_set_data LT_PARAMS((lt_dlcaller_id key,
|
||||||
|
lt_dlhandle handle,
|
||||||
|
lt_ptr data));
|
||||||
|
extern lt_ptr lt_dlcaller_get_data LT_PARAMS((lt_dlcaller_id key,
|
||||||
|
lt_dlhandle handle));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1
ltdl.m4
1
ltdl.m4
@ -39,6 +39,7 @@ AC_CHECK_HEADERS(malloc.h memory.h stdlib.h stdio.h ctype.h dl.h dld.h)
|
|||||||
AC_CHECK_HEADERS(string.h strings.h, break)
|
AC_CHECK_HEADERS(string.h strings.h, break)
|
||||||
AC_CHECK_FUNCS(strchr index, break)
|
AC_CHECK_FUNCS(strchr index, break)
|
||||||
AC_CHECK_FUNCS(strrchr rindex, break)
|
AC_CHECK_FUNCS(strrchr rindex, break)
|
||||||
|
AC_CHECK_FUNCS(memcpy bcopy, break)
|
||||||
AC_CHECK_FUNCS(strcmp)
|
AC_CHECK_FUNCS(strcmp)
|
||||||
|
|
||||||
AC_REQUIRE([AC_LTDL_ENABLE_INSTALL])dnl
|
AC_REQUIRE([AC_LTDL_ENABLE_INSTALL])dnl
|
||||||
|
Loading…
Reference in New Issue
Block a user