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