[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
libtool--gary--1.0--patch-33
From: |
Gary V. Vaughan |
Subject: |
libtool--gary--1.0--patch-33 |
Date: |
Wed, 14 Jul 2004 10:52:05 +0100 (BST) |
User-agent: |
mailnotify/0.3 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
As part and parcel of allowing multiple libraries, each with their
own loaded modules, we need a way of letting each client of libltdl
ignore everyone elses modules...
Okay to commit?
- --
Gary V. Vaughan ())_. address@hidden,gnu.org}
Research Scientist ( '/ http://tkd.kicks-ass.net
GNU Hacker / )= http://www.gnu.org/software/libtool
Technical Author `(_~)_ http://sources.redhat.com/autobook
_________________________________________________________
This patch notification generated by tlaapply version 0.5
http://tkd.kicks-ass.net/arch/address@hidden/cvs-utils--tla--1.0
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (Darwin)
iD8DBQFA9QJEFRMICSmD1gYRAjb3AJ92dnGZm2gZnDmL833Lg3OpRNt0kgCgibtX
vCO8cSiqjD8ehz9VD1L25p0=
=JMUc
-----END PGP SIGNATURE-----
* looking for address@hidden/libtool--gary--1.0--patch-32 to compare with
* comparing to address@hidden/libtool--gary--1.0--patch-32
M libltdl/lt_dlloader.c
M ChangeLog
M NEWS
M doc/libtool.texi
M libltdl/ltdl.c
M libltdl/ltdl.h
M libltdl/lt__private.h
* modified files
Index: Changelog
from Gary V. Vaughan <address@hidden>
* libltdl/lt__private.h (lt_dlhandle_struct): Renamed to
lt__handle to better reflect the naming scheme.
* libltdl/ltdl.h (lt_dlhandle): Be truly opaque with a void *.
* libltdl/lt_dlloader.c (lt_dlloader_remove): Party to
lt__private.h, so use internal lt__handle instead of opaque
lt_dlhandle.
* libltdl/ltdl.c (LT_DLGET_FLAG, LT_DLSET_FLAG): Add a cast to
internal lt__handle type.
(try_dlopen, tryall_dlopen, load_deplibs, unload_deplibs): Ditto.
(lt_dlexit, lt_dlclose, lt_dlsym): Use lt__handle to iterate
throught the handle list.
(try_dlopen): Use lt__zalloc instead of MALLOC and memset.
* libltdl/ltdl.h (lt_dlcaller_id): Be truly opaque with a void *.
(lt_dlhandle_interface): New callback type for filtering handles
according to the interface they present.
* libltdl/ltdl.c (lt_dlcaller_register): Take an id and an
interface check callback, and generate a caller_id.
(iterator): New static variable for the use of...
(lt_dlhandle_first): New function. Set the iterator for
subsequent calls to lt_dlhandle_next.
(lt_dlhandle_next): Either work as before when iterator is unset,
or else skip handles that fail the interface check in iterator set
by lt_dlhandle_first.
* libltdl/ltdl.h (lt_dlhandle_first): Declaration.
* doc/libtool.texi (User defined module data): Document the new
APIs.
* NEWS: Updated.
2004-07-13 Gary V. Vaughan <address@hidden>
--- orig/NEWS
+++ mod/NEWS
@@ -45,6 +45,8 @@
* libltdl no longer loads shared libraries with global symbol resolution,
this caused problems when the symbols were intended to be overriden further
up the stack; it is also not recommended practice.
+* New function in libltdl: lt_dlhandle_first, primes handle iterations (using
+ lt_dlhandle_next) to filter by module interface.
* libltdl no longer tries to support multi-threaded programming with
lt_dlmutex_register(), which was unusable with POSIX threads anyway.
The symbols are deprecated but exported for backwards compatibility.
--- orig/doc/libtool.texi
+++ mod/doc/libtool.texi
@@ -3430,6 +3430,15 @@
list if @var{place} is @code{NULL}, and the next one on subsequent calls.
If @var{place} is the last element in the list of loaded modules, this
function returns @code{NULL}.
+
address@hidden
+ lt_dlhandle handle = 0;
+
+ while ((handle = lt_dlhandle_next (handle)))
+ @{
+ @dots{}
+ @}
address@hidden example
@end deftypefun
@deftypefun lt_dlhandle lt_dlhandle_find (@w{const char address@hidden)
@@ -3451,8 +3460,17 @@
The opaque type used to hold individual data set keys.
@end deftp
address@hidden lt_dlcaller_id lt_dlcaller_register (void)
-Use this to obtain a unique key to store and retrieve per module data.
address@hidden {Type} int lt_dlhandle_interface (@w{lt_dlhandle @var{handle},}
@w{const char address@hidden)
+Functions of this type are called to check that a handle conforms to a
+library's expected module interface when iterating over the global
+handle list.
address@hidden deftp
+
address@hidden lt_dlcaller_id lt_dlcaller_register (@w{const char
address@hidden,} @w{lt_dlhandle_interface address@hidden)
+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
address@hidden 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}})
@@ -3510,6 +3528,53 @@
@}
@end example
address@hidden lt_dlhandle lt_dlhandle_first (@w{lt_dlcaller_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
+module in your application, including the modules used by libltdl
+itself! This is useful from within a module loader for example.
+
address@hidden
+Often, your application doesn't want to concern itself with modules
+loaded by the libraries it uses, or for libltdl's internal use. In
+order to do that, you need to specify an interface validator callback:
+
address@hidden
+/* @r{Return non-zero if} @var{handle} @r{doesn't conform to my iface.} */
+int
+iface_validator_callback (lt_dlhandle handle, const char *id_string)
address@hidden
+ return (lt_sym (handle, "module_entry_point") != 0)
address@hidden
address@hidden example
+
address@hidden
+When you register for a caller identification with
address@hidden, 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
+skip any loaded module handles that fail the registered interface
+validator callback function:
+
address@hidden
+ /* @r{Register for a} caller_id @r{to identify ourselves to} libltdl. */
+ caller_id = lt_dlcaller_register ("example", iface_validator_callback);
+
address@hidden
+ /* @r{Iterate over the modules related to my} caller_id. */
+ @{
+ lt_dlhandle handle = lt_dlhandle_first (caller_id);
+
+ while ((handle = lt_dlhandle_next (handle)))
+ @{
+ @dots{}
+ @}
+ @}
address@hidden example
address@hidden deftypefun
+
@node Module loaders for libltdl
@section How to create and register new module loaders
--- orig/libltdl/lt__private.h
+++ mod/libltdl/lt__private.h
@@ -97,8 +97,10 @@
void * data;
} lt_caller_data;
-struct lt_dlhandle_struct {
- struct lt_dlhandle_struct *next;
+typedef struct lt__handle lt__handle;
+
+struct lt__handle {
+ lt__handle * next;
const lt_dlvtable * vtable; /* dlopening interface */
lt_dlinfo info; /* user visible fields */
int depcount; /* number of dependencies */
--- orig/libltdl/lt_dlloader.c
+++ mod/libltdl/lt_dlloader.c
@@ -113,7 +113,7 @@
lt_dlloader_remove (const char *name)
{
const lt_dlvtable * vtable = lt_dlloader_find (name);
- lt_dlhandle handle = 0;
+ lt__handle * handle = 0;
int errors = 0;
if (!vtable)
@@ -123,7 +123,7 @@
}
/* Fail if there are any open modules which use this loader. */
- while (handle = lt_dlhandle_next (handle))
+ for (handle = 0; handle; handle = handle->next)
{
if (handle->vtable == vtable)
{
--- orig/libltdl/ltdl.c
+++ mod/libltdl/ltdl.c
@@ -59,8 +59,8 @@
/* Various boolean flags can be stored in the flags field of an
lt_dlhandle... */
-#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
-#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
+#define LT_DLGET_FLAG(handle, flag) ((((lt__handle *) handle)->flags & (flag))
== (flag))
+#define LT_DLSET_FLAG(handle, flag) (((lt__handle *)handle)->flags |= (flag))
#define LT_DLRESIDENT_FLAG (0x01 << 0)
/* ...add more flags here... */
@@ -240,6 +240,7 @@
{
/* shut down libltdl */
lt_dlloader *loader = 0;
+ lt__handle *handle = (lt__handle *) handles;
int errors = 0;
if (!initialized)
@@ -256,26 +257,28 @@
while (handles && LT_DLIS_RESIDENT (handles))
{
- handles = handles->next;
+ handles = ((lt__handle *) handles)->next;
}
/* close all modules */
- for (level = 1; handles; ++level)
+ for (level = 1; handle; ++level)
{
- lt_dlhandle cur = handles;
+ lt__handle *cur = (lt__handle *) handles;
int saw_nonresident = 0;
while (cur)
{
- lt_dlhandle tmp = cur;
+ lt__handle *tmp = cur;
cur = cur->next;
if (!LT_DLIS_RESIDENT (tmp))
- saw_nonresident = 1;
- if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
{
- if (lt_dlclose (tmp))
+ saw_nonresident = 1;
+ if (tmp->info.ref_count <= level)
{
- ++errors;
+ if (lt_dlclose (tmp))
+ {
+ ++errors;
+ }
}
}
}
@@ -307,14 +310,14 @@
static int
tryall_dlopen (lt_dlhandle *phandle, const char *filename)
{
- lt_dlhandle handle = 0;
+ lt__handle * handle = (lt__handle *) handles;
const char * saved_error = 0;
int errors = 0;
LT__GETERROR (saved_error);
/* check whether the module was already opened */
- while (handle = lt_dlhandle_next (handle))
+ for (;handle; handle = handle->next)
{
if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */
|| (handle->info.filename && filename
@@ -720,7 +723,7 @@
#endif
int errors = 0;
- handle->depcount = 0;
+ ((lt__handle *) handle)->depcount = 0;
#if defined(LTDL_DLOPEN_DEPLIBS)
if (!deplibs)
@@ -833,22 +836,23 @@
later on if the loaded module cannot resolve all of its symbols. */
if (depcount)
{
+ lt__handle *cur = (lt__handle *) handle;
int j = 0;
- handle->deplibs = (lt_dlhandle*) MALLOC (lt_dlhandle *, depcount);
- if (!handle->deplibs)
+ cur->deplibs = (lt_dlhandle *) MALLOC (lt__handle, depcount);
+ if (!cur->deplibs)
goto cleanup;
for (i = 0; i < depcount; ++i)
{
- handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
- if (handle->deplibs[j])
+ cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
+ if (cur->deplibs[j])
{
++j;
}
}
- handle->depcount = j; /* Number of successfully loaded deplibs */
+ cur->depcount = j; /* Number of successfully loaded deplibs */
errors = 0;
}
@@ -870,14 +874,15 @@
{
int i;
int errors = 0;
+ lt__handle *cur = (lt__handle *) handle;
- if (handle->depcount)
+ if (cur->depcount)
{
- for (i = 0; i < handle->depcount; ++i)
+ for (i = 0; i < cur->depcount; ++i)
{
- if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
+ if (!LT_DLIS_RESIDENT (cur->deplibs[i]))
{
- errors += lt_dlclose (handle->deplibs[i]);
+ errors += lt_dlclose (cur->deplibs[i]);
}
}
}
@@ -934,11 +939,10 @@
/* dlopen self? */
if (!filename)
{
- *phandle = (lt_dlhandle) MALLOC (struct lt_dlhandle_struct, 1);
+ *phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle));
if (*phandle == 0)
return 1;
- memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
newhandle = *phandle;
/* lt_dlclose()ing yourself is very bad! Disallow it. */
@@ -1186,7 +1190,7 @@
FREE (line);
/* allocate the handle */
- *phandle = (lt_dlhandle) malloc (sizeof (struct lt_dlhandle_struct));
+ *phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle));
if (*phandle == 0)
++errors;
@@ -1202,7 +1206,6 @@
assert (*phandle);
- memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
if (load_deplibs (*phandle, deplibs) == 0)
{
newhandle = *phandle;
@@ -1237,14 +1240,13 @@
else
{
/* not a libtool module */
- *phandle = (lt_dlhandle) MALLOC (struct lt_dlhandle_struct, 1);
+ *phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle));
if (*phandle == 0)
{
++errors;
goto cleanup;
}
- memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
newhandle = *phandle;
/* If the module has no directory name component, try to find it
@@ -1280,13 +1282,13 @@
register_handle:
MEMREASSIGN (*phandle, newhandle);
- if ((*phandle)->info.ref_count == 0)
+ if (((lt__handle *) *phandle)->info.ref_count == 0)
{
- (*phandle)->info.ref_count = 1;
- MEMREASSIGN ((*phandle)->info.name, name);
+ ((lt__handle *) *phandle)->info.ref_count = 1;
+ MEMREASSIGN (((lt__handle *) *phandle)->info.name, name);
- (*phandle)->next = handles;
- handles = *phandle;
+ ((lt__handle *) *phandle)->next = handles;
+ handles = *phandle;
}
LT__SETERRORSTR (saved_error);
@@ -1640,11 +1642,11 @@
int
lt_dlclose (lt_dlhandle handle)
{
- lt_dlhandle cur, last;
+ lt__handle *cur, *last;
int errors = 0;
/* check whether the handle is valid */
- last = cur = handles;
+ last = cur = (lt__handle *) handles;
while (cur && handle != cur)
{
last = cur;
@@ -1658,34 +1660,35 @@
goto done;
}
- handle->info.ref_count--;
+ cur = (lt__handle *) handle;
+ cur->info.ref_count--;
/* Note that even with resident modules, we must track the ref_count
correctly incase the user decides to reset the residency flag
later (even though the API makes no provision for that at the
moment). */
- if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
+ if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
{
- lt_user_data data = handle->vtable->dlloader_data;
+ lt_user_data data = cur->vtable->dlloader_data;
- if (handle != handles)
+ if (cur != handles)
{
- last->next = handle->next;
+ last->next = cur->next;
}
else
{
- handles = handle->next;
+ handles = cur->next;
}
- errors += handle->vtable->module_close (data, handle->module);
- errors += unload_deplibs(handle);
+ errors += cur->vtable->module_close (data, cur->module);
+ errors += unload_deplibs (handle);
/* It is up to the callers to free the data itself. */
- FREE (handle->caller_data);
+ FREE (cur->caller_data);
- FREE (handle->info.filename);
- FREE (handle->info.name);
- FREE (handle);
+ FREE (cur->info.filename);
+ FREE (cur->info.name);
+ FREE (cur);
goto done;
}
@@ -1701,20 +1704,23 @@
}
void *
-lt_dlsym (lt_dlhandle handle, const char *symbol)
+lt_dlsym (lt_dlhandle place, const char *symbol)
{
size_t lensym;
char lsym[LT_SYMBOL_LENGTH];
char *sym;
void *address;
lt_user_data data;
+ lt__handle *handle;
- if (!handle)
+ if (!place)
{
LT__SETERROR (INVALID_HANDLE);
return 0;
}
+ handle = (lt__handle *) place;
+
if (!symbol)
{
LT__SETERROR (SYMBOL_NOT_FOUND);
@@ -1976,71 +1982,20 @@
/* --- MODULE INFORMATION --- */
-const lt_dlinfo *
-lt_dlgetinfo (lt_dlhandle handle)
-{
- if (!handle)
- {
- LT__SETERROR (INVALID_HANDLE);
- return 0;
- }
-
- return &(handle->info);
-}
-
-
-lt_dlhandle
-lt_dlhandle_next (lt_dlhandle place)
-{
- return place ? place->next : handles;
-}
-
+typedef struct {
+ const char *id_string;
+ lt_dlhandle_interface *iface;
+} lt__caller_id;
-lt_dlhandle
-lt_dlhandle_find (const char *module_name)
-{
- lt_dlhandle cur = handles;
-
- if (cur)
- {
- do
- {
- if (cur->info.name && streq (cur->info.name, module_name))
- break;
- }
- while ((cur = cur->next));
- }
-
- return cur;
-}
-
-int
-lt_dlforeach (int (*func) (lt_dlhandle handle, void *data), void *data)
+lt_dlcaller_id
+lt_dlcaller_register (const char *id_string, lt_dlhandle_interface *iface)
{
- int errors = 0;
- lt_dlhandle cur;
+ lt__caller_id *caller_id = lt__malloc (sizeof *caller_id);
- cur = handles;
- while (cur)
- {
- lt_dlhandle tmp = cur;
+ caller_id->id_string = lt__strdup (id_string);
+ caller_id->iface = iface;
- cur = cur->next;
- if ((*func) (tmp, data))
- {
- ++errors;
- break;
- }
- }
-
- return errors;
-}
-
-lt_dlcaller_id
-lt_dlcaller_register (void)
-{
- static lt_dlcaller_id last_caller_id = 0;
- return ++last_caller_id;
+ return (lt_dlcaller_id) caller_id;
}
void *
@@ -2048,17 +2003,18 @@
{
int n_elements = 0;
void *stale = (void *) 0;
+ lt__handle *cur = (lt__handle *) handle;
int i;
- if (handle->caller_data)
- while (handle->caller_data[n_elements].key)
+ if (cur->caller_data)
+ while (cur->caller_data[n_elements].key)
++n_elements;
for (i = 0; i < n_elements; ++i)
{
- if (handle->caller_data[i].key == key)
+ if (cur->caller_data[i].key == key)
{
- stale = handle->caller_data[i].data;
+ stale = cur->caller_data[i].data;
break;
}
}
@@ -2068,7 +2024,7 @@
if (i == n_elements)
{
lt_caller_data *temp
- = REALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
+ = REALLOC (lt_caller_data, cur->caller_data, 2+ n_elements);
if (!temp)
{
@@ -2076,14 +2032,14 @@
goto done;
}
- handle->caller_data = temp;
+ cur->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[1+ i].key = 0;
+ cur->caller_data[i].key = key;
+ cur->caller_data[1+ i].key = 0;
}
- handle->caller_data[i].data = data;
+ cur->caller_data[i].data = data;
done:
return stale;
@@ -2093,15 +2049,16 @@
lt_dlcaller_get_data (lt_dlcaller_id key, lt_dlhandle handle)
{
void *result = (void *) 0;
+ lt__handle *cur = (lt__handle *) handle;
/* Locate the index of the element with a matching KEY. */
{
int i;
- for (i = 0; handle->caller_data[i].key; ++i)
+ for (i = 0; cur->caller_data[i].key; ++i)
{
- if (handle->caller_data[i].key == key)
+ if (cur->caller_data[i].key == key)
{
- result = handle->caller_data[i].data;
+ result = cur->caller_data[i].data;
break;
}
}
@@ -2110,6 +2067,109 @@
return result;
}
+const lt_dlinfo *
+lt_dlgetinfo (lt_dlhandle handle)
+{
+ if (!handle)
+ {
+ LT__SETERROR (INVALID_HANDLE);
+ return 0;
+ }
+
+ return &(((lt__handle *) handle)->info);
+}
+
+
+/* Nasty semantics, necessary for reasonable backwards compatibility:
+ Either iterate over the whole handle list starting with lt_dlhandle_next(0),
+ 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;
+
+lt_dlhandle
+lt_dlhandle_first (lt_dlcaller_id caller)
+{
+ iterator = caller;
+
+ return handles;
+}
+
+
+lt_dlhandle
+lt_dlhandle_next (lt_dlhandle place)
+{
+ lt__handle *handle = (lt__handle *) place;
+
+ if (!handle)
+ {
+ /* old style iteration across all handles */
+ iterator = 0;
+ handle = (lt__handle *) handles;
+ }
+ else
+ {
+ /* otherwise start at the next handle after the passed one */
+ handle = handle->next;
+ }
+
+ /* advance until the interface check (if we have one) succeeds */
+ while (handle && iterator && iterator->iface
+ && (iterator->iface (handle, iterator->id_string) != 0))
+ {
+ handle = handle->next;
+ }
+
+ if (!handle)
+ {
+ /* clear the iterator after the last handle */
+ iterator = 0;
+ }
+
+ return (lt_dlhandle) handle;
+}
+
+
+lt_dlhandle
+lt_dlhandle_find (const char *module_name)
+{
+ lt__handle *cur = (lt__handle *) handles;
+
+ if (cur)
+ {
+ do
+ {
+ if (cur->info.name && streq (cur->info.name, module_name))
+ break;
+ }
+ while ((cur = cur->next));
+ }
+
+ return cur;
+}
+
+int
+lt_dlforeach (int (*func) (lt_dlhandle handle, void *data), void *data)
+{
+ int errors = 0;
+ lt__handle *cur;
+
+ cur = (lt__handle *) handles;
+ while (cur)
+ {
+ lt__handle *tmp = cur;
+
+ cur = cur->next;
+ if ((*func) (tmp, data))
+ {
+ ++errors;
+ break;
+ }
+ }
+
+ return errors;
+}
+
/* These symbols are part of the published interface to libltdl,
--- orig/libltdl/ltdl.h
+++ mod/libltdl/ltdl.h
@@ -45,7 +45,7 @@
/* --- DYNAMIC MODULE LOADING API --- */
-typedef struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module. */
+typedef void * lt_dlhandle; /* A loaded module. */
/* Initialisation and finalisation functions for libltdl. */
LT_SCOPE int lt_dlinit (void);
@@ -110,6 +110,17 @@
/* --- MODULE INFORMATION --- */
+/* Associating user data with loaded modules. */
+typedef void * lt_dlcaller_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);
+
/* Read only information pertaining to a loaded module. */
typedef struct {
char * filename; /* file name */
@@ -119,21 +130,13 @@
} 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_next (lt_dlhandle place);
LT_SCOPE lt_dlhandle lt_dlhandle_find (const char *module_name);
LT_SCOPE int lt_dlforeach (
int (*func) (lt_dlhandle handle, void *data),
void *data);
-/* Associating user data with loaded modules. */
-typedef unsigned lt_dlcaller_id;
-
-LT_SCOPE lt_dlcaller_id lt_dlcaller_register (void);
-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);
-
/* --- BINARY COMPATIBILITY WITH OLD LIBLTDL --- */
- libtool--gary--1.0--patch-33,
Gary V. Vaughan <=