mirror of
git://git.savannah.gnu.org/libtool.git
synced 2025-02-11 15:00:08 +08:00
* libltdl/ltdl.c (lt_dlcaller_register): Renamed to avoid problems
with module visibilty when linked with programs written for the old API. (lt_dlinterface_register): New name. * Makefile.am (VERSION_INFO): Bumped. * doc/libtool.texi (User defined module data): Updated.
This commit is contained in:
parent
121d473ead
commit
9d4089fbbb
@ -1,3 +1,12 @@
|
||||
2005-09-27 Gary V. Vaughan <gary@gnu.org>
|
||||
|
||||
* libltdl/ltdl.c (lt_dlcaller_register): Renamed to avoid problems
|
||||
with module visibilty when linked with programs written for the
|
||||
old API.
|
||||
(lt_dlinterface_register): New name.
|
||||
* Makefile.am (VERSION_INFO): Bumped.
|
||||
* doc/libtool.texi (User defined module data): Updated.
|
||||
|
||||
2005-09-27 Tim Rice <tim@multitalents.net>
|
||||
|
||||
* tests/defs.m4sh, tests/testsuite.at (PREPARE_TESTS)
|
||||
|
@ -233,7 +233,7 @@ DEFS = -DLTDL -DHAVE_CONFIG_H -DLT_CONFIG_H='<$(LT_CONFIG_H)>'
|
||||
AM_CPPFLAGS = -I. -I$(srcdir) -Ilibltdl -I$(srcdir)/libltdl \
|
||||
-I$(srcdir)/libltdl/libltdl
|
||||
AM_LDFLAGS = -no-undefined
|
||||
VERSION_INFO = -version-info 6:1:0
|
||||
VERSION_INFO = -version-info 7:0:0
|
||||
|
||||
noinst_LTLIBRARIES = $(LT_DLLOADERS)
|
||||
|
||||
|
@ -3774,12 +3774,12 @@ However, you might still need to maintain your own list of loaded
|
||||
module handles (in parallel with the list maintained inside libltdl)
|
||||
if there were any other data that your application wanted to associate
|
||||
with each open module. Instead, you can use the following @sc{api}
|
||||
calls to do that for you. You must first obtain a unique caller id
|
||||
calls to do that for you. You must first obtain a unique interface id
|
||||
from libltdl, and subsequently always use it to retrieve the data you
|
||||
stored earlier. This allows different libraries to each store their
|
||||
own data against loaded modules, without interfering with one another.
|
||||
|
||||
@deftp {Type} lt_dlcaller_id
|
||||
@deftp {Type} lt_dlinterface_id
|
||||
The opaque type used to hold individual data set keys.
|
||||
@end deftp
|
||||
|
||||
@ -3789,14 +3789,14 @@ library's expected module interface when iterating over the global
|
||||
handle list.
|
||||
@end deftp
|
||||
|
||||
@deftypefun lt_dlcaller_id lt_dlcaller_register (@w{const char *@var{id_string},} @w{lt_dlhandle_interface *@var{iface}})
|
||||
@deftypefun lt_dlinterface_id lt_dlinterface_register (@w{const char *@var{id_string},} @w{lt_dlhandle_interface *@var{iface}})
|
||||
Use this to obtain a unique key to store and retrieve per module data,
|
||||
if you supply an @var{id_string} and @var{iface}, then the resulting
|
||||
@code{lt_dlcaller_id} can be used to filter the module handles
|
||||
@code{lt_dlinterface_id} can be used to filter the module handles
|
||||
returned by @samp{lt_dlhandle_next}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun lt_ptr lt_dlcaller_set_data (@w{lt_dlcaller_id @var{key}}, @w{lt_dlhandle @var{handle}}, @w{lt_ptr @var{data}})
|
||||
@deftypefun lt_ptr lt_dlcaller_set_data (@w{lt_dlinterface_id @var{key}}, @w{lt_dlhandle @var{handle}}, @w{lt_ptr @var{data}})
|
||||
Set @var{data} as the set of data uniquely associated with @var{key} and
|
||||
@var{handle} for later retrieval. This function returns the @var{data}
|
||||
previously associated with @var{key} and @var{handle} if any. A result of
|
||||
@ -3824,7 +3824,7 @@ else
|
||||
@end example
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun lt_ptr lt_dlcaller_get_data (@w{lt_dlcaller_id @var{key}}, @w{lt_dlhandle @var{handle}})
|
||||
@deftypefun lt_ptr lt_dlcaller_get_data (@w{lt_dlinterface_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
|
||||
@ -3835,23 +3835,23 @@ application to track the modules that have been loaded and unloaded:
|
||||
|
||||
@example
|
||||
int
|
||||
my_dlcaller_callback (lt_dlhandle handle, lt_ptr key_ptr)
|
||||
my_dlinterface_callback (lt_dlhandle handle, void *key)
|
||||
@{
|
||||
struct my_module_data *my_data;
|
||||
|
||||
my_data = lt_dlcaller_get_data (handle, (lt_dlcaller_id) *key_ptr);
|
||||
my_data = lt_dlcaller_get_data (handle, (lt_dlinterface_id) key);
|
||||
|
||||
return process (my_data);
|
||||
@}
|
||||
|
||||
int
|
||||
my_dlcaller_foreach (lt_dlcaller_id key)
|
||||
my_dlinterface_foreach (lt_dlinterface_id key)
|
||||
@{
|
||||
lt_dlforeach (my_dlcaller_callback, (lt_ptr) &key);
|
||||
lt_dlforeach (my_dlinterface_callback, (void *) key);
|
||||
@}
|
||||
@end example
|
||||
|
||||
@deftypefun lt_dlhandle lt_dlhandle_first (@w{lt_dlcaller_id @var{key}})
|
||||
@deftypefun lt_dlhandle lt_dlhandle_first (@w{lt_dlinterface_id @var{key}})
|
||||
Normally, you can fetch each of the loaded module handles in turn with
|
||||
successive calls to @samp{lt_dlhandle_next} as shown in the example
|
||||
above. In that example, the loop iterates over every libltdl loaded
|
||||
@ -3873,8 +3873,8 @@ iface_validator_callback (lt_dlhandle handle, const char *id_string)
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
When you register for a caller identification with
|
||||
@samp{lt_dlcaller_register}, you log the interface validator. But
|
||||
When you register for an interface identification key with
|
||||
@samp{lt_dlinterface_register}, you log the interface validator. But
|
||||
this time, when you start the iterator loop over the loaded module
|
||||
handles, if you fetch the first handle with @samp{lt_dlhandle_first},
|
||||
then that and all subsequent calls to @samp{lt_dlhandle_next} will
|
||||
@ -3882,15 +3882,16 @@ skip any loaded module handles that fail the registered interface
|
||||
validator callback function:
|
||||
|
||||
@example
|
||||
/* @r{Register for a} caller_id @r{to identify ourselves to} libltdl. */
|
||||
caller_id = lt_dlcaller_register ("example", iface_validator_callback);
|
||||
/* @r{Register for an} interface_id @r{to identify ourselves to} libltdl. */
|
||||
interface_id = lt_dlinterface_register ("example", iface_validator_callback);
|
||||
|
||||
@dots{}
|
||||
/* @r{Iterate over the modules related to my} caller_id. */
|
||||
/* @r{Iterate over the modules related to my} interface_id. */
|
||||
@{
|
||||
lt_dlhandle handle = lt_dlhandle_first (caller_id);
|
||||
|
||||
while ((handle = lt_dlhandle_next (handle)))
|
||||
lt_dlhandle handle;
|
||||
for (handle = lt_dlhandle_first (interface_id);
|
||||
handle;
|
||||
handle = lt_dlhandle_next (handle))
|
||||
@{
|
||||
@dots{}
|
||||
@}
|
||||
@ -3898,6 +3899,14 @@ caller_id = lt_dlcaller_register ("example", iface_validator_callback);
|
||||
@end example
|
||||
@end deftypefun
|
||||
|
||||
Old versions of libltdl also provided a simpler, but similar, @sc{api}
|
||||
based around @code{lt_dlcaller_id}. Unfortunately, it had no
|
||||
provision for detecting whether a module belonged to a particular
|
||||
interface as libltdl didn't support multiple loaders in the same
|
||||
address space at that time. Those @sc{api}s are no longer supported
|
||||
as there would be no way to stop clients of the old @sc{api}s from
|
||||
seeing (and accidentally altering) modules loaded by other libraries.
|
||||
|
||||
|
||||
@node Module loaders for libltdl
|
||||
@section How to create and register new module loaders
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* lt__private.h -- internal apis for libltdl
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
Originally by Gary V. Vaughan <gary@gnu.org>
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the
|
||||
@ -95,11 +95,11 @@ LT_SCOPE void lt__alloc_die_callback (void);
|
||||
|
||||
/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
|
||||
|
||||
/* This type is used for the array of caller data sets in each handler. */
|
||||
/* This type is used for the array of interface data sets in each handler. */
|
||||
typedef struct {
|
||||
lt_dlcaller_id key;
|
||||
lt_dlinterface_id key;
|
||||
void * data;
|
||||
} lt_caller_data;
|
||||
} lt_interface_data;
|
||||
|
||||
typedef struct lt__handle lt__handle;
|
||||
|
||||
@ -111,7 +111,7 @@ struct lt__handle {
|
||||
lt_dlhandle * deplibs; /* dependencies */
|
||||
lt_module module; /* system module handle */
|
||||
void * system; /* system specific data */
|
||||
lt_caller_data * caller_data; /* per caller associated data */
|
||||
lt_interface_data * interface_data; /* per caller associated data */
|
||||
int flags; /* various boolean stats */
|
||||
};
|
||||
|
||||
|
@ -1447,7 +1447,7 @@ lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
|
||||
|
||||
/* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
|
||||
pargz_len, NULL, entry) failed with EINVAL. */
|
||||
if (before)
|
||||
if (before)
|
||||
error = argz_insert (pargz, pargz_len, before, entry);
|
||||
else
|
||||
error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
|
||||
@ -1712,7 +1712,7 @@ lt_dlclose (lt_dlhandle handle)
|
||||
errors += unload_deplibs (handle);
|
||||
|
||||
/* It is up to the callers to free the data itself. */
|
||||
FREE (cur->caller_data);
|
||||
FREE (cur->interface_data);
|
||||
|
||||
FREE (cur->info.filename);
|
||||
FREE (cur->info.name);
|
||||
@ -2013,51 +2013,51 @@ lt_dlisresident (lt_dlhandle handle)
|
||||
typedef struct {
|
||||
const char *id_string;
|
||||
lt_dlhandle_interface *iface;
|
||||
} lt__caller_id;
|
||||
} lt__interface_id;
|
||||
|
||||
lt_dlcaller_id
|
||||
lt_dlcaller_register (const char *id_string, lt_dlhandle_interface *iface)
|
||||
lt_dlinterface_id
|
||||
lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
|
||||
{
|
||||
lt__caller_id *caller_id = lt__malloc (sizeof *caller_id);
|
||||
lt__interface_id *interface_id = lt__malloc (sizeof *interface_id);
|
||||
|
||||
/* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
|
||||
can then be detected with lt_dlerror() if we return 0. */
|
||||
if (caller_id)
|
||||
if (interface_id)
|
||||
{
|
||||
caller_id->id_string = lt__strdup (id_string);
|
||||
caller_id->iface = iface;
|
||||
interface_id->id_string = lt__strdup (id_string);
|
||||
interface_id->iface = iface;
|
||||
}
|
||||
|
||||
return (lt_dlcaller_id) caller_id;
|
||||
return (lt_dlinterface_id) interface_id;
|
||||
}
|
||||
|
||||
void *
|
||||
lt_dlcaller_set_data (lt_dlcaller_id key, lt_dlhandle handle, void *data)
|
||||
lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
|
||||
{
|
||||
int n_elements = 0;
|
||||
void *stale = (void *) 0;
|
||||
lt__handle *cur = (lt__handle *) handle;
|
||||
int i;
|
||||
|
||||
if (cur->caller_data)
|
||||
while (cur->caller_data[n_elements].key)
|
||||
if (cur->interface_data)
|
||||
while (cur->interface_data[n_elements].key)
|
||||
++n_elements;
|
||||
|
||||
for (i = 0; i < n_elements; ++i)
|
||||
{
|
||||
if (cur->caller_data[i].key == key)
|
||||
if (cur->interface_data[i].key == key)
|
||||
{
|
||||
stale = cur->caller_data[i].data;
|
||||
stale = cur->interface_data[i].data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure that there is enough room in this handle's caller_data
|
||||
/* Ensure that there is enough room in this handle's interface_data
|
||||
array to accept a new element (and an empty end marker). */
|
||||
if (i == n_elements)
|
||||
{
|
||||
lt_caller_data *temp
|
||||
= REALLOC (lt_caller_data, cur->caller_data, 2+ n_elements);
|
||||
lt_interface_data *temp
|
||||
= REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);
|
||||
|
||||
if (!temp)
|
||||
{
|
||||
@ -2065,21 +2065,21 @@ lt_dlcaller_set_data (lt_dlcaller_id key, lt_dlhandle handle, void *data)
|
||||
goto done;
|
||||
}
|
||||
|
||||
cur->caller_data = temp;
|
||||
cur->interface_data = temp;
|
||||
|
||||
/* We only need this if we needed to allocate a new caller_data. */
|
||||
cur->caller_data[i].key = key;
|
||||
cur->caller_data[1+ i].key = 0;
|
||||
/* We only need this if we needed to allocate a new interface_data. */
|
||||
cur->interface_data[i].key = key;
|
||||
cur->interface_data[1+ i].key = 0;
|
||||
}
|
||||
|
||||
cur->caller_data[i].data = data;
|
||||
cur->interface_data[i].data = data;
|
||||
|
||||
done:
|
||||
return stale;
|
||||
}
|
||||
|
||||
void *
|
||||
lt_dlcaller_get_data (lt_dlcaller_id key, lt_dlhandle handle)
|
||||
lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle)
|
||||
{
|
||||
void *result = (void *) 0;
|
||||
lt__handle *cur = (lt__handle *) handle;
|
||||
@ -2087,11 +2087,11 @@ lt_dlcaller_get_data (lt_dlcaller_id key, lt_dlhandle handle)
|
||||
/* Locate the index of the element with a matching KEY. */
|
||||
{
|
||||
int i;
|
||||
for (i = 0; cur->caller_data[i].key; ++i)
|
||||
for (i = 0; cur->interface_data[i].key; ++i)
|
||||
{
|
||||
if (cur->caller_data[i].key == key)
|
||||
if (cur->interface_data[i].key == key)
|
||||
{
|
||||
result = cur->caller_data[i].data;
|
||||
result = cur->interface_data[i].data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2118,12 +2118,12 @@ lt_dlgetinfo (lt_dlhandle handle)
|
||||
or else iterate over just the handles of modules that satisfy a given
|
||||
interface by getting the first element using lt_dlhandle_first(iface). */
|
||||
|
||||
static lt__caller_id *iterator = 0;
|
||||
static lt__interface_id *iterator = 0;
|
||||
|
||||
lt_dlhandle
|
||||
lt_dlhandle_first (lt_dlcaller_id caller)
|
||||
lt_dlhandle_first (lt_dlinterface_id iface)
|
||||
{
|
||||
iterator = caller;
|
||||
iterator = iface;
|
||||
|
||||
return handles;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ltdl.h -- generic dlopen functions
|
||||
Copyright (C) 1998-2000, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998-2000, 2004, 2005 Free Software Foundation, Inc.
|
||||
Originally by Thomas Tanner <tanner@ffii.org>
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the
|
||||
@ -106,15 +106,16 @@ LT_SCOPE int lt_dlpreload_open (const char *originator,
|
||||
|
||||
|
||||
/* Associating user data with loaded modules. */
|
||||
typedef void * lt_dlcaller_id;
|
||||
typedef void * lt_dlinterface_id;
|
||||
typedef int lt_dlhandle_interface (lt_dlhandle handle, const char *id_string);
|
||||
|
||||
LT_SCOPE lt_dlcaller_id lt_dlcaller_register (const char *id_string,
|
||||
lt_dlhandle_interface *iface);
|
||||
LT_SCOPE void * lt_dlcaller_set_data (lt_dlcaller_id key,
|
||||
lt_dlhandle handle, void *data);
|
||||
LT_SCOPE void * lt_dlcaller_get_data (lt_dlcaller_id key,
|
||||
lt_dlhandle handle);
|
||||
LT_SCOPE lt_dlinterface_id lt_dlinterface_register (const char *id_string,
|
||||
lt_dlhandle_interface *iface);
|
||||
LT_SCOPE void * lt_dlcaller_set_data (lt_dlinterface_id key,
|
||||
lt_dlhandle handle, void *data);
|
||||
LT_SCOPE void * lt_dlcaller_get_data (lt_dlinterface_id key,
|
||||
lt_dlhandle handle);
|
||||
|
||||
|
||||
/* Read only information pertaining to a loaded module. */
|
||||
typedef struct {
|
||||
@ -125,7 +126,7 @@ typedef struct {
|
||||
} lt_dlinfo;
|
||||
|
||||
LT_SCOPE const lt_dlinfo *lt_dlgetinfo (lt_dlhandle handle);
|
||||
LT_SCOPE lt_dlhandle lt_dlhandle_first (lt_dlcaller_id key);
|
||||
LT_SCOPE lt_dlhandle lt_dlhandle_first (lt_dlinterface_id key);
|
||||
LT_SCOPE lt_dlhandle lt_dlhandle_next (lt_dlhandle place);
|
||||
LT_SCOPE lt_dlhandle lt_dlhandle_find (const char *module_name);
|
||||
LT_SCOPE int lt_dlforeach (
|
||||
@ -136,9 +137,9 @@ LT_SCOPE int lt_dlforeach (
|
||||
|
||||
/* --- BINARY COMPATIBILITY WITH OLD LIBLTDL --- */
|
||||
|
||||
typedef void lt_dlmutex_lock (void);
|
||||
typedef void lt_dlmutex_unlock (void);
|
||||
typedef void lt_dlmutex_seterror (const char *errmsg);
|
||||
typedef void lt_dlmutex_lock (void);
|
||||
typedef void lt_dlmutex_unlock (void);
|
||||
typedef void lt_dlmutex_seterror (const char *errmsg);
|
||||
typedef const char *lt_dlmutex_geterror (void);
|
||||
|
||||
LT_SCOPE void * (*lt_dlmalloc) (size_t size);
|
||||
|
Loading…
Reference in New Issue
Block a user