From: Gary V. Vaughan Date: Sat, 2 Dec 2000 23:50:54 +0000 (+0000) Subject: * doc/libtool.texi (Libltdl interface): Add documentation. X-Git-Tag: release-1-3d~52 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ae2e67203dbf57cfad460aab16b7ca93f07acce;p=thirdparty%2Flibtool.git * 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. --- diff --git a/ChangeLog b/ChangeLog index 8e7f16800..8c0032acc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14 +1,24 @@ 2000-12-01 Gary V. Vaughan + * 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 diff --git a/TODO b/TODO index f8d9641a1..3867f3bbe 100644 --- 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? diff --git a/doc/libtool.texi b/doc/libtool.texi index 7cb5248ff..48ac08f19 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -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. diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index 97db20059..b8ea56ebe 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -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; diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h index 1ae64bb45..60434cf76 100644 --- a/libltdl/ltdl.h +++ b/libltdl/ltdl.h @@ -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 {