Hi Charles, Eric, * Charles Wilson wrote on Thu, Nov 10, 2005 at 05:55:28AM CET: > Ralf Wildenhues wrote: > > > >There are several separate issues here: > > > >1) lt_dlhandle_iterate breakage of loadlibrary.c > >2) needed dlinterface_free (or maybe _unregister?) > > including documentation > >3) cygwin managed mount fix of loadlibrary.c > > or remove the cygwin-specific code of loadlibrary.c > >4) use either > > - only dlopen, or > > - first dlopen, then LoadLibrary > > on cygwin, or > > - make the choice configurable > > I think Ralf's issues (1) and (2) need fixing first
Please take a look at and test the following patches which should address (1), (2), and (3). I have not done a lot testing myself /yet/, so beware. I'm not so sure whether we should register/free the thing in loadlibrary every time instead of once at the start: those memory checker users always go nuts when they find a small, constant-amount of allocated memory not freed before exit(). (OTOH, we might be lucky in that there aren't any good checkers -- at least that I know of -- for mingw or cygwin ;-) Also, I wasn't sure whether paths on w32 (all incarnations) can be bound by MAX_PATH. The documentation for cygwin_conv_to_full_win32_path suggests that at least for cygwin this is safe. Cheers, Ralf 2005-11-12 Eric Blake <[EMAIL PROTECTED]>, Ralf Wildenhues <[EMAIL PROTECTED]> * libltdl/ltdl.h, libltdl/ltdl.c (lt_dlinterface_free): New function. * doc/libtool.texi (User defined module data): Document it. * libltdl/ltdl.c (lt_dlhandle_iterate): Fix endless loop. * libltdl/loaders/loadlibrary.c (iface_id): New variable. (loadlibrary__module_interface): New function. (get_vtable): Register it to `lt_dlinterface_register'. (get_vtable): Rewrite to catch up with lt_dlhandle_iterate interface change. Append dot only after w32 path conversion so it works on cygwin managed mounts. Index: doc/libtool.texi =================================================================== RCS file: /cvsroot/libtool/libtool/doc/libtool.texi,v retrieving revision 1.204 diff -u -r1.204 libtool.texi --- doc/libtool.texi 7 Nov 2005 14:35:35 -0000 1.204 +++ doc/libtool.texi 12 Nov 2005 12:57:07 -0000 @@ -3848,6 +3848,10 @@ returned by the iteration functions below. @end deftypefun [EMAIL PROTECTED] void lt_dlinterface_free (@w{lt_dlinterface_id @var{iface}}) +Release the data associated with @var{iface}. [EMAIL PROTECTED] deftypefun + @deftypefun int lt_dlhandle_map (@w{lt_dlinterface_id @var{iface}}, @w{int ([EMAIL PROTECTED]) (lt_dlhandle @var{handle}, void * @var{data})}, @w{void * @var{data}}) For each module that matches @var{iface}, call the function @var{func}. When writing the @var{func} callback function, the Index: libltdl/ltdl.h =================================================================== RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.h,v retrieving revision 1.82 diff -u -r1.82 ltdl.h --- libltdl/ltdl.h 26 Oct 2005 10:26:48 -0000 1.82 +++ libltdl/ltdl.h 12 Nov 2005 12:51:11 -0000 @@ -111,6 +111,7 @@ LT_SCOPE lt_dlinterface_id lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface); +LT_SCOPE void lt_dlinterface_free (lt_dlinterface_id key); LT_SCOPE void * lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data); LT_SCOPE void * lt_dlcaller_get_data (lt_dlinterface_id key, Index: libltdl/ltdl.c =================================================================== RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.c,v retrieving revision 1.236 diff -u -r1.236 ltdl.c --- libltdl/ltdl.c 26 Oct 2005 10:26:48 -0000 1.236 +++ libltdl/ltdl.c 12 Nov 2005 12:51:11 -0000 @@ -2033,6 +2033,13 @@ return (lt_dlinterface_id) interface_id; } +void lt_dlinterface_free (lt_dlinterface_id key) +{ + lt__interface_id *interface_id = (lt__interface_id *)key; + FREE (interface_id->id_string); + FREE (interface_id); +} + void * lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data) { @@ -2125,6 +2132,8 @@ if (!handle) handle = (lt__handle *) handles; + else + handle = handle->next; /* advance while the interface check fails */ while (handle && iterator->iface Index: libltdl/loaders/loadlibrary.c =================================================================== RCS file: /cvsroot/libtool/libtool/libltdl/loaders/loadlibrary.c,v retrieving revision 1.9 diff -u -r1.9 loadlibrary.c --- libltdl/loaders/loadlibrary.c 23 Sep 2005 07:58:42 -0000 1.9 +++ libltdl/loaders/loadlibrary.c 12 Nov 2005 12:51:13 -0000 @@ -50,6 +50,15 @@ static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); +static lt_dlinterface_id iface_id = 0; + +static int +loadlibrary__module_interface (lt_dlhandle handle, const char *id_string) +{ + /* we _need_ to look at every module, so pretend all belong to us */ + return 0; +} + /* Return the vtable for this loader, only the name and sym_prefix attributes (plus the virtual function implementations, obviously) change between loaders. */ @@ -61,6 +70,7 @@ if (!vtable) { vtable = lt__zalloc (sizeof *vtable); + iface_id = lt_dlinterface_register ("ltdl loadlibrary", loadlibrary__module_interface); } if (vtable && !vtable->name) @@ -84,6 +94,7 @@ + /* --- IMPLEMENTATION --- */ @@ -99,6 +110,7 @@ char *searchname = 0; char *ext; char self_name_buf[MAX_PATH]; + char wpath[MAX_PATH]; if (!filename) { @@ -109,24 +121,33 @@ } else { - ext = strrchr (filename, '.'); - } + if (LT_STRLEN (filename) >= MAX_PATH) + return 0; - if (ext) - { - /* FILENAME already has an extension. */ - searchname = lt__strdup (filename); - } - else - { - /* Append a `.' to stop Windows from adding an - implicit `.dll' extension. */ - searchname = MALLOC (char, 2+ LT_STRLEN (filename)); - if (searchname) - sprintf (searchname, "%s.", filename); +#if defined(__CYGWIN__) + cygwin_conv_to_full_win32_path (filename, wpath); +#else + strcpy(wpath, filename); +#endif + + ext = strrchr (wpath, '.'); + + if (ext) + { + /* FILENAME already has an extension. */ + searchname = lt__strdup (wpath); + } + else + { + /* Append a `.' to stop Windows from adding an + implicit `.dll' extension. */ + searchname = MALLOC (char, 2+ LT_STRLEN (wpath)); + if (searchname) + sprintf (searchname, "%s.", wpath); + } + if (!searchname) + return 0; } - if (!searchname) - return 0; { /* Silence dialog from LoadLibrary on some failures. @@ -135,15 +156,7 @@ UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS); SetErrorMode(errormode | SEM_FAILCRITICALERRORS); -#if defined(__CYGWIN__) - { - char wpath[MAX_PATH]; - cygwin_conv_to_full_win32_path (searchname, wpath); - module = LoadLibrary (wpath); - } -#else module = LoadLibrary (searchname); -#endif /* Restore the error mode. */ SetErrorMode(errormode); @@ -161,20 +174,20 @@ { lt__handle * cur = 0; - while ((cur = (lt__handle *) lt_dlhandle_next ((lt_dlhandle) cur))) + while ((cur = (lt__handle *) lt_dlhandle_iterate (iface_id, (lt_dlhandle) cur))) { if (!cur->module) { cur = 0; break; } - + if (cur->module == module) { break; } } - + if (cur || !module) { LT__SETERROR (CANNOT_OPEN);