]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
* doc/libtool.texi (User defined module data)
authorRalf Wildenhues <Ralf.Wildenhues@gmx.de>
Tue, 4 Sep 2007 18:01:33 +0000 (18:01 +0000)
committerRalf Wildenhues <Ralf.Wildenhues@gmx.de>
Tue, 4 Sep 2007 18:01:33 +0000 (18:01 +0000)
<lt_dlinterface_register>: Document that a NULL place matches
all modules.
* libltdl/lt_dlloader.c (lt_dlloader_remove): Actually iterate
over all open modules when looking for modules that use it.
If a resident module is found, return but do not set the error
string.
* libltdl/ltdl.c (lt_dlexit): When removing dlloaders, ignore
errors that stem from earlier failed commands.  Exposed by the
lt_dladvise test.
Fixes regression over branch-1-5.
Memleak report as Coverity CID 19 via Jeff Squyres.

ChangeLog
doc/libtool.texi
libltdl/lt_dlloader.c
libltdl/ltdl.c

index ec8d6db2e22ecfcc149807c9775adf8e0487aa01..0811fdf1644f9b6f5a9d78950fa1359ff41afd04 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2007-09-04  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
+
+       * doc/libtool.texi (User defined module data)
+       <lt_dlinterface_register>: Document that a NULL place matches
+       all modules.
+       * libltdl/lt_dlloader.c (lt_dlloader_remove): Actually iterate
+       over all open modules when looking for modules that use it.
+       If a resident module is found, return but do not set the error
+       string.
+       * libltdl/ltdl.c (lt_dlexit): When removing dlloaders, ignore
+       errors that stem from earlier failed commands.  Exposed by the
+       lt_dladvise test.
+       Fixes regression over branch-1-5.
+       Memleak report as Coverity CID 19 via Jeff Squyres.
+
 2007-09-01  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        * NEWS: Update.
index e1939fdb132307c68798a192f53e6de82d51f216..e5a58b8f848f2d010edf024fa4b1e9cc2f2a6a9b 100644 (file)
@@ -4022,7 +4022,8 @@ Use this function to register your interface validator with libltdl,
 and in return obtain a unique key to store and retrieve per-module data.
 You supply an @var{id_string} and @var{iface} so that the resulting
 @code{lt_dlinterface_id} can be used to filter the module handles
-returned by the iteration functions below.
+returned by the iteration functions below.  If @var{iface} is @code{NULL},
+all modules will be matched.
 @end deftypefun
 
 @deftypefun void lt_dlinterface_free (@w{lt_dlinterface_id @var{iface}})
index 82e98cdf2b294c70667a133970313273c516f4a4..80f6cfb347382be1ffecdf9c55c99b89558884bf 100644 (file)
@@ -146,13 +146,18 @@ lt_dlloader_get   (lt_dlloader loader)
 /* Return the contents of the first item in the global loader list
    with a matching NAME after removing it from that list.  If there
    was no match, return NULL; if there is an error, return NULL and
-   set an error for lt_dlerror; in either case, the loader list is
-   not changed if NULL is returned.  */
+   set an error for lt_dlerror; do not set an error if only resident
+   modules need this loader; in either case, the loader list is not
+   changed if NULL is returned.  */
 lt_dlvtable *
 lt_dlloader_remove (char *name)
 {
   const lt_dlvtable *  vtable  = lt_dlloader_find (name);
-  lt__handle *         handle  = 0;
+  static const char    id_string[] = "lt_dlloader_remove";
+  lt_dlinterface_id    iface;
+  lt_dlhandle          handle = 0;
+  int                  in_use = 0;
+  int                  in_use_by_resident = 0;
 
   if (!vtable)
     {
@@ -161,14 +166,24 @@ lt_dlloader_remove (char *name)
     }
 
   /* Fail if there are any open modules which use this loader.  */
-  for  (handle = 0; handle; handle = handle->next)
+  iface = lt_dlinterface_register (id_string, NULL);
+  while ((handle = lt_dlhandle_iterate (iface, handle)))
     {
-      if (handle->vtable == vtable)
+      lt__handle *cur = (lt__handle *) handle;
+      if (cur->vtable == vtable)
        {
-         LT__SETERROR (REMOVE_LOADER);
-         return 0;
+         in_use = 1;
+         if (lt_dlisresident (handle))
+           in_use_by_resident = 1;
        }
     }
+  lt_dlinterface_free (iface);
+  if (in_use)
+    {
+      if (!in_use_by_resident)
+       LT__SETERROR (REMOVE_LOADER);
+      return 0;
+    }
 
   /* Call the loader finalisation function.  */
   if (vtable && vtable->dlloader_exit)
index 05f97fdddccebcbd1967411f1c43270886b5e73f..cfc61004b5cb1328d262ff0362d55d56c1660044 100644 (file)
@@ -310,6 +310,12 @@ lt_dlexit (void)
            break;
        }
 
+      /* When removing loaders, we can only find out failure by testing
+        the error string, so avoid a spurious one from an earlier
+        failed command. */
+      if (!errors)
+       LT__SETERRORSTR (0);
+
       /* close all loaders */
       for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;)
        {
@@ -322,7 +328,11 @@ lt_dlexit (void)
            }
          else
            {
-             ++errors;
+             /* ignore errors due to resident modules */
+             const char *err;
+             LT__GETERROR (err);
+             if (err)
+               ++errors;
            }
 
          loader = next;