2000-02-03 Gary V. Vaughan <gary@oranda.demon.co.uk>
+ * libltdl/ltdl.h (lt_dlloader_data_t): New type for loader
+ instance data.
+ (lt_user_dlloader): New lt_dlloader_data_t field.
+ (lt_module_open_t): Add lt_dlloader_data_t parameter.
+ (lt_module_close_t): Add lt_dlloader_data_t parameter.
+ (lt_find_sym_t): Add lt_dlloader_data_t parameter.
+ (lt_dlloader_exit_t): Add lt_dlloader_data_t parameter.
+ * libltdl/ltdl.c: A sprinkling of /*ARGSUSED*/ markers to
+ reassure lint that the unused arguments are intentional.
+ (lt_dlloader_t): New lt_dlloader_data_t field.
+ (lt_dlloader_data): New function to return the contents of the
+ dlloader_data field.
+ (sys_dl_open): Take an additional lt_dlloader_data_t argument.
+ (sys_dl_close): Ditto.
+ (sys_dl_sym): Ditto.
+ (sys_dl): Initialise lt_dlloader_data_t field.
+ (sys_shl_open, sys_shl_close, sys_shl_sym, sys_shl): As above.
+ (sys_wll_open, sys_wll_close, sys_wll_sym, sys_wll): As above.
+ (sys_bedl_open, sys_bedl_close, sys_bedl_sym, sys_bedl): As
+ above.
+ (sys_dld_open, sys_dld_close, sys_dld_sym, sys_dld): As above.
+ (presym_init, presym_exit, presym_open, presym_close, presym_sym,
+ presym): As above.
+ (lt_dlinit): Call presym_init with additional argument.
+ (lt_dlexit): Call dlloader_exit method with additional argument.
+ (tryall_dlopen): Call module_open method with additional argument.
+ (lt_dlclose): Call module_close method with additional argument.
+ (lt_dlsym): Call find_sym method with additional argument.
+ (lt_add_dlloader): Initialise dlloader_data field.
+ (lt_remove_dlloader): Call dlloader_exit method with additional
+ argument.
+
* libltdl/ltdl.c (find_file): Prevent early release of memory
in filename/*pdir.
From Jon Leichter <jon@symas.com>
@code{lt_dlloader_t} is a handle for module loader types.
@end deftp
-@deftypefn {Type} {struct} lt_user_dlloader @{@w{const char *@var{sym_prefix};} @w{lt_module_open_t *@var{module_open};} @w{lt_module_close_t *@var{module_close};} @w{lt_find_sym_t *@var{find_sym};} @w{lt_dlloader_exit_t *@var{dlloader_exit};} @}
+@deftp {Type} lt_dlloader_data_t
+@code{lt_dlloader_data_t} is used for specifying loader instance data.
+@end deftp
+
+@deftypefn {Type} {struct} lt_user_dlloader @{@w{const char *@var{sym_prefix};} @w{lt_module_open_t *@var{module_open};}@w{lt_module_close_t *@var{module_close};} @w{lt_find_sym_t *@var{find_sym};} @w{lt_dlloader_exit_t *@var{dlloader_exit};} @w{lt_dlloader_data_t @var{dlloader_data};} @}
If you want to define a new way to open dynamic modules, and have the
@code{lt_dlopen} @sc{api} use it, you need to instantiate one of these
-structures and pass it to @code{lt_add_dlloader}.
+structures and pass it to @code{lt_add_dlloader}. You can pass whatever
+you like in the @var{dlloader_data} field, and it will be passed back as
+the value of the first parameter to each of the functions specified in
+the function pointer fields.
@end deftypefn
-@deftypefn {Type} lt_module_t lt_module_open_t (@w{const char *@var{filename}})
+@deftypefn {Type} lt_module_t lt_module_open_t (@w{lt_dlloader_data_t @var{loader_data},} @w{const char *@var{filename}})
The type of the loader function for an @code{lt_dlloader_t} module
-loader. Implementation of such a function should attempt to load the
-named module, and return an @code{lt_module_t} suitable for passing in
-to the associated @code{lt_module_close_t} and @code{lt_sym_find_t}
-function pointers. If the function fails it should return NULL, and set
-the error message with @code{lt_dlseterror}.
+loader. The value set in the dlloader_data field of the @code{struct
+lt_user_dlloader} structure will be passed into this function in the
+@var{loader_data} parameter. Implementation of such a function should
+attempt to load the named module, and return an @code{lt_module_t}
+suitable for passing in to the associated @code{lt_module_close_t} and
+@code{lt_sym_find_t} function pointers. If the function fails it should
+return NULL, and set the error message with @code{lt_dlseterror}.
@end deftypefn
-@deftypefn {Type} int lt_module_close_t (@w{lt_module_t @var{module}})
+@deftypefn {Type} int lt_module_close_t (@w{lt_dlloader_data_t @var{loader_data},} @w{lt_module_t @var{module}})
The type of the unloader function for a user defined module loader.
Implementatation of such a function should attempt to release
any resources tied up by the @var{module} module, and then unload it
message with @code{lt_dlseterror} and return non-zero.
@end deftypefn
-@deftypefn {Type} lt_ptr_t lt_find_sym_t (@w{lt_module_t @var{module},} @w{const char *@var{symbol}})
+@deftypefn {Type} lt_ptr_t lt_find_sym_t (@w{lt_dlloader_data_t @var{loader_data},} @w{lt_module_t @var{module},} @w{const char *@var{symbol}})
The type of the symbol lookup function for a user defined module loader.
Implementation of such a function should return the address of the named
@var{symbol} in the module @var{module}, or else set the error message
with @code{lt_dlseterror} and return NULL if lookup fails.
@end deftypefn
-@deftypefn {Type} int lt_dlloader_exit_t (void)
+@deftypefn {Type} int lt_dlloader_exit_t (@w{lt_dlloader_data_t @var{loader_data}})
The type of the finalisation function for a user defined module loader.
Implementation of such a function should free any resources associated
-with the loader. If non-NULL, the function will be called by
-@code{lt_dlexit}.
+with the loader, including any user specified data in the
+@code{dlloader_data} field of the @code{lt_user_dlloader}. If non-NULL,
+the function will be called by @code{lt_dlexit}, and
+@code{lt_remove_dlloader}.
@end deftypefn
For example:
dlloader.module_close = myloader_close;
dlloader.find_sym = myloader_find_sym.
dlloader.dlloader_exit = myloader_exit;
+ dlloader.dlloader_data = (lt_dlloader_data_t)myloader_function;
/* Add my loader as the default module loader. */
if (lt_add_dlloader (lt_next_dlloader (NULL), &dlloader, "myloader") != 0)
@end example
@end deftypefun
-@deftypefun char *lt_dlloader_name (@w{lt_dlloader_t *@var{place}})
+@deftypefun const char *lt_dlloader_name (@w{lt_dlloader_t *@var{place}})
Return the identifying name of @var{PLACE}, as obtained from
@code{lt_next_dlloader} or @code{lt_find_dlloader}. If this function fails,
it will return @code{NULL} and set an error for retrieval with
@code{lt_dlerror}.
@end deftypefun
+@deftypefun lt_dlloader_data_t *lt_dlloader_data (@w{lt_dlloader_t *@var{place}})
+Return the address of the @code{dlloader_data} of @var{PLACE}, as
+obtained from @code{lt_next_dlloader} or @code{lt_find_dlloader}. If
+this function fails, it will return @code{NULL} and set an error for
+retrieval with @code{lt_dlerror}.
+@end deftypefun
+
@subsection Error handling within user module loaders
@deftypefun int lt_dladderror (@w{const char *@var{diagnostic}})
struct lt_dlloader_t *next;
const char *loader_name; /* identifying name for each loader */
const char *sym_prefix; /* prefix for symbols */
- lt_dlloader_exit_t *dlloader_exit;
lt_module_open_t *module_open;
lt_module_close_t *module_close;
lt_find_sym_t *find_sym;
+ lt_dlloader_exit_t *dlloader_exit;
+ lt_dlloader_data_t dlloader_data;
};
typedef struct lt_dlhandle_t {
# endif
#endif
+/*ARGSUSED*/
static lt_module_t
-sys_dl_open (filename)
+sys_dl_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
lt_module_t module = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
return module;
}
+/*ARGSUSED*/
static int
-sys_dl_close (module)
+sys_dl_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
{
if (dlclose(module) != 0) {
return 0;
}
+/*ARGSUSED*/
static lt_ptr_t
-sys_dl_sym (module, symbol)
+sys_dl_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
const char *symbol;
{
# else
0,
# endif
- sys_dl_open, sys_dl_close, sys_dl_sym, 0 };
+ sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
#endif
#if HAVE_SHL_LOAD
#define LTDL_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
+/*ARGSUSED*/
static lt_module_t
-sys_shl_open (filename)
+sys_shl_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
lt_module_t module = shl_load(filename, LTDL_BIND_FLAGS, 0L);
return module;
}
+/*ARGSUSED*/
static int
-sys_shl_close (module)
+sys_shl_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
{
if (shl_unload((shl_t) (module)) != 0) {
return 0;
}
+/*ARGSUSED*/
static lt_ptr_t
-sys_shl_sym (module, symbol)
+sys_shl_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
const char *symbol;
{
}
static struct lt_user_dlloader
-sys_shl = { 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0 };
+sys_shl = { 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0 };
#undef LTDL_TYPE_TOP
#define LTDL_TYPE_TOP &sys_shl
/* Forward declaration; required to implement handle search below. */
static lt_dlhandle handles;
+/*ARGSUSED*/
static lt_module_t
-sys_wll_open (filename)
+sys_wll_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
lt_dlhandle cur;
return module;
}
+/*ARGSUSED*/
static int
-sys_wll_close (module)
+sys_wll_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
{
if (FreeLibrary(module) == 0) {
return 0;
}
+/*ARGSUSED*/
static lt_ptr_t
-sys_wll_sym (module, symbol)
+sys_wll_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
const char *symbol;
{
}
static struct lt_user_dlloader
-sys_wll = { 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0 };
+sys_wll = { 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0 };
#endif
#include <kernel/image.h>
+/*ARGSUSED*/
static lt_module_t
-sys_bedl_open (filename)
+sys_bedl_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
image_id image = 0;
return (lt_module_t) image;
}
+/*ARGSUSED*/
static int
-sys_bedl_close (module)
+sys_bedl_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
{
if (unload_add_on((image_id)module) != B_OK) {
return 0;
}
+/*ARGSUSED*/
static lt_ptr_t
-sys_bedl_sym (module, symbol)
+sys_bedl_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
const char *symbol;
{
}
static struct lt_user_dlloader
-sys_bedl = { 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0 };
+sys_bedl = { 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0 };
#endif
#include <dld.h>
#endif
+/*ARGSUSED*/
static lt_module_t
-sys_dld_open (filename)
+sys_dld_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
lt_module_t module = strdup(filename);
return module;
}
+/*ARGSUSED*/
static int
-sys_dld_close (module)
+sys_dld_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
{
if (dld_unlink_by_file((char*)(module), 1) != 0) {
return 0;
}
+/*ARGSUSED*/
static lt_ptr_t
-sys_dld_sym (module, symbol)
+sys_dld_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
const char *symbol;
{
}
static struct lt_user_dlloader
-sys_dld = { 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0 };
+sys_dld = { 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 };
#endif
static const lt_dlsymlist *default_preloaded_symbols = 0;
static lt_dlsymlists_t *preloaded_symbols = 0;
+/*ARGSUSED*/
static int
-presym_init LTDL_PARAMS((void))
+presym_init (loader_data)
+ lt_dlloader_data_t loader_data;
{
preloaded_symbols = 0;
if (default_preloaded_symbols)
return 0;
}
+/*ARGSUSED*/
static int
-presym_exit LTDL_PARAMS((void))
+presym_exit (loader_data)
+ lt_dlloader_data_t loader_data;
{
presym_free_symlists();
return 0;
return 0;
}
+/*ARGSUSED*/
static lt_module_t
-presym_open (filename)
+presym_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
lt_dlsymlists_t *lists = preloaded_symbols;
return 0;
}
+/*ARGSUSED*/
static int
-presym_close (module)
+presym_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
{
/* Just to silence gcc -Wall */
return 0;
}
+/*ARGSUSED*/
static lt_ptr_t
-presym_sym (module, symbol)
+presym_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
lt_module_t module;
const char *symbol;
{
}
static struct lt_user_dlloader
-presym = { 0, presym_open, presym_close, presym_sym, presym_exit };
+presym = { 0, presym_open, presym_close, presym_sym, presym_exit, 0 };
static char *user_search_path = 0;
errors += lt_add_dlloader (lt_next_dlloader(0), &sys_dld, "dld");
#endif
errors += lt_add_dlloader (lt_next_dlloader(0), &presym, "dlpreload");
- if (presym_init()) {
+ if (presym_init(presym.dlloader_data)) {
last_error = LT_DLSTRERROR(INIT_LOADER);
return 1;
- }
+ }
if (errors != 0) {
last_error = LT_DLSTRERROR(DLOPEN_NOT_SUPPORTED);
/* close all loaders */
while (loader) {
lt_dlloader_t *next = loader->next;
- if (loader->dlloader_exit && loader->dlloader_exit())
+ lt_dlloader_data_t data = loader->dlloader_data;
+ if (loader->dlloader_exit && loader->dlloader_exit(data))
errors++;
lt_dlfree (loader);
loader = next;
} else
cur->info.filename = 0;
while (loader) {
- cur->module = loader->module_open(filename);
+ lt_dlloader_data_t data = loader->dlloader_data;
+ cur->module = loader->module_open(data, filename);
if (cur->module != 0)
break;
loader = loader->next;
handle->info.ref_count--;
if (!handle->info.ref_count) {
int error;
+ lt_dlloader_data_t data = handle->loader->dlloader_data;
if (handle != handles)
last->next = handle->next;
else
handles = handle->next;
- error = handle->loader->module_close(handle->module);
+ error = handle->loader->module_close(data, handle->module);
error += unload_deplibs(handle);
if (handle->info.filename)
lt_dlfree(handle->info.filename);
char lsym[LTDL_SYMBOL_LENGTH];
char *sym;
lt_ptr_t address;
+ lt_dlloader_data_t data;
if (!handle) {
last_error = LT_DLSTRERROR(INVALID_HANDLE);
last_error = LT_DLSTRERROR(BUFFER_OVERFLOW);
return 0;
}
+ data = handle->loader->dlloader_data;
if (handle->info.name) {
const char *saved_error = last_error;
strcat(sym, "_LTX_");
strcat(sym, symbol);
/* try "modulename_LTX_symbol" */
- address = handle->loader->find_sym(handle->module, sym);
+ address = handle->loader->find_sym(data, handle->module, sym);
if (address) {
if (sym != lsym)
lt_dlfree(sym);
strcat(sym, symbol);
} else
strcpy(sym, symbol);
- address = handle->loader->find_sym(handle->module, sym);
+ address = handle->loader->find_sym(data, handle->module, sym);
if (sym != lsym)
lt_dlfree(sym);
return address;
node->module_open = dlloader->module_open;
node->module_close = dlloader->module_close;
node->find_sym = dlloader->find_sym;
+ node->dlloader_data = dlloader->dlloader_data;
if (!loaders)
/* If there are no loaders, NODE becomes the list! */
prev->next = prev->next->next;
}
if (place->dlloader_exit)
- result = place->dlloader_exit ();
+ result = place->dlloader_exit (place->dlloader_data);
lt_dlfree (place);
return result;
return place ? place->loader_name : 0;
}
+lt_dlloader_data_t *
+lt_dlloader_data (place)
+ lt_dlloader_t *place;
+{
+ if (!place)
+ last_error = LT_DLSTRERROR(INVALID_LOADER);
+ return place ? &(place->dlloader_data) : 0;
+}
+
lt_dlloader_t *
lt_find_dlloader (loader_name)
const char *loader_name;