[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: cygwin dlopening backends
From: |
Ralf Wildenhues |
Subject: |
Re: cygwin dlopening backends |
Date: |
Sat, 12 Nov 2005 14:07:06 +0100 |
User-agent: |
Mutt/1.5.9i |
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 <address@hidden>,
Ralf Wildenhues <address@hidden>
* 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
address@hidden void lt_dlinterface_free (@w{lt_dlinterface_id @var{iface}})
+Release the data associated with @var{iface}.
address@hidden deftypefun
+
@deftypefun int lt_dlhandle_map (@w{lt_dlinterface_id @var{iface}}, @w{int
(address@hidden) (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);
Re: cygwin dlopening backends, Charles Wilson, 2005/11/13