summaryrefslogtreecommitdiff
path: root/libnm
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2019-04-03 08:52:38 +0200
committerLubomir Rintel <lkundrak@v3.sk>2019-04-03 08:52:38 +0200
commitb027723e00679f2b709880407a6ff24583faeae3 (patch)
treeb972843460a92d737edb7512444b24791118f9de /libnm
parent61aad8cda475a07d579a85f209696d1ff8fd3e84 (diff)
downloadNetworkManager-b027723e00679f2b709880407a6ff24583faeae3.tar.gz
Revert "all: goodbye libnm-glib"
We need this for a little little longer :( This reverts commit 1de8383ad9fdfc8f552117e5d109bdfa7005634b.
Diffstat (limited to 'libnm')
-rw-r--r--libnm/fake-typelib/NMClient.gir9
-rw-r--r--libnm/fake-typelib/NetworkManager.gir10
-rw-r--r--libnm/fake-typelib/meson.build30
-rw-r--r--libnm/fake-typelib/typelibs.gresource.xml7
-rw-r--r--libnm/meson.build5
-rw-r--r--libnm/nm-libnm-utils.c82
6 files changed, 143 insertions, 0 deletions
diff --git a/libnm/fake-typelib/NMClient.gir b/libnm/fake-typelib/NMClient.gir
new file mode 100644
index 0000000000..3002f8d630
--- /dev/null
+++ b/libnm/fake-typelib/NMClient.gir
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!-- A lame duck typelib which prevents GIR from loading the
+ real one (which would crash due to conflict with libnm) -->
+<repository version="1.2"
+ xmlns="http://www.gtk.org/introspection/core/1.0"
+ xmlns:c="http://www.gtk.org/introspection/c/1.0"
+ xmlns:glib="http://www.gtk.org/introspection/glib/1.0">
+ <namespace name="NMClient" version="0.0" />
+</repository>
diff --git a/libnm/fake-typelib/NetworkManager.gir b/libnm/fake-typelib/NetworkManager.gir
new file mode 100644
index 0000000000..d15d29afc7
--- /dev/null
+++ b/libnm/fake-typelib/NetworkManager.gir
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!-- A lame duck typelib which prevents GIR from loading the
+ real one (which would crash due to conflict with libnm) -->
+<repository version="1.2"
+ xmlns="http://www.gtk.org/introspection/core/1.0"
+ xmlns:c="http://www.gtk.org/introspection/c/1.0"
+ xmlns:glib="http://www.gtk.org/introspection/glib/1.0">
+ <namespace name="NetworkManager" version="0.0">
+ </namespace>
+</repository>
diff --git a/libnm/fake-typelib/meson.build b/libnm/fake-typelib/meson.build
new file mode 100644
index 0000000000..fdbb29202e
--- /dev/null
+++ b/libnm/fake-typelib/meson.build
@@ -0,0 +1,30 @@
+g_ir_compiler = find_program('g-ir-compiler')
+
+girs = [
+ 'NetworkManager',
+ 'NMClient',
+]
+
+resource_data = []
+
+foreach gir: girs
+ gir_typelib = gir + '.typelib'
+
+ resource_data += custom_target(
+ gir_typelib,
+ input: gir + '.gir',
+ output: gir_typelib,
+ command: [g_ir_compiler, '@INPUT@', '-o', '@OUTPUT@'],
+ )
+endforeach
+
+resource = 'typelibs'
+
+libnm_utils_sources += gnome.compile_resources(
+ resource,
+ resource + '.gresource.xml',
+ source_dir: '.',
+ dependencies: resource_data,
+ extra_args: '--manual-register',
+ export: true,
+)
diff --git a/libnm/fake-typelib/typelibs.gresource.xml b/libnm/fake-typelib/typelibs.gresource.xml
new file mode 100644
index 0000000000..9a71d97544
--- /dev/null
+++ b/libnm/fake-typelib/typelibs.gresource.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/freedesktop/libnm/fake-typelib">
+ <file>NetworkManager.typelib</file>
+ <file>NMClient.typelib</file>
+ </gresource>
+</gresources>
diff --git a/libnm/meson.build b/libnm/meson.build
index 86345c7a6d..558a587b4a 100644
--- a/libnm/meson.build
+++ b/libnm/meson.build
@@ -13,6 +13,11 @@ deps = [
nm_core_dep,
]
+if have_fake_typelibs
+ deps += gir_dep
+ subdir('fake-typelib')
+endif
+
libnm_utils = static_library(
'nm-utils',
sources: libnm_utils_sources,
diff --git a/libnm/nm-libnm-utils.c b/libnm/nm-libnm-utils.c
index 580d576be6..f740c37caf 100644
--- a/libnm/nm-libnm-utils.c
+++ b/libnm/nm-libnm-utils.c
@@ -561,3 +561,85 @@ nm_utils_fixup_product_string (const char *desc)
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.
+ */
+
+#include <girepository.h>
+
+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 */