diff --git a/doc/libtool.texi b/doc/libtool.texi index 482e635..172e273 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -4282,16 +4282,24 @@ can be recognised by @code{lt_dlloader_find} and removed with already in use by libltdl's builtin loaders: @table @asis address@hidden "dlopen" -The system dynamic library loader, if one exists. address@hidden "dld" address@hidden "lt_dlopen" +The POSIX dynamic library loader, if one exists. address@hidden "lt_dld_link" The @sc{gnu} dld loader, if @file{libdld} was installed when libltdl was built. address@hidden "dlpreload" -The loader for @code{lt_dlopen}ing of preloaded static modules. address@hidden "lt_preopen" +The loader for @code{lt_dlopen}ing of preopened static modules. address@hidden "lt_dyld" +The Darwin / OS X dynamic library loader. address@hidden "lt_load_add_on" +The BeOS dynamic library loader. address@hidden "lt_loadlibrary" +The Windows dynamic library loader. address@hidden "lt_shl_load" +The HP/UX dynamic library loader. @end table -The prefix "dl" is reserved for loaders supplied with future versions of +The prefix "lt_" is reserved for loaders supplied with future versions of libltdl, so you should not use that for your own loader names. @noindent @@ -4311,7 +4319,11 @@ level types. @code{lt_user_data} is used for specifying loader instance data. @end deftp address@hidden {Type} {struct} lt_user_dlloader @address@hidden char address@hidden;} @w{lt_module_open address@hidden;} @w{lt_module_close address@hidden;} @w{lt_find_sym address@hidden;} @w{lt_dlloader_exit address@hidden;} @} address@hidden {Type} lt_dlloader_priority address@hidden is used for specifying the loader priority. address@hidden deftp + address@hidden {Type} {struct} lt_dlvtable @address@hidden char address@hidden;} @w{const char address@hidden;} @w{lt_module_open address@hidden;} @w{lt_module_close address@hidden;} @w{lt_find_sym address@hidden;} @w{lt_dlloader_init address@hidden;} @w{lt_dlloader_exit address@hidden;} @w{lt_user_data @var{dlloader_data};} @w{lt_dlloader_priority @var{priority};} @} 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_dlloader_add}. You can pass whatever @@ -4320,7 +4332,7 @@ the value of the first parameter to each of the functions specified in the function pointer fields. @end deftypefn address@hidden {Type} lt_module lt_module_open (@w{const char address@hidden) address@hidden {Type} lt_module lt_module_open (@w{lt_user_data @var{data},} @w{const char address@hidden,} @w{lt_dladvise @var{advise}}) The type of the loader function for an @code{lt_dlloader} module 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 @@ -4331,7 +4343,7 @@ suitable for passing in to the associated @code{lt_module_close} and return @code{NULL}, and set the error message with @code{lt_dlseterror}. @end deftypefn address@hidden {Type} int lt_module_close (@w{lt_user_data @var{loader_data},} @w{lt_module @var{module}}) address@hidden {Type} int lt_module_close (@w{lt_user_data @var{data},} @w{lt_module @var{module}}) The type of the unloader function for a user defined module loader. Implementation of such a function should attempt to release any resources tied up by the @var{module} module, and then unload it @@ -4339,18 +4351,18 @@ from memory. If the function fails for some reason, set the error message with @code{lt_dlseterror} and return non-zero. @end deftypefn address@hidden {Type} {void *} lt_find_sym (@w{lt_module @var{module},} @w{const char address@hidden) address@hidden {Type} {void *} lt_find_sym (@w{lt_user_data @var{data},} @w{lt_module @var{module},} @w{const char address@hidden) 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 @code{NULL} if lookup fails. @end deftypefn address@hidden {Type} int lt_dlloader_exit (@w{lt_user_data @var{loader_data}}) address@hidden {Type} int lt_dlloader_exit (@w{lt_user_data @var{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, including any user specified data in the address@hidden field of the @code{lt_user_dlloader}. If address@hidden, address@hidden field of the @code{lt_dlvtable}. If address@hidden, the function will be called by @code{lt_dlexit}, and @code{lt_dlloader_remove}. @end deftypefn @@ -4361,22 +4373,35 @@ For example: int register_myloader (void) @{ - lt_user_dlloader dlloader; + lt_dlvtable *myloader; + + myloader = malloc (sizeof (*myloader)); + if (!myloader) + return MEMORY_ERROR; /* User modules are responsible for their own initialisation. */ if (myloader_init () != 0) - return MYLOADER_INIT_ERROR; + @{ + free (myloader); + return MYLOADER_INIT_ERROR; + @} - dlloader.sym_prefix = NULL; - dlloader.module_open = myloader_open; - dlloader.module_close = myloader_close; - dlloader.find_sym = myloader_find_sym; - dlloader.dlloader_exit = myloader_exit; - dlloader.dlloader_data = (lt_user_data)myloader_function; + myloader->name = "myloader"; + myloader->sym_prefix = NULL; + myloader->module_open = myloader_open; + myloader->module_close = myloader_close; + myloader->find_sym = myloader_find_sym; + myloader->dlloader_exit = myloader_exit; + myloader->dlloader_data = (lt_user_data)myloader_function; + myloader->priority = LT_DLLOADER_PREPEND; /* Add my loader as the default module loader. */ - if (lt_dlloader_add (lt_dlloader_next (NULL), &dlloader, "myloader") != 0) - return ERROR; + if (lt_dlloader_add (myloader) != 0) + @{ + myloader_exit (myloader->dlloader_data); + free (myloader); + return ERROR; + @} return OK; @} @@ -4395,55 +4420,61 @@ during the initialisation phase. libltdl provides the following functions for writing your own module loaders: address@hidden int lt_dlloader_add (@w{lt_dlloader address@hidden,} @w{lt_user_dlloader address@hidden,} @w{const char address@hidden) address@hidden int lt_dlloader_add (@w{lt_dlvtable address@hidden) Add a new module loader to the list of all loaders, either as the -last loader (if @var{place} is @code{NULL}), else immediately before the -loader passed as @var{place}. @var{loader_name} will be returned by address@hidden if it is subsequently passed a newly -registered loader. These @var{loader_name}s must be unique, or address@hidden and @code{lt_dlloader_find} cannot -work. Returns 0 for success. +last loader (if @var{priority} in @var{dlloader} is set to address@hidden), else the first loader (if it is set +to @code{LT_DLLOADER_PREPEND}). The @var{loader_name} given in address@hidden will be returned by @code{lt_dlloader_name} if it +is subsequently passed a newly registered loader. These address@hidden must be unique, or @code{lt_dlloader_remove} +and @code{lt_dlloader_find} cannot work. Returns 0 for success. @example /* Make myloader be the last one. */ -if (lt_dlloader_add (NULL, myloader) != 0) - perror (lt_dlerror ()); +myloader.priority = LT_DLLOADER_APPEND; +if (lt_dlloader_add (&myloader) != 0) + fprintf (stderr, "lt_dlloader_add failed: %s\n", lt_dlerror ()); @end example @end deftypefun address@hidden int lt_dlloader_remove (@w{const char address@hidden) address@hidden {lt_dlvtable *}lt_dlloader_remove (@w{const char address@hidden) Remove the loader identified by the unique name, @var{loader_name}. Before this can succeed, all modules opened by the named loader must -have been closed. Returns 0 for success, otherwise an error message can -be obtained from @code{lt_dlerror}. +have been closed. Returns the vtable of the removed loader for success, +otherwise @code{NULL} in which case an error message can be obtained +from @code{lt_dlerror}. The caller is responsible for @code{free}ing the +returned @var{vtable}, if that is needed. @example /* Remove myloader. */ -if (lt_dlloader_remove ("myloader") != 0) - perror (lt_dlerror ()); +lt_dlvtable *myloader = lt_dlloader_remove ("myloader"); +if (myloader) + free (myloader); +else + fprintf (stderr, "lt_dlloader_remove failed: %s\n", lt_dlerror ()); +myloader = NULL; @end example @end deftypefun address@hidden {lt_dlloader *}lt_dlloader_next (@w{lt_dlloader address@hidden) -Iterate over the module loaders, returning the first loader if @var{place} is address@hidden, and the next one on subsequent calls. The handle is for use with address@hidden address@hidden lt_dlloader lt_dlloader_next (@w{const lt_dlloader @var{loader}}) +Iterate over the module loaders, returning the first loader if @var{loader} is address@hidden, and the next one on subsequent calls, or @code{NULL} if at the +end of the list. The handle is for use with @code{lt_dlloader_get}. @example -/* Make myloader be the first one. */ -if (lt_dlloader_add (lt_dlloader_next (NULL), myloader) != 0) - return ERROR; +/* Print the name of the first loader. */ +puts (lt_dlloader_get (lt_dlloader_next (NULL))->name); @end example @end deftypefun address@hidden {lt_dlloader *}lt_dlloader_find (@w{const char address@hidden) address@hidden {const lt_dlvtable *}lt_dlloader_find (@w{const char address@hidden) Return the first loader with a matching @var{loader_name} identifier, or else @code{NULL}, if the identifier is not found. The identifiers that may be used by libltdl itself, if the host -architecture supports them are @address@hidden is used for -the host dependent module loading @sc{api} -- @code{shl_load} and address@hidden for example}, @dfn{dld} and @dfn{dlpreload}. +architecture supports them are e.g. @dfn{lt_dlopen}, @dfn{lt_dld_link}, address@hidden, @dfn{lt_dyld} and @dfn{lt_loadlibrary}. @example /* Add a user loader as the next module loader to be tried if @@ -4453,20 +4484,13 @@ if (lt_dlloader_add (lt_dlloader_find ("dlopen"), myloader) != 0) @end example @end deftypefun address@hidden {const char *}lt_dlloader_name (@w{lt_dlloader address@hidden) -Return the identifying name of @var{PLACE}, as obtained from address@hidden or @code{lt_dlloader_find}. If this function fails, -it will return @code{NULL} and set an error for retrieval with address@hidden {const lt_dlvtable *}lt_dlloader_get (@w{lt_dlloader @var{loader}}) +This function returns the @var{vtable} associated with the @var{loader}, +as obtained from @code{lt_dlloader_next}. If this function fails, it +will return @code{NULL} and set an error for retrieval with @code{lt_dlerror}. @end deftypefun address@hidden {lt_user_data *}lt_dlloader_data (@w{lt_dlloader address@hidden) -Return the address of the @code{dlloader_data} of @var{PLACE}, as -obtained from @code{lt_dlloader_next} or @code{lt_dlloader_find}. If -this function fails, it will return @code{NULL} and set an error for -retrieval with @code{lt_dlerror}. address@hidden deftypefun - @subsection Error handling within user module loaders @deftypefun int lt_dladderror (@w{const char address@hidden) @@ -4480,7 +4504,7 @@ If the allocation of an identifier fails, this function returns -1. @example int myerror = lt_dladderror ("Doh!"); if (myerror < 0) - perror (lt_dlerror ()); + fprintf (stderr, "lt_dladderror failed: %s\n", lt_dlerror ()); @end example @end deftypefun @@ -4493,7 +4517,7 @@ interface. All of the standard errors used by libltdl are declared in @example if (lt_dlseterror (LTDL_ERROR_NO_MEMORY) != 0) - perror (lt_dlerror ()); + fprintf (stderr, "lt_dlseterror failed: %s\n", lt_dlerror ()); @end example @end deftypefun