]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
* doc/libtool.texi (Libltdl interface): Add documentation.
authorGary V. Vaughan <gary@gnu.org>
Sat, 2 Dec 2000 23:50:54 +0000 (23:50 +0000)
committerGary V. Vaughan <gary@gnu.org>
Sat, 2 Dec 2000 23:50:54 +0000 (23:50 +0000)
* libltdl/ltdl.h (lt_dlmakeresident, lt_dlisresident):  Add
prototypes.
(LT_DLERROR_CLOSE_RESIDENT_MODULE): New error status.
* libltdl/ltdl.c (lt_dlmakeresident, lt_dlisresident):  Allow
making and testing of resident module status, which prevents a
module from being lt_dlclosed.
(lt_dlopen):  If lt_dlopen()ing self, make the module resident.
(lt_dlclose):  Return an error if the module is resident.

ChangeLog
TODO
doc/libtool.texi
libltdl/ltdl.c
libltdl/ltdl.h

index 8e7f168004e9c2a5e704d391983cf098afb68df5..8c0032acc0b8b0319d7cdf504e3f5d70a07bea97 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,14 +1,24 @@
 2000-12-01  Gary V. Vaughan  <gvv@techie.com>
 
+       * doc/libtool.texi (Libltdl interface):  Add documentation.
+       * libltdl/ltdl.h (lt_dlmakeresident, lt_dlisresident):  Add
+       prototypes.
+       (LT_DLERROR_CLOSE_RESIDENT_MODULE): New error status.
+       * libltdl/ltdl.c (lt_dlmakeresident, lt_dlisresident):  Allow
+       making and testing of resident module status, which prevents a
+       module from being lt_dlclosed.
+       (lt_dlopen):  If lt_dlopen()ing self, make the module resident.
+       (lt_dlclose):  Return an error if the module is resident.
+
        * libtool.m4 (_LT_AC_LTCONFIG_HACK): Move the tests for dlopen
        from here...
-       (AC_LTDL_DLOPEN_SELF): ...to here.
-       (_LTDL_AC_CHECK_DLFCN):  Factor out repeated code for dlfcn.h
+       (AC_LIBTOOL_DLOPEN_SELF): ...to here.
+       (_LT_AC_CHECK_DLFCN):  Factor out repeated code for dlfcn.h
        (_LT_AC_TRY_DLOPEN_SELF): Factor out repeated code for
        checking dlopen status.
-       * ltdl.m4 (AC_LIB_LTDL):  Use _LTDL_AC_CHECK_DLFCN.
-       dlopen compile time checking.  Use _LTDL_AC_CHECK_DLFCN.
-       (AC_LTDL_DLSYM_USCORE):  Use _LTDL_AC_TRY_DLOPEN_SELF.
+       * ltdl.m4 (AC_LIB_LTDL):  Use _LT_AC_CHECK_DLFCN.
+       dlopen compile time checking.  Use _LT_AC_CHECK_DLFCN.
+       (AC_LTDL_DLSYM_USCORE):  Use _LT_AC_TRY_DLOPEN_SELF.
 
 2000-11-29  Gary V. Vaughan  <gvv@techie.com>
 
diff --git a/TODO b/TODO
index f8d9641a13b427aff7f266ca5302c07060ec3ad9..3867f3bbe6e655f11ed403cb51d0bb62207758ba 100644 (file)
--- a/TODO
+++ b/TODO
@@ -128,3 +128,10 @@ like libtool should be distributed as part of such a binary package.
 * Maybe implement full support for other orthogonal library types
 (libhello_g, libhello_p, 64 vs 32-bit ABI's, etc).  Make these types
 configurable.
+
+* Perhaps the iuse of libltdl could be made cleaner by allowing
+registration of hook functions to call at various points.  This would
+hopefully free the user from having to maintain a parallel module
+list with user data.  This would likely involve being able to carry
+additional per user module data in the lt_dlmodule structure -- perhaps
+in the form of an associative array keyed by user name?
index 7cb5248ff9afe581b1557fb142338e1d7b4a529b..48ac08f199d88e9f08f16c23d1243a4c4514e5b2 100644 (file)
@@ -2846,6 +2846,23 @@ directories.  Return 0 on success.
 Return the current user-defined library search path.
 @end deftypefun
 
+@deftypefun int lt_dlmakeresident (lt_dlhandle @var{handle})
+Mark a module so that it cannot be @samp{lt_dlclose}d.  This can be
+useful if a module implements some core functionality in your project,
+which would cause your code to crash if removed.  Return 0 on success.
+
+If you use @samp{lt_dlopen (NULL)} to get a @var{handle} for the running
+binary, that handle will always be marked as resident, and consequently
+cannot be successfully @samp{lt_dlclose}d.
+@end deftypefun
+
+@deftypefun int lt_dlisresident (lt_dlhandle @var{handle})
+Check whether a particular module has be marked as resident, returning 1
+if it has or 0 otherwise.  If there is an error while executing this
+function, return -1 and set an error message for retrieval with
+@code{lt_dlerror}.
+@end deftypefun
+
 @deftypefun {const lt_dlinfo *}lt_dlgetinfo (lt_dlhandle @var{handle})
 Return a pointer to a struct that contains some information about
 the module @var{handle}.  The contents of the struct must not be modified.
index 97db2005908a6d73e4e1b2195fc759f99655258f..b8ea56ebebc7587f6ddb22f2b16be3a5cbf20d8d 100644 (file)
@@ -122,8 +122,20 @@ struct lt_dlhandle_struct {
   lt_dlhandle         *deplibs;        /* dependencies */
   lt_module            module;         /* system module handle */
   lt_ptr               system;         /* system specific data */
+  int                  flags;          /* various boolean stats */
 };
 
+/* Various boolean flags can be stored in the flags field of an
+   lt_dlhandle_struct... */
+#define LT_DLGET_FLAG(handle, flag) ((handle)->flags&(flag) == (flag))
+#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
+
+#define LT_DLRESIDENT_FLAG         (0x01 << 0)
+/* ...add more flags here... */
+
+#define LT_DLIS_RESIDENT(handle)    LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
+
+
 static const char      objdir[]                = LTDL_OBJDIR;
 #ifdef LTDL_SHLIB_EXT
 static const char      shlib_ext[]             = LTDL_SHLIB_EXT;
@@ -1089,15 +1101,21 @@ lt_dlexit ()
     {
       int      level;
 
+      while (handles && LT_DLIS_RESIDENT (handles))
+       {
+         handles = handles->next;
+       }
+
       /* close all modules */
       for (level = 1; handles; ++level)
        {
          lt_dlhandle cur = handles;
+
          while (cur)
            {
              lt_dlhandle tmp = cur;
              cur = cur->next;
-             if (tmp->info.ref_count <= level)
+             if (!LT_DLIS_RESIDENT (cur) && tmp->info.ref_count <= level)
                {
                  if (lt_dlclose (tmp))
                    {
@@ -1630,7 +1648,12 @@ unload_deplibs(handle)
   if (handle->depcount)
     {
       for (i = 0; i < handle->depcount; ++i)
-       errors += lt_dlclose (handle->deplibs[i]);
+       {
+         if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
+           {
+             errors += lt_dlclose (handle->deplibs[i]);
+           }
+       }
     }
 
   return errors;
@@ -1712,6 +1735,9 @@ lt_dlopen (filename)
       handle->deplibs          = 0;
       newhandle                        = handle;
 
+      /* lt_dlclose()ing yourself is very bad!  Disallow it.  */
+      LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
+
       if (tryall_dlopen (&newhandle, 0) != 0)
        {
          lt_dlfree(handle);
@@ -2012,7 +2038,7 @@ lt_dlopen (filename)
       handle = newhandle;
     }
 
-  if (!handle->info.ref_count)
+  if (handle->info.ref_count == 0)
     {
       handle->info.ref_count   = 1;
       handle->info.name                = name;
@@ -2131,7 +2157,11 @@ lt_dlclose (handle)
 
   handle->info.ref_count--;
 
-  if (!handle->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))
     {
       int      error;
       lt_user_data data = handle->loader->dlloader_data;
@@ -2163,6 +2193,12 @@ lt_dlclose (handle)
       return error;
     }
 
+  if (LT_DLIS_RESIDENT (handle))
+    {
+      last_error = LT_DLSTRERROR (CLOSE_RESIDENT_MODULE);
+      return 1;
+    }
+      
   return 0;
 }
 
@@ -2345,6 +2381,34 @@ lt_dlgetsearchpath ()
   return user_search_path;
 }
 
+int
+lt_dlmakeresident (handle)
+     lt_dlhandle handle;
+{
+  if (!handle)
+    {
+      last_error = LT_DLSTRERROR (INVALID_HANDLE);
+      return -1;
+    }
+
+  LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
+
+  return 0;
+}
+
+int
+lt_dlisresident        (handle)
+     lt_dlhandle handle;
+{
+  if (!handle)
+    {
+      last_error = LT_DLSTRERROR (INVALID_HANDLE);
+      return -1;
+    }
+
+  return LT_DLIS_RESIDENT (handle);
+}
+
 const lt_dlinfo *
 lt_dlgetinfo (handle)
      lt_dlhandle handle;
index 1ae64bb45a9c083563312d70a3b4e18a7edd70ca..60434cf76acffef928efd629e8aeb15eef87c127 100644 (file)
@@ -159,6 +159,10 @@ extern     lt_ptr      lt_dlsym            LT_PARAMS((lt_dlhandle handle,
 extern const char *lt_dlerror          LT_PARAMS((void));
 extern int         lt_dlclose          LT_PARAMS((lt_dlhandle handle));
 
+/* Module residency management. */
+extern int         lt_dlmakeresident   LT_PARAMS((lt_dlhandle handle));
+extern int         lt_dlisresident     LT_PARAMS((lt_dlhandle handle));
+
 /* Pointers to memory management functions to be used by libltdl. */
 LT_SCOPE  lt_ptr   (*lt_dlmalloc)      LT_PARAMS((size_t size));
 LT_SCOPE  void    (*lt_dlfree)         LT_PARAMS((lt_ptr ptr));
@@ -269,7 +273,8 @@ extern      int             lt_dlloader_remove  LT_PARAMS((
     LT_ERROR(INVALID_HANDLE,       "invalid module handle")            \
     LT_ERROR(BUFFER_OVERFLOW,      "internal buffer overflow")         \
     LT_ERROR(INVALID_ERRORCODE,     "invalid errorcode")               \
-    LT_ERROR(SHUTDOWN,             "library already shutdown")
+    LT_ERROR(SHUTDOWN,             "library already shutdown")         \
+    LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module")
 
 /* Enumerate the symbolic error names. */
 enum {