2e0a926250a38ec0b520b27b8209104564e840f6
[platform/upstream/glib.git] / gio / giomodule.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include <config.h>
24
25 #include "giomodule.h"
26 #include "giomodule-priv.h"
27
28 #include "gioalias.h"
29
30 /**
31  * SECTION:giomodule
32  * @short_description: Loadable GIO Modules
33  * @include: gio.h
34  *
35  * Provides an interface and default functions for loading and unloading 
36  * modules. This is used internally to make gio extensible, but can also
37  * be used by other to implement module loading.
38  * 
39  **/
40
41 struct _GIOModule {
42   GTypeModule parent_instance;
43   
44   gchar       *filename;
45   GModule     *library;
46   
47   void (* load)   (GIOModule *module);
48   void (* unload) (GIOModule *module);
49 };
50
51 struct _GIOModuleClass
52 {
53   GTypeModuleClass parent_class;
54
55 };
56
57 static void      g_io_module_finalize      (GObject      *object);
58 static gboolean  g_io_module_load_module   (GTypeModule  *gmodule);
59 static void      g_io_module_unload_module (GTypeModule  *gmodule);
60
61 G_DEFINE_TYPE (GIOModule, g_io_module, G_TYPE_TYPE_MODULE);
62
63 static void
64 g_io_module_class_init (GIOModuleClass *class)
65 {
66   GObjectClass     *object_class      = G_OBJECT_CLASS (class);
67   GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (class);
68
69   object_class->finalize     = g_io_module_finalize;
70
71   type_module_class->load    = g_io_module_load_module;
72   type_module_class->unload  = g_io_module_unload_module;
73 }
74
75 static void
76 g_io_module_init (GIOModule *module)
77 {
78 }
79
80 static void
81 g_io_module_finalize (GObject *object)
82 {
83   GIOModule *module = G_IO_MODULE (object);
84
85   g_free (module->filename);
86
87   G_OBJECT_CLASS (g_io_module_parent_class)->finalize (object);
88 }
89
90 static gboolean
91 g_io_module_load_module (GTypeModule *gmodule)
92 {
93   GIOModule *module = G_IO_MODULE (gmodule);
94
95   if (!module->filename)
96     {
97       g_warning ("GIOModule path not set");
98       return FALSE;
99     }
100
101   module->library = g_module_open (module->filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
102
103   if (!module->library)
104     {
105       g_printerr ("%s\n", g_module_error ());
106       return FALSE;
107     }
108
109   /* Make sure that the loaded library contains the required methods */
110   if (! g_module_symbol (module->library,
111                          "g_io_module_load",
112                          (gpointer) &module->load) ||
113       ! g_module_symbol (module->library,
114                          "g_io_module_unload",
115                          (gpointer) &module->unload))
116     {
117       g_printerr ("%s\n", g_module_error ());
118       g_module_close (module->library);
119
120       return FALSE;
121     }
122
123   /* Initialize the loaded module */
124   module->load (module);
125
126   return TRUE;
127 }
128
129 static void
130 g_io_module_unload_module (GTypeModule *gmodule)
131 {
132   GIOModule *module = G_IO_MODULE (gmodule);
133
134   module->unload (module);
135
136   g_module_close (module->library);
137   module->library = NULL;
138
139   module->load   = NULL;
140   module->unload = NULL;
141 }
142
143 /**
144  * g_io_module_new:
145  * @filename: filename of the shared library module.
146  * 
147  * Creates a new GIOModule that will load the specific
148  * shared library when in use.
149  * 
150  * Returns: a #GIOModule from given @filename, 
151  * or %NULL on error.
152  **/
153 GIOModule *
154 g_io_module_new (const gchar *filename)
155 {
156   GIOModule *module;
157
158   g_return_val_if_fail (filename != NULL, NULL);
159
160   module = g_object_new (G_IO_TYPE_MODULE, NULL);
161   module->filename = g_strdup (filename);
162
163   return module;
164 }
165
166 static gboolean
167 is_valid_module_name (const gchar *basename)
168 {
169 #if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN)
170   return
171     g_str_has_prefix (basename, "lib") &&
172     g_str_has_suffix (basename, ".so");
173 #else
174   return g_str_has_suffix (basename, ".dll");
175 #endif
176 }
177
178 /**
179  * g_io_modules_load_all_in_directory:
180  * @dirname: pathname for a directory containing modules to load.
181  * 
182  * Loads all the modules in the the specified directory.
183  * 
184  * Returns: a list of #GIOModules loaded from the directory
185  **/
186 GList *
187 g_io_modules_load_all_in_directory (const char *dirname)
188 {
189   const gchar *name;
190   GDir        *dir;
191   GList *modules;
192
193   if (!g_module_supported ())
194     return NULL;
195
196   dir = g_dir_open (dirname, 0, NULL);
197   if (!dir)
198     return NULL;
199
200   modules = NULL;
201   while ((name = g_dir_read_name (dir)))
202     {
203       if (is_valid_module_name (name))
204         {
205           GIOModule *module;
206           gchar     *path;
207
208           path = g_build_filename (dirname, name, NULL);
209           module = g_io_module_new (path);
210
211           if (!g_type_module_use (G_TYPE_MODULE (module)))
212             {
213               g_printerr ("Failed to load module: %s\n", path);
214               g_object_unref (module);
215               g_free (path);
216               continue;
217             }
218           
219           g_free (path);
220
221           g_type_module_unuse (G_TYPE_MODULE (module));
222           
223           modules = g_list_prepend (modules, module);
224         }
225     }
226   
227   g_dir_close (dir);
228
229   return modules;
230 }
231
232 G_LOCK_DEFINE_STATIC (loaded_dirs);
233
234 void
235 _g_io_modules_ensure_loaded (void)
236 {
237   GList *modules;
238   static gboolean loaded_dirs = FALSE;
239   
240   G_LOCK (loaded_dirs);
241
242   if (!loaded_dirs)
243     {
244       loaded_dirs = TRUE;
245       modules = g_io_modules_load_all_in_directory (GIO_MODULE_DIR);
246     }
247   
248   G_UNLOCK (loaded_dirs);
249 }
250
251 #define __G_IO_MODULE_C__
252 #include "gioaliasdef.c"