Changes GC.cs
[mono-project.git] / mono / eglib / gmodule-unix.c
blob77f8b8dd515195523e50ea6de908cd6caa39209b
1 /*
2 * gmodule.c: dl* functions, glib style
4 * Author:
5 * Gonzalo Paniagua Javier (gonzalo@novell.com)
6 * Jonathan Chambers (joncham@gmail.com)
7 * Robert Jordan (robertj@gmx.net)
9 * (C) 2006 Novell, Inc.
10 * (C) 2006 Jonathan Chambers
12 * Permission is hereby granted, free of charge, to any person obtaining
13 * a copy of this software and associated documentation files (the
14 * "Software"), to deal in the Software without restriction, including
15 * without limitation the rights to use, copy, modify, merge, publish,
16 * distribute, sublicense, and/or sell copies of the Software, and to
17 * permit persons to whom the Software is furnished to do so, subject to
18 * the following conditions:
20 * The above copyright notice and this permission notice shall be
21 * included in all copies or substantial portions of the Software.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #include <config.h>
33 #include <glib.h>
34 #include <gmodule.h>
36 #if defined(G_OS_UNIX) && defined(HAVE_DLFCN_H)
37 #include <dlfcn.h>
39 /* For Linux and Solaris, need to add others as we port this */
40 #define LIBPREFIX "lib"
41 #define LIBSUFFIX ".so"
43 struct _GModule {
44 void *handle;
47 GModule *
48 g_module_open (const gchar *file, GModuleFlags flags)
50 int f = 0;
51 GModule *module;
52 void *handle;
54 flags &= G_MODULE_BIND_MASK;
55 if ((flags & G_MODULE_BIND_LAZY) != 0)
56 f |= RTLD_LAZY;
57 if ((flags & G_MODULE_BIND_LOCAL) != 0)
58 f |= RTLD_LOCAL;
60 handle = dlopen (file, f);
61 if (handle == NULL)
62 return NULL;
64 module = g_new (GModule,1);
65 module->handle = handle;
67 return module;
70 gboolean
71 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
73 if (symbol_name == NULL || symbol == NULL)
74 return FALSE;
76 if (module == NULL || module->handle == NULL)
77 return FALSE;
79 *symbol = dlsym (module->handle, symbol_name);
80 return (*symbol != NULL);
83 const gchar *
84 g_module_error (void)
86 return dlerror ();
89 gboolean
90 g_module_close (GModule *module)
92 void *handle;
93 if (module == NULL || module->handle == NULL)
94 return FALSE;
96 handle = module->handle;
97 module->handle = NULL;
98 g_free (module);
99 return (0 == dlclose (handle));
102 #elif defined (G_OS_WIN32)
103 #include <windows.h>
104 #include <psapi.h>
106 #define LIBSUFFIX ".dll"
107 #define LIBPREFIX ""
109 struct _GModule {
110 HMODULE handle;
111 int main_module;
114 GModule *
115 g_module_open (const gchar *file, GModuleFlags flags)
117 GModule *module;
118 module = g_malloc (sizeof (GModule));
119 if (module == NULL)
120 return NULL;
122 if (file != NULL) {
123 gunichar2 *file16;
124 file16 = u8to16(file);
125 module->main_module = FALSE;
126 module->handle = LoadLibrary (file16);
127 g_free(file16);
128 if (!module->handle) {
129 g_free (module);
130 return NULL;
133 } else {
134 module->main_module = TRUE;
135 module->handle = GetModuleHandle (NULL);
138 return module;
141 static gpointer
142 w32_find_symbol (const gchar *symbol_name)
144 HMODULE *modules;
145 DWORD buffer_size = sizeof (HMODULE) * 1024;
146 DWORD needed, i;
148 modules = (HMODULE *) g_malloc (buffer_size);
150 if (modules == NULL)
151 return NULL;
153 if (!EnumProcessModules (GetCurrentProcess (), modules,
154 buffer_size, &needed)) {
155 g_free (modules);
156 return NULL;
159 /* check whether the supplied buffer was too small, realloc, retry */
160 if (needed > buffer_size) {
161 g_free (modules);
163 buffer_size = needed;
164 modules = (HMODULE *) g_malloc (buffer_size);
166 if (modules == NULL)
167 return NULL;
169 if (!EnumProcessModules (GetCurrentProcess (), modules,
170 buffer_size, &needed)) {
171 g_free (modules);
172 return NULL;
176 for (i = 0; i < needed / sizeof (HANDLE); i++) {
177 gpointer proc = (gpointer)(intptr_t)GetProcAddress (modules [i], symbol_name);
178 if (proc != NULL) {
179 g_free (modules);
180 return proc;
184 g_free (modules);
185 return NULL;
188 gboolean
189 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
191 if (module == NULL || symbol_name == NULL || symbol == NULL)
192 return FALSE;
194 if (module->main_module) {
195 *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name);
196 if (*symbol != NULL)
197 return TRUE;
199 *symbol = w32_find_symbol (symbol_name);
200 return *symbol != NULL;
201 } else {
202 *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name);
203 return *symbol != NULL;
207 const gchar *
208 g_module_error (void)
210 gchar* ret = NULL;
211 TCHAR* buf = NULL;
212 DWORD code = GetLastError ();
214 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL,
215 code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 0, NULL);
217 ret = u16to8 (buf);
218 LocalFree(buf);
220 return ret;
223 gboolean
224 g_module_close (GModule *module)
226 HMODULE handle;
227 int main_module;
229 if (module == NULL || module->handle == NULL)
230 return FALSE;
232 handle = module->handle;
233 main_module = module->main_module;
234 module->handle = NULL;
235 g_free (module);
236 return (main_module ? 1 : (0 == FreeLibrary (handle)));
239 #else
241 #define LIBSUFFIX ""
242 #define LIBPREFIX ""
244 GModule *
245 g_module_open (const gchar *file, GModuleFlags flags)
247 g_error ("%s", "g_module_open not implemented on this platform");
248 return NULL;
251 gboolean
252 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
254 g_error ("%s", "g_module_open not implemented on this platform");
255 return FALSE;
258 const gchar *
259 g_module_error (void)
261 g_error ("%s", "g_module_open not implemented on this platform");
262 return NULL;
265 gboolean
266 g_module_close (GModule *module)
268 g_error ("%s", "g_module_open not implemented on this platform");
269 return FALSE;
271 #endif
273 gchar *
274 g_module_build_path (const gchar *directory, const gchar *module_name)
276 const char *lib_prefix = "";
278 if (module_name == NULL)
279 return NULL;
281 if (strncmp (module_name, "lib", 3) != 0)
282 lib_prefix = LIBPREFIX;
284 if (directory && *directory)
285 return g_strdup_printf ("%s/%s%s" LIBSUFFIX, directory, lib_prefix, module_name);
286 return g_strdup_printf ("%s%s" LIBSUFFIX, lib_prefix, module_name);