summaryrefslogtreecommitdiff
path: root/libnm/nm-libnm-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm/nm-libnm-utils.c')
-rw-r--r--libnm/nm-libnm-utils.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/libnm/nm-libnm-utils.c b/libnm/nm-libnm-utils.c
index fbbfe2c552..a01228d5bb 100644
--- a/libnm/nm-libnm-utils.c
+++ b/libnm/nm-libnm-utils.c
@@ -23,6 +23,8 @@
#include "nm-libnm-utils.h"
+#include <girepository.h>
+
/*****************************************************************************/
char *
@@ -160,3 +162,83 @@ next:
nm_assert (g_utf8_validate (desc_full, -1, NULL));
return desc_full;
}
+
+#if WITH_FAKE_TYPELIBS
+
+/*
+ * Here we register empty "NMClient" and "NetworkManager" GIR modules as soon
+ * as we are loaded (if gnome-introspection is being used). This prevents the
+ * real modules from being loaded because they would in turn load libnm-glib
+ * and abort() and crash.
+ *
+ * For the high level languages that utilize GIR the crash is highly inconvenient
+ * while the inability to resolve any methods and attributes is potentially
+ * recoverable.
+ */
+
+GResource *typelibs_get_resource (void);
+void typelibs_register_resource (void);
+
+static void __attribute__((constructor))
+_nm_libnm_utils_init (void)
+{
+ GITypelib *typelib;
+ GBytes *data;
+ const char *namespace;
+ GModule *self;
+ GITypelib *(*_g_typelib_new_from_const_memory) (const guint8 *memory,
+ gsize len,
+ GError **error) = NULL;
+ const char *(*_g_irepository_load_typelib) (GIRepository *repository,
+ GITypelib *typelib,
+ GIRepositoryLoadFlags flags,
+ GError **error) = NULL;
+ const char *names[] = { "/org/freedesktop/libnm/fake-typelib/NetworkManager.typelib",
+ "/org/freedesktop/libnm/fake-typelib/NMClient.typelib" };
+ int i;
+
+ self = g_module_open (NULL, 0);
+ if (!self)
+ return;
+ g_module_symbol (self, "g_typelib_new_from_const_memory",
+ (gpointer *) &_g_typelib_new_from_const_memory);
+ if (_g_typelib_new_from_const_memory) {
+ g_module_symbol (self, "g_irepository_load_typelib",
+ (gpointer *) &_g_irepository_load_typelib);
+ }
+ g_module_close (self);
+
+ if (!_g_typelib_new_from_const_memory || !_g_irepository_load_typelib)
+ return;
+
+ typelibs_register_resource ();
+
+ for (i = 0; i < 2; i++) {
+ gs_free_error GError *error = NULL;
+
+ data = g_resource_lookup_data (typelibs_get_resource (),
+ names[i],
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ &error);
+ if (!data) {
+ g_warning ("Fake typelib %s could not be loaded: %s", names[i], error->message);
+ return;
+ }
+
+ typelib = _g_typelib_new_from_const_memory (g_bytes_get_data (data, NULL),
+ g_bytes_get_size (data),
+ &error);
+ if (!typelib) {
+ g_warning ("Could not create fake typelib instance %s: %s", names[i], error->message);
+ return;
+ }
+
+ namespace = _g_irepository_load_typelib (NULL, typelib, 0, &error);
+ if (!namespace) {
+ g_warning ("Could not load fake typelib %s: %s", names[i], error->message);
+ return;
+ }
+ }
+}
+
+#endif /* WITH_FAKE_TYPELIBS */