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. diff -ur ../libtool.orig/doc/libtool.texi ./doc/libtool.texi --- ../libtool.orig/doc/libtool.texi Tue Nov 21 08:36:50 2000 +++ ./doc/libtool.texi Fri Dec 1 12:08:03 2000 @@ -2846,6 +2846,23 @@ Return the current user-defined library search path. @end deftypefun address@hidden 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. address@hidden deftypefun + address@hidden 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 address@hidden address@hidden 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 -ur ../libtool.orig/doc/stamp-vti ./doc/stamp-vti --- ../libtool.orig/doc/stamp-vti Wed Nov 29 19:22:27 2000 +++ ./doc/stamp-vti Fri Dec 1 12:18:57 2000 @@ -1,3 +1,3 @@ address@hidden UPDATED 21 November 2000 address@hidden UPDATED 1 December 2000 @set EDITION 1.3c @set VERSION 1.3c diff -ur ../libtool.orig/doc/version.texi ./doc/version.texi --- ../libtool.orig/doc/version.texi Wed Nov 29 19:22:27 2000 +++ ./doc/version.texi Fri Dec 1 12:18:57 2000 @@ -1,3 +1,3 @@ address@hidden UPDATED 21 November 2000 address@hidden UPDATED 1 December 2000 @set EDITION 1.3c @set VERSION 1.3c diff -ur ../libtool.orig/libltdl/ltdl.c ./libltdl/ltdl.c --- ../libtool.orig/libltdl/ltdl.c Wed Nov 29 22:49:43 2000 +++ ./libltdl/ltdl.c Fri Dec 1 12:56:46 2000 @@ -122,8 +122,20 @@ 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; @@ -1712,6 +1724,9 @@ 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 +2027,7 @@ handle = newhandle; } - if (!handle->info.ref_count) + if (handle->info.ref_count == 0) { handle->info.ref_count = 1; handle->info.name = name; @@ -2131,7 +2146,11 @@ 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 +2182,12 @@ return error; } + if (LT_DLIS_RESIDENT (handle)) + { + last_error = LT_DLSTRERROR (CLOSE_RESIDENT_MODULE); + return 1; + } + return 0; } @@ -2343,6 +2368,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 * diff -ur ../libtool.orig/libltdl/ltdl.h ./libltdl/ltdl.h --- ../libtool.orig/libltdl/ltdl.h Wed Nov 29 22:07:08 2000 +++ ./libltdl/ltdl.h Fri Dec 1 11:34:36 2000 @@ -159,6 +159,10 @@ 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 @@ 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 {