remove langversion:linq as it is the default now
[mono.git] / eglib / src / gmodule.c
blobf6d2d6b7f734457ee2763ea6eb41e7b099b18b23
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 <glib.h>
32 #include <gmodule.h>
34 #ifdef G_OS_UNIX
35 #include <dlfcn.h>
37 /* For Linux and Solaris, need to add others as we port this */
38 #define LIBPREFIX "lib"
39 #define LIBSUFFIX ".so"
41 struct _GModule {
42 void *handle;
45 GModule *
46 g_module_open (const gchar *file, GModuleFlags flags)
48 int f = 0;
49 GModule *module;
50 void *handle;
52 flags &= G_MODULE_BIND_MASK;
53 if ((flags & G_MODULE_BIND_LAZY) != 0)
54 f |= RTLD_LAZY;
55 if ((flags & G_MODULE_BIND_LOCAL) != 0)
56 f |= RTLD_LOCAL;
58 handle = dlopen (file, f);
59 if (handle == NULL)
60 return NULL;
62 module = g_new (GModule,1);
63 module->handle = handle;
65 return module;
68 gboolean
69 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
71 if (symbol_name == NULL || symbol == NULL)
72 return FALSE;
74 if (module == NULL || module->handle == NULL)
75 return FALSE;
77 *symbol = dlsym (module->handle, symbol_name);
78 return (*symbol != NULL);
81 const gchar *
82 g_module_error (void)
84 return dlerror ();
87 gboolean
88 g_module_close (GModule *module)
90 void *handle;
91 if (module == NULL || module->handle == NULL)
92 return FALSE;
94 handle = module->handle;
95 module->handle = NULL;
96 g_free (module);
97 return (0 == dlclose (handle));
100 #elif defined (G_OS_WIN32)
101 #include <windows.h>
102 #include <psapi.h>
104 #define LIBSUFFIX ".dll"
105 #define LIBPREFIX ""
107 struct _GModule {
108 HMODULE handle;
109 int main_module;
112 GModule *
113 g_module_open (const gchar *file, GModuleFlags flags)
115 GModule *module;
116 module = g_malloc (sizeof (GModule));
117 if (module == NULL)
118 return NULL;
120 if (file != NULL) {
121 gunichar2 *file16;
122 file16 = u8to16(file);
123 module->main_module = FALSE;
124 module->handle = LoadLibrary (file16);
125 g_free(file16);
126 if (!module->handle) {
127 g_free (module);
128 return NULL;
131 } else {
132 module->main_module = TRUE;
133 module->handle = GetModuleHandle (NULL);
136 return module;
139 static gpointer
140 w32_find_symbol (const gchar *symbol_name)
142 HMODULE *modules;
143 DWORD buffer_size = sizeof (HMODULE) * 1024;
144 DWORD needed, i;
146 modules = (HMODULE *) g_malloc (buffer_size);
148 if (modules == NULL)
149 return NULL;
151 if (!EnumProcessModules (GetCurrentProcess (), modules,
152 buffer_size, &needed)) {
153 g_free (modules);
154 return NULL;
157 /* check whether the supplied buffer was too small, realloc, retry */
158 if (needed > buffer_size) {
159 g_free (modules);
161 buffer_size = needed;
162 modules = (HMODULE *) g_malloc (buffer_size);
164 if (modules == NULL)
165 return NULL;
167 if (!EnumProcessModules (GetCurrentProcess (), modules,
168 buffer_size, &needed)) {
169 g_free (modules);
170 return NULL;
174 for (i = 0; i < needed / sizeof (HANDLE); i++) {
175 gpointer proc = (gpointer)(intptr_t)GetProcAddress (modules [i], symbol_name);
176 if (proc != NULL) {
177 g_free (modules);
178 return proc;
182 g_free (modules);
183 return NULL;
186 gboolean
187 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
189 if (module == NULL || symbol_name == NULL || symbol == NULL)
190 return FALSE;
192 if (module->main_module) {
193 *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name);
194 if (*symbol != NULL)
195 return TRUE;
197 *symbol = w32_find_symbol (symbol_name);
198 return *symbol != NULL;
199 } else {
200 *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name);
201 return *symbol != NULL;
205 const gchar *
206 g_module_error (void)
208 gchar* ret = NULL;
209 TCHAR* buf = NULL;
210 DWORD code = GetLastError ();
212 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL,
213 code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 0, NULL);
215 ret = u16to8 (buf);
216 LocalFree(buf);
218 return ret;
221 gboolean
222 g_module_close (GModule *module)
224 HMODULE handle;
225 int main_module;
227 if (module == NULL || module->handle == NULL)
228 return FALSE;
230 handle = module->handle;
231 main_module = module->main_module;
232 module->handle = NULL;
233 g_free (module);
234 return (main_module ? 1 : (0 == FreeLibrary (handle)));
237 #else
239 #define LIBSUFFIX ""
240 #define LIBPREFIX ""
242 GModule *
243 g_module_open (const gchar *file, GModuleFlags flags)
245 g_error ("%s", "g_module_open not implemented on this platform");
246 return NULL;
249 gboolean
250 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
252 g_error ("%s", "g_module_open not implemented on this platform");
253 return FALSE;
256 const gchar *
257 g_module_error (void)
259 g_error ("%s", "g_module_open not implemented on this platform");
260 return NULL;
263 gboolean
264 g_module_close (GModule *module)
266 g_error ("%s", "g_module_open not implemented on this platform");
267 return FALSE;
269 #endif
271 gchar *
272 g_module_build_path (const gchar *directory, const gchar *module_name)
274 char *lib_prefix = "";
276 if (module_name == NULL)
277 return NULL;
279 if (strncmp (module_name, "lib", 3) != 0)
280 lib_prefix = LIBPREFIX;
282 if (directory && *directory){
284 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);