]> sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/dlfcn.cc
Remove unneeded header files from source files throughout.
[newlib-cygwin.git] / winsup / cygwin / dlfcn.cc
1 /* dlfcn.cc
2
3 Copyright 1998, 2000, 2001, 2002, 2003, 2004, 2008 Red Hat, Inc.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include "winsup.h"
12 #include <psapi.h>
13 #include <stdlib.h>
14 #include <ctype.h>
15 #include "path.h"
16 #include "perprocess.h"
17 #include "dlfcn.h"
18 #include "cygtls.h"
19 #include "tls_pbuf.h"
20
21 static void __stdcall
22 set_dl_error (const char *str)
23 {
24 strcpy (_my_tls.locals.dl_buffer, strerror (get_errno ()));
25 _my_tls.locals.dl_error = 1;
26 }
27
28 /* Look for an executable file given the name and the environment
29 variable to use for searching (eg., PATH); returns the full
30 pathname (static buffer) if found or NULL if not. */
31 inline const char * __stdcall
32 check_path_access (const char *mywinenv, const char *name, path_conv& buf)
33 {
34 return find_exec (name, buf, mywinenv, FE_NNF | FE_NATIVE | FE_CWD | FE_DLL);
35 }
36
37 /* Search LD_LIBRARY_PATH for dll, if it exists.
38 Return Windows version of given path. */
39 static const char * __stdcall
40 get_full_path_of_dll (const char* str, char *name)
41 {
42 int len = strlen (str);
43
44 /* empty string or too long to be legal win32 pathname? */
45 if (len == 0 || len >= PATH_MAX)
46 return str; /* Yes. Let caller deal with it. */
47
48 const char *ret;
49
50 strcpy (name, str); /* Put it somewhere where we can manipulate it. */
51
52 /* Add extension if necessary */
53 if (str[len - 1] != '.')
54 {
55 /* Add .dll only if no extension provided. */
56 const char *p = strrchr (str, '.');
57 if (!p || strpbrk (p, "\\/"))
58 strcat (name, ".dll");
59 }
60
61 path_conv real_filename;
62
63 if (isabspath (name) ||
64 (ret = check_path_access ("LD_LIBRARY_PATH=", name, real_filename)
65 ?: check_path_access ("/usr/lib", name, real_filename)) == NULL)
66 real_filename.check (name, PC_SYM_FOLLOW | PC_NOFULL | PC_NULLEMPTY); /* Convert */
67
68 if (!real_filename.error)
69 ret = strcpy (name, real_filename.get_win32 ());
70 else
71 {
72 set_errno (real_filename.error);
73 ret = NULL;
74 }
75
76 return ret;
77 }
78
79 void *
80 dlopen (const char *name, int)
81 {
82 void *ret;
83
84 if (name == NULL)
85 ret = (void *) GetModuleHandle (NULL); /* handle for the current module */
86 else
87 {
88 tmp_pathbuf tp;
89 char *buf = tp.c_get ();
90 /* handle for the named library */
91 const char *fullpath = get_full_path_of_dll (name, buf);
92 if (!fullpath)
93 ret = NULL;
94 else
95 {
96 ret = (void *) LoadLibrary (fullpath);
97 if (ret == NULL)
98 __seterrno ();
99 }
100 }
101
102 if (!ret)
103 set_dl_error ("dlopen");
104 debug_printf ("ret %p", ret);
105
106 return ret;
107 }
108
109 void *
110 dlsym (void *handle, const char *name)
111 {
112 void *ret = NULL;
113 if (handle == RTLD_DEFAULT)
114 { /* search all modules */
115 HANDLE cur_proc = GetCurrentProcess ();
116 HMODULE *modules;
117 DWORD needed, i;
118 if (!EnumProcessModules (cur_proc, NULL, 0, &needed))
119 {
120 dlsym_fail:
121 set_dl_error ("dlsym");
122 return NULL;
123 }
124 modules = (HMODULE*) alloca (needed);
125 if (!EnumProcessModules (cur_proc, modules, needed, &needed))
126 goto dlsym_fail;
127 for (i = 0; i < needed / sizeof (HMODULE); i++)
128 if ((ret = (void *) GetProcAddress (modules[i], name)))
129 break;
130 }
131 else
132 ret = (void *) GetProcAddress ((HMODULE)handle, name);
133 if (!ret)
134 set_dl_error ("dlsym");
135 debug_printf ("ret %p", ret);
136 return ret;
137 }
138
139 int
140 dlclose (void *handle)
141 {
142 int ret = -1;
143 if (handle == GetModuleHandle (NULL) || FreeLibrary ((HMODULE) handle))
144 ret = 0;
145 if (ret)
146 set_dl_error ("dlclose");
147 return ret;
148 }
149
150 char *
151 dlerror ()
152 {
153 char *res;
154 if (!_my_tls.locals.dl_error)
155 res = NULL;
156 else
157 {
158 _my_tls.locals.dl_error = 0;
159 res = _my_tls.locals.dl_buffer;
160 }
161 return res;
162 }
This page took 0.040313 seconds and 5 git commands to generate.