* 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.
This commit is contained in:
Corinna Vinschen 2011-08-16 14:44:26 +00:00
parent 56c387b1b3
commit 6bc64eac26
4 changed files with 50 additions and 16 deletions

View 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> 2011-08-15 Corinna Vinschen <corinna@vinschen.de>
* pipe.cc (pipe): Just call _pipe with O_BINARY mode. Move code to * pipe.cc (pipe): Just call _pipe with O_BINARY mode. Move code to

View File

@ -390,6 +390,7 @@ LoadDLLfunc (GetNetworkParams, 8, iphlpapi)
LoadDLLfunc (GetUdpTable, 12, iphlpapi) LoadDLLfunc (GetUdpTable, 12, iphlpapi)
LoadDLLfuncEx (AttachConsole, 4, kernel32, 1) LoadDLLfuncEx (AttachConsole, 4, kernel32, 1)
LoadDLLfuncEx (GetModuleHandleExW, 12, kernel32, 1)
LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1) LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1)
LoadDLLfunc (LocaleNameToLCID, 8, kernel32) LoadDLLfunc (LocaleNameToLCID, 8, kernel32)

View File

@ -67,10 +67,10 @@ get_full_path_of_dll (const char* str, path_conv &real_filename)
return false; return false;
} }
void * extern "C" void *
dlopen (const char *name, int) dlopen (const char *name, int flags)
{ {
void *ret; void *ret = NULL;
if (name == NULL) if (name == NULL)
{ {
@ -82,16 +82,14 @@ dlopen (const char *name, int)
{ {
/* handle for the named library */ /* handle for the named library */
path_conv pc; path_conv pc;
if (!get_full_path_of_dll (name, pc)) if (get_full_path_of_dll (name, pc))
ret = NULL;
else
{ {
tmp_pathbuf tp; tmp_pathbuf tp;
wchar_t *path = tp.w_get (); wchar_t *path = tp.w_get ();
pc.get_wide_win32_path (path); pc.get_wide_win32_path (path);
/* Check if the last path component contains a dot. If so, /* 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. */ to override LoadLibrary's automatic adding of a ".dll" suffix. */
wchar_t *last_bs = wcsrchr (path, L'\\'); wchar_t *last_bs = wcsrchr (path, L'\\');
if (last_bs && !wcschr (last_bs, L'.')) if (last_bs && !wcschr (last_bs, L'.'))
@ -113,7 +111,23 @@ dlopen (const char *name, int)
struct per_process_cxx_malloc *tmp_malloc; struct per_process_cxx_malloc *tmp_malloc;
tmp_malloc = __cygwin_user_data.cxx_malloc; tmp_malloc = __cygwin_user_data.cxx_malloc;
if (!(flags & RTLD_NOLOAD)
|| (ret = GetModuleHandleW (path)) != NULL)
{
ret = (void *) LoadLibraryW (path); 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. */ /* Restore original cxx_malloc pointer. */
__cygwin_user_data.cxx_malloc = tmp_malloc; __cygwin_user_data.cxx_malloc = tmp_malloc;
@ -130,7 +144,7 @@ dlopen (const char *name, int)
return ret; return ret;
} }
void * extern "C" void *
dlsym (void *handle, const char *name) dlsym (void *handle, const char *name)
{ {
void *ret = NULL; void *ret = NULL;
@ -176,7 +190,7 @@ dlsym (void *handle, const char *name)
return ret; return ret;
} }
int extern "C" int
dlclose (void *handle) dlclose (void *handle)
{ {
int ret; int ret;
@ -191,7 +205,7 @@ dlclose (void *handle)
return ret; return ret;
} }
char * extern "C" char *
dlerror () dlerror ()
{ {
char *res; char *res;

View File

@ -1,6 +1,6 @@
/* dlfcn.h /* 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. This file is part of Cygwin.
@ -31,10 +31,18 @@ extern void dlfork (int);
#define RTLD_DEFAULT NULL #define RTLD_DEFAULT NULL
/* valid values for mode argument to dlopen */ /* 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_LOCAL 0 /* Symbols in this dlopen'ed obj are not */
#define RTLD_LAZY 1 /* lazy function call binding */ /* visible to other dlopen'ed objs. */
#define RTLD_NOW 2 /* immediate function call binding */ #define RTLD_LAZY 1 /* Lazy function call binding. */
#define RTLD_GLOBAL 4 /* symbols in this dlopen'ed obj are visible to other dlopen'ed objs */ #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 #ifdef __cplusplus
} }