OSDN Git Service

* autoload.cc (GetModuleHandleExW): Define.
authorcorinna <corinna>
Tue, 16 Aug 2011 14:44:25 +0000 (14:44 +0000)
committercorinna <corinna>
Tue, 16 Aug 2011 14:44:25 +0000 (14:44 +0000)
* dlfcn.cc: Throughout mark exported symbols as extern "C".
(dlopen): Unignore flags argument.  Define ret to NULL.  Fix typo in
comment.  Support Glibc flags RTLD_NOLOAD and RTLD_NODELETE.
* include/dlfcn.h:  Clean up comments.
(RTLD_NODELETE): Define.
(RTLD_NOLOAD): Define.
(RTLD_DEEPBIND): Define.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/dlfcn.cc
winsup/cygwin/include/dlfcn.h

index 2c97801..c4d0290 100644 (file)
@@ -1,3 +1,14 @@
+2011-08-16  Corinna Vinschen  <corinna@vinschen.de>
+
+       * autoload.cc (GetModuleHandleExW): Define.
+       * dlfcn.cc: Throughout mark exported symbols as extern "C".
+       (dlopen): Unignore flags argument.  Define ret to NULL.  Fix typo in
+       comment.  Support Glibc flags RTLD_NOLOAD and RTLD_NODELETE.
+       * include/dlfcn.h:  Clean up comments.
+       (RTLD_NODELETE): Define.
+       (RTLD_NOLOAD): Define.
+       (RTLD_DEEPBIND): Define.
+
 2011-08-15  Corinna Vinschen  <corinna@vinschen.de>
 
        * pipe.cc (pipe): Just call _pipe with O_BINARY mode.  Move code to
index 63355b4..f8a7a0c 100644 (file)
@@ -390,6 +390,7 @@ LoadDLLfunc (GetNetworkParams, 8, iphlpapi)
 LoadDLLfunc (GetUdpTable, 12, iphlpapi)
 
 LoadDLLfuncEx (AttachConsole, 4, kernel32, 1)
+LoadDLLfuncEx (GetModuleHandleExW, 12, kernel32, 1)
 LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1)
 LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
 
index ff1be8d..91ffc9a 100644 (file)
@@ -67,10 +67,10 @@ get_full_path_of_dll (const char* str, path_conv &real_filename)
   return false;
 }
 
-void *
-dlopen (const char *name, int)
+extern "C" void *
+dlopen (const char *name, int flags)
 {
-  void *ret;
+  void *ret = NULL;
 
   if (name == NULL)
     {
@@ -82,16 +82,14 @@ dlopen (const char *name, int)
     {
       /* handle for the named library */
       path_conv pc;
-      if (!get_full_path_of_dll (name, pc))
-       ret = NULL;
-      else
+      if (get_full_path_of_dll (name, pc))
        {
          tmp_pathbuf tp;
          wchar_t *path = tp.w_get ();
 
          pc.get_wide_win32_path (path);
          /* Check if the last path component contains a dot.  If so,
-            leave the filename alone.  Otherwise add a traiing dot
+            leave the filename alone.  Otherwise add a trailing dot
             to override LoadLibrary's automatic adding of a ".dll" suffix. */
          wchar_t *last_bs = wcsrchr (path, L'\\');
          if (last_bs && !wcschr (last_bs, L'.'))
@@ -113,7 +111,23 @@ dlopen (const char *name, int)
          struct per_process_cxx_malloc *tmp_malloc;
          tmp_malloc = __cygwin_user_data.cxx_malloc;
 
-         ret = (void *) LoadLibraryW (path);
+         if (!(flags & RTLD_NOLOAD)
+             || (ret = GetModuleHandleW (path)) != NULL)
+           {
+             ret = (void *) LoadLibraryW (path);
+             if (ret && (flags & RTLD_NODELETE)
+                 && !GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_PIN, path,
+                                         (HMODULE *) &ret))
+               {
+                 /* Windows 2000 is missing the GetModuleHandleEx call, so we
+                    just use a trick.  Call LoadLibrary 10 times more if the
+                    RTLD_NODELETE flag has been specified.  That makes it
+                    unlikely (but not impossible) that dlclose will actually
+                    free the library. */
+                 for (int i = 0; i < 10; ++i)
+                   LoadLibraryW (path);
+               }
+           }
 
          /* Restore original cxx_malloc pointer. */
          __cygwin_user_data.cxx_malloc = tmp_malloc;
@@ -130,7 +144,7 @@ dlopen (const char *name, int)
   return ret;
 }
 
-void *
+extern "C" void *
 dlsym (void *handle, const char *name)
 {
   void *ret = NULL;
@@ -176,7 +190,7 @@ dlsym (void *handle, const char *name)
   return ret;
 }
 
-int
+extern "C" int
 dlclose (void *handle)
 {
   int ret;
@@ -191,7 +205,7 @@ dlclose (void *handle)
   return ret;
 }
 
-char *
+extern "C" char *
 dlerror ()
 {
   char *res;
index 56a7fb4..9ffbdb3 100644 (file)
@@ -1,6 +1,6 @@
 /* dlfcn.h
 
-   Copyright 1998, 1999, 2000, 2001, 2010 Red Hat, Inc.
+   Copyright 1998, 1999, 2000, 2001, 2010, 2011 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -31,10 +31,18 @@ extern void dlfork (int);
 #define RTLD_DEFAULT    NULL
 
 /* valid values for mode argument to dlopen */
-#define RTLD_LOCAL     0       /* symbols in this dlopen'ed obj are not visible to other dlopen'ed objs */
-#define RTLD_LAZY      1       /* lazy function call binding */
-#define RTLD_NOW       2       /* immediate function call binding */
-#define RTLD_GLOBAL    4       /* symbols in this dlopen'ed obj are visible to other dlopen'ed objs */
+#define RTLD_LOCAL     0       /* Symbols in this dlopen'ed obj are not     */
+                               /* visible to other dlopen'ed objs.          */
+#define RTLD_LAZY      1       /* Lazy function call binding.               */
+#define RTLD_NOW       2       /* Immediate function call binding.          */
+#define RTLD_GLOBAL    4       /* Symbols in this dlopen'ed obj are visible */
+                               /* to other dlopen'ed objs.                  */
+/* Non-standard GLIBC extensions */
+#define RTLD_NODELETE  8       /* Don't unload lib in dlcose.               */
+#define RTLD_NOLOAD    16      /* Don't load lib, just return handle if lib */
+                               /* is already loaded, NULL otherwise.        */
+#define RTLD_DEEPBIND  32      /* Place lookup scope so that this lib is    */
+                               /* preferred over global scope.  */
 
 #ifdef __cplusplus
 }