First steps to build this on Windows (for those who have been trying
[mono.git] / eglib / src / gmodule.c
1 /*
2  * gmodule.c: dl* functions, glib style
3  *
4  * Author:
5  *   Gonzalo Paniagua Javier (gonzalo@novell.com)
6  *
7  * (C) 2006 Novell, Inc.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining
10  * a copy of this software and associated documentation files (the
11  * "Software"), to deal in the Software without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sublicense, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27  */
28 #include <glib.h>
29
30 #ifdef G_OS_UNIX
31 #include <dlfcn.h>
32
33 /* For Linux and Solaris, need to add others as we port this */
34 #define LIBSUFFIX "lib"
35 #define LIBPREFIX ".so"
36
37 struct _GModule {
38         void *handle;
39 };
40
41 GModule *
42 g_module_open (const gchar *file, GModuleFlags flags)
43 {
44         int f = 0;
45         GModule *module;
46
47         flags &= G_MODULE_BIND_MASK;
48         if ((flags & G_MODULE_BIND_LAZY) != 0)
49                 f |= RTLD_LAZY;
50         if ((flags & G_MODULE_BIND_LOCAL) != 0)
51                 f |= RTLD_LOCAL;
52
53         module = g_malloc (sizeof (GModule));
54         if (module == NULL)
55                 return NULL;
56
57         module->handle = dlopen (file, f);
58         return module;
59 }
60
61 gboolean
62 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
63 {
64         if (symbol_name == NULL || symbol == NULL)
65                 return FALSE;
66
67         if (module == NULL || module->handle == NULL)
68                 return FALSE;
69
70         *symbol = dlsym (module->handle, symbol_name);
71         return (*symbol != NULL);
72 }
73
74 const gchar *
75 g_module_error (void)
76 {
77         return dlerror ();
78 }
79
80 gboolean
81 g_module_close (GModule *module)
82 {
83         void *handle;
84         if (module == NULL || module->handle == NULL)
85                 return FALSE;
86
87         handle = module->handle;
88         module->handle = NULL;
89         g_free (module);
90         return (0 == dlclose (handle));
91 }
92
93 #else
94
95 GModule *
96 g_module_open (const gchar *file, GModuleFlags flags)
97 {
98         g_error ("g_module_open not implemented on this platform");
99 }
100
101 gboolean
102 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
103 {
104         g_error ("g_module_open not implemented on this platform");
105 }
106
107 const gchar *
108 g_module_error (void)
109 {
110         g_error ("g_module_open not implemented on this platform");
111 }
112
113 gboolean
114 g_module_close (GModule *module)
115 {
116         g_error ("g_module_open not implemented on this platform");
117 }
118 #endif
119
120 gchar *
121 g_module_build_path (const gchar *directory, const gchar *module_name)
122 {
123         if (module_name == NULL)
124                 return NULL;
125
126         if (directory)
127                 return g_strdup_printf ("%s/" LIBPREFIX "%s" LIBSUFFIX, directory, module_name);
128         return g_strdup_printf (LIBPREFIX "%s" LIBSUFFIX, module_name); 
129 }