nautilus-3.6.3/libnautilus-private/nautilus-module.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found nautilus-module.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
  2 /*
  3  *  nautilus-module.h - Interface to nautilus extensions
  4  * 
  5  *  Copyright (C) 2003 Novell, Inc.
  6  *
  7  *  This library is free software; you can redistribute it and/or
  8  *  modify it under the terms of the GNU Library General Public
  9  *  License as published by the Free Software Foundation; either
 10  *  version 2 of the License, or (at your option) any later version.
 11  *
 12  *  This library is distributed in the hope that it will be useful,
 13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15  *  Library General Public License for more details.
 16  *
 17  *  You should have received a copy of the GNU Library General Public
 18  *  License along with this library; if not, write to the Free
 19  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20  *
 21  *  Author: Dave Camp <dave@ximian.com>
 22  * 
 23  */
 24 
 25 #include <config.h>
 26 #include "nautilus-module.h"
 27 
 28 #include <eel/eel-debug.h>
 29 #include <gmodule.h>
 30 
 31 #define NAUTILUS_TYPE_MODULE    	(nautilus_module_get_type ())
 32 #define NAUTILUS_MODULE(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_MODULE, NautilusModule))
 33 #define NAUTILUS_MODULE_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_MODULE, NautilusModule))
 34 #define NAUTILUS_IS_MODULE(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_MODULE))
 35 #define NAUTILUS_IS_MODULE_CLASS(klass)	(G_TYPE_CLASS_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_MODULE))
 36 
 37 typedef struct _NautilusModule        NautilusModule;
 38 typedef struct _NautilusModuleClass   NautilusModuleClass;
 39 
 40 struct _NautilusModule {
 41 	GTypeModule parent;
 42 
 43 	GModule *library;
 44 
 45 	char *path;
 46 
 47 	void (*initialize) (GTypeModule  *module);
 48 	void (*shutdown)   (void);
 49 
 50 	void (*list_types) (const GType **types,
 51 			    int          *num_types);
 52 
 53 };
 54 
 55 struct _NautilusModuleClass {
 56 	GTypeModuleClass parent;	
 57 };
 58 
 59 static GList *module_objects = NULL;
 60 
 61 static GType nautilus_module_get_type (void);
 62 
 63 G_DEFINE_TYPE (NautilusModule, nautilus_module, G_TYPE_TYPE_MODULE);
 64 
 65 static gboolean
 66 module_pulls_in_orbit (GModule *module)
 67 {
 68 	gpointer symbol;
 69 	gboolean res;
 70 
 71 	res = g_module_symbol (module, "ORBit_realloc_tcval", &symbol);
 72 
 73 	return res;
 74 }
 75 
 76 static gboolean
 77 nautilus_module_load (GTypeModule *gmodule)
 78 {
 79 	NautilusModule *module;
 80 	
 81 	module = NAUTILUS_MODULE (gmodule);
 82 	
 83 	module->library = g_module_open (module->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
 84 
 85 	if (!module->library) {
 86 		g_warning ("%s", g_module_error ());
 87 		return FALSE;
 88 	}
 89 
 90 	/* ORBit installs atexit() handlers, which would get unloaded together
 91 	 * with the module now that the main process doesn't depend on GConf anymore,
 92 	 * causing nautilus to sefgault at exit.
 93 	 * If we detect that an extension would pull in ORBit, we make the
 94 	 * module resident to prevent that.
 95 	 */
 96         if (module_pulls_in_orbit (module->library)) {
 97 		g_module_make_resident (module->library);
 98         }
 99 
100 	if (!g_module_symbol (module->library,
101 			      "nautilus_module_initialize",
102 			      (gpointer *)&module->initialize) ||
103 	    !g_module_symbol (module->library,
104 			      "nautilus_module_shutdown",
105 			      (gpointer *)&module->shutdown) ||
106 	    !g_module_symbol (module->library,
107 			      "nautilus_module_list_types",
108 			      (gpointer *)&module->list_types)) {
109 
110 		g_warning ("%s", g_module_error ());
111 		g_module_close (module->library);
112 		
113 		return FALSE;
114 	}
115 
116 	module->initialize (gmodule);
117 	
118 	return TRUE;
119 }
120 
121 static void
122 nautilus_module_unload (GTypeModule *gmodule)
123 {
124 	NautilusModule *module;
125 	
126 	module = NAUTILUS_MODULE (gmodule);
127 	
128 	module->shutdown ();
129 	
130 	g_module_close (module->library);
131 	
132 	module->initialize = NULL;
133 	module->shutdown = NULL;
134 	module->list_types = NULL;
135 }
136 
137 static void
138 nautilus_module_finalize (GObject *object)
139 {
140 	NautilusModule *module;
141 	
142 	module = NAUTILUS_MODULE (object);
143 
144 	g_free (module->path);
145 	
146 	G_OBJECT_CLASS (nautilus_module_parent_class)->finalize (object);
147 }
148 
149 static void
150 nautilus_module_init (NautilusModule *module)
151 {
152 }
153 
154 static void
155 nautilus_module_class_init (NautilusModuleClass *class)
156 {
157 	G_OBJECT_CLASS (class)->finalize = nautilus_module_finalize;
158 	G_TYPE_MODULE_CLASS (class)->load = nautilus_module_load;
159 	G_TYPE_MODULE_CLASS (class)->unload = nautilus_module_unload;
160 }
161 
162 static void
163 module_object_weak_notify (gpointer user_data, GObject *object)
164 {
165 	module_objects = g_list_remove (module_objects, object);
166 }
167 
168 static void
169 add_module_objects (NautilusModule *module)
170 {
171 	const GType *types;
172 	int num_types;
173 	int i;
174 	
175 	module->list_types (&types, &num_types);
176 	
177 	for (i = 0; i < num_types; i++) {
178 		if (types[i] == 0) { /* Work around broken extensions */
179 			break;
180 		}
181 		nautilus_module_add_type (types[i]);
182 	}
183 }
184 
185 static NautilusModule *
186 nautilus_module_load_file (const char *filename)
187 {
188 	NautilusModule *module;
189 	
190 	module = g_object_new (NAUTILUS_TYPE_MODULE, NULL);
191 	module->path = g_strdup (filename);
192 	
193 	if (g_type_module_use (G_TYPE_MODULE (module))) {
194 		add_module_objects (module);
195 		g_type_module_unuse (G_TYPE_MODULE (module));
196 		return module;
197 	} else {
198 		g_object_unref (module);
199 		return NULL;
200 	}
201 }
202 
203 static void
204 load_module_dir (const char *dirname)
205 {
206 	GDir *dir;
207 	
208 	dir = g_dir_open (dirname, 0, NULL);
209 	
210 	if (dir) {
211 		const char *name;
212 		
213 		while ((name = g_dir_read_name (dir))) {
214 			if (g_str_has_suffix (name, "." G_MODULE_SUFFIX)) {
215 				char *filename;
216 
217 				filename = g_build_filename (dirname, 
218 							     name, 
219 							     NULL);
220 				nautilus_module_load_file (filename);
221 				g_free (filename);
222 			}
223 		}
224 
225 		g_dir_close (dir);
226 	}
227 }
228 
229 static void
230 free_module_objects (void)
231 {
232 	GList *l, *next;
233 	
234 	for (l = module_objects; l != NULL; l = next) {
235 		next = l->next;
236 		g_object_unref (l->data);
237 	}
238 	
239 	g_list_free (module_objects);
240 }
241 
242 void
243 nautilus_module_setup (void)
244 {
245 	static gboolean initialized = FALSE;
246 
247 	if (!initialized) {
248 		initialized = TRUE;
249 		
250 		load_module_dir (NAUTILUS_EXTENSIONDIR);
251 
252 		eel_debug_call_at_shutdown (free_module_objects);
253 	}
254 }
255 
256 GList *
257 nautilus_module_get_extensions_for_type (GType type)
258 {
259 	GList *l;
260 	GList *ret = NULL;
261 	
262 	for (l = module_objects; l != NULL; l = l->next) {
263 		if (G_TYPE_CHECK_INSTANCE_TYPE (G_OBJECT (l->data),
264 						type)) {
265 			g_object_ref (l->data);
266 			ret = g_list_prepend (ret, l->data);
267 		}
268 	}
269 
270 	return ret;	
271 }
272 
273 void
274 nautilus_module_extension_list_free (GList *extensions)
275 {
276 	GList *l, *next;
277 	
278 	for (l = extensions; l != NULL; l = next) {
279 		next = l->next;
280 		g_object_unref (l->data);
281 	}
282 	g_list_free (extensions);
283 }
284 
285 void   
286 nautilus_module_add_type (GType type)
287 {
288 	GObject *object;
289 	
290 	object = g_object_new (type, NULL);
291 	g_object_weak_ref (object, 
292 			   (GWeakNotify)module_object_weak_notify,
293 			   NULL);
294 
295 	module_objects = g_list_prepend (module_objects, object);
296 }