libtool-patches
[Top][All Lists]
Advanced

[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);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]