02d12d69bb72152979225bf49ababb9346fe28f3
[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
27 #include "gioalias.h"
28
29 /**
30  * SECTION:giomodule
31  * @short_description: Loadable GIO Modules
32  *
33  * Provides an interface and default functions for loading and unloading 
34  * GIO modules.
35  * 
36  **/
37
38 struct _GIOModule {
39   GTypeModule parent_instance;
40   
41   gchar       *filename;
42   GModule     *library;
43   
44   void (* load)   (GIOModule *module);
45   void (* unload) (GIOModule *module);
46 };
47
48 struct _GIOModuleClass
49 {
50   GTypeModuleClass parent_class;
51
52 };
53
54 static void      g_io_module_finalize      (GObject      *object);
55 static gboolean  g_io_module_load_module   (GTypeModule  *gmodule);
56 static void      g_io_module_unload_module (GTypeModule  *gmodule);
57
58 G_DEFINE_TYPE (GIOModule, g_io_module, G_TYPE_TYPE_MODULE);
59
60 static void
61 g_io_module_class_init (GIOModuleClass *class)
62 {
63   GObjectClass     *object_class      = G_OBJECT_CLASS (class);
64   GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (class);
65
66   object_class->finalize     = g_io_module_finalize;
67
68   type_module_class->load    = g_io_module_load_module;
69   type_module_class->unload  = g_io_module_unload_module;
70 }
71
72 static void
73 g_io_module_init (GIOModule *module)
74 {
75 }
76
77 static void
78 g_io_module_finalize (GObject *object)
79 {
80   GIOModule *module = G_IO_MODULE (object);
81
82   g_free (module->filename);
83
84   G_OBJECT_CLASS (g_io_module_parent_class)->finalize (object);
85 }
86
87 static gboolean
88 g_io_module_load_module (GTypeModule *gmodule)
89 {
90   GIOModule *module = G_IO_MODULE (gmodule);
91
92   if (!module->filename)
93     {
94       g_warning ("GIOModule path not set");
95       return FALSE;
96     }
97
98   module->library = g_module_open (module->filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
99
100   if (!module->library)
101     {
102       g_printerr ("%s\n", g_module_error ());
103       return FALSE;
104     }
105
106   /* Make sure that the loaded library contains the required methods */
107   if (! g_module_symbol (module->library,
108                          "g_io_module_load",
109                          (gpointer *) &module->load) ||
110       ! g_module_symbol (module->library,
111                          "g_io_module_unload",
112                          (gpointer *) &module->unload))
113     {
114       g_printerr ("%s\n", g_module_error ());
115       g_module_close (module->library);
116
117       return FALSE;
118     }
119
120   /* Initialize the loaded module */
121   module->load (module);
122
123   return TRUE;
124 }
125
126 static void
127 g_io_module_unload_module (GTypeModule *gmodule)
128 {
129   GIOModule *module = G_IO_MODULE (gmodule);
130
131   module->unload (module);
132
133   g_module_close (module->library);
134   module->library = NULL;
135
136   module->load   = NULL;
137   module->unload = NULL;
138 }
139
140 /**
141  * g_io_module_new:
142  * @filename: filename of the module to load.
143  * 
144  * Loads a new module into GIO.
145  * 
146  * Returns: a #GIOModule from given @filename, 
147  * or %NULL on error.
148  **/
149 GIOModule *
150 g_io_module_new (const gchar *filename)
151 {
152   GIOModule *module;
153
154   g_return_val_if_fail (filename != NULL, NULL);
155
156   module = g_object_new (G_IO_TYPE_MODULE, NULL);
157   module->filename = g_strdup (filename);
158
159   return module;
160 }
161
162 static gboolean
163 is_valid_module_name (const gchar *basename)
164 {
165 #if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN)
166   return
167     g_str_has_prefix (basename, "lib") &&
168     g_str_has_suffix (basename, ".so");
169 #else
170   return g_str_has_suffix (basename, ".dll");
171 #endif
172 }
173
174 static GList *
175 load_modules (const char *dirname)
176 {
177   const gchar *name;
178   GDir        *dir;
179   GList *modules;
180
181   if (!g_module_supported ())
182     return NULL;
183
184   dir = g_dir_open (dirname, 0, NULL);
185   if (!dir)
186     return NULL;
187
188   modules = NULL;
189   while ((name = g_dir_read_name (dir)))
190     {
191       if (is_valid_module_name (name))
192         {
193           GIOModule *module;
194           gchar     *path;
195
196           path = g_build_filename (dirname, name, NULL);
197           module = g_io_module_new (path);
198
199           if (!g_type_module_use (G_TYPE_MODULE (module)))
200             {
201               g_printerr ("Failed to load module: %s\n", path);
202               g_object_unref (module);
203               g_free (path);
204               continue;
205             }
206           
207           g_free (path);
208
209           g_type_module_unuse (G_TYPE_MODULE (module));
210           
211           modules = g_list_prepend (modules, module);
212         }
213     }
214   
215   g_dir_close (dir);
216
217   return modules;
218 }
219
220 G_LOCK_DEFINE_STATIC (loaded_dirs);
221 static GHashTable *loaded_dirs = NULL;
222
223 /**
224  * g_io_modules_ensure_loaded:
225  * @directory: string containing a directory path.
226  * 
227  * Loads all of the modules within the @directory. 
228  **/
229 void
230 g_io_modules_ensure_loaded (const char *directory)
231 {
232   GList *modules;
233
234   g_return_if_fail (directory != NULL);
235   
236   G_LOCK (loaded_dirs);
237
238   if (loaded_dirs == NULL)
239     loaded_dirs = g_hash_table_new (g_str_hash, g_str_equal);
240
241   if (!g_hash_table_lookup_extended (loaded_dirs, directory,
242                                      NULL, NULL))
243     {
244       modules = load_modules (directory);
245       g_hash_table_insert (loaded_dirs,
246                            g_strdup (directory),
247                            modules);
248     }
249   
250   G_UNLOCK (loaded_dirs);
251 }
252
253 #define __G_IO_MODULE_C__
254 #include "gioaliasdef.c"