[glib] GIOModule: Use unique names for load/unload symbols
- From: Xavier Claessens <xclaesse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GIOModule: Use unique names for load/unload symbols
- Date: Thu, 4 Jan 2018 16:15:55 +0000 (UTC)
commit 7f69b828fcf952fac9cb27da1e74b2fdffa997d0
Author: Xavier Claessens <xavier claessens collabora com>
Date: Thu Nov 30 15:36:21 2017 -0500
GIOModule: Use unique names for load/unload symbols
GIO modules should include their name into their exported symbols to
make them unique. This avoids symbol clash when building modules
statically.
extract_name() function is copied from GStreamer which recently
switched to the same symbol naming scheme.
https://bugzilla.gnome.org/show_bug.cgi?id=684282
gio/Makefile.am | 3 +-
gio/gio-querymodules.c | 16 ++++++++++-
gio/giomodule-priv.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++
gio/giomodule-priv.h | 3 ++
gio/giomodule.c | 44 ++++++++++++++++++++++++++----
gio/giomodule.h | 24 ++++++++++++++++
gio/meson.build | 3 +-
7 files changed, 153 insertions(+), 9 deletions(-)
---
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 0cfda50..9b3d04e 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -476,6 +476,7 @@ gio_base_sources = \
gioenums.h \
gioerror.c \
giomodule.c \
+ giomodule-priv.c \
giomodule-priv.h \
gioscheduler.c \
giostream.c \
@@ -815,7 +816,7 @@ glib_compile_resources_SOURCES = \
gvdb/gvdb-builder.c \
glib-compile-resources.c
-gio_querymodules_SOURCES = gio-querymodules.c
+gio_querymodules_SOURCES = gio-querymodules.c giomodule-priv.c
gio_querymodules_LDADD = libgio-2.0.la \
$(top_builddir)/gobject/libgobject-2.0.la \
$(top_builddir)/gmodule/libgmodule-2.0.la \
diff --git a/gio/gio-querymodules.c b/gio/gio-querymodules.c
index 7abfe07..74c6594 100644
--- a/gio/gio-querymodules.c
+++ b/gio/gio-querymodules.c
@@ -20,6 +20,7 @@
#include "config.h"
#include "giomodule.h"
+#include "giomodule-priv.h"
#include <gstdio.h>
#include <errno.h>
@@ -83,7 +84,20 @@ query_dir (const char *dirname)
if (module)
{
- g_module_symbol (module, "g_io_module_query", (gpointer) &query);
+ gchar *modulename;
+ gchar *symname;
+
+ modulename = _g_io_module_extract_name (name);
+ symname = g_strconcat ("g_io_", modulename, "_query", NULL);
+ g_module_symbol (module, symname, (gpointer) &query);
+ g_free (symname);
+ g_free (modulename);
+
+ if (!query)
+ {
+ /* Fallback to old name */
+ g_module_symbol (module, "g_io_module_query", (gpointer) &query);
+ }
if (query)
{
diff --git a/gio/giomodule-priv.c b/gio/giomodule-priv.c
new file mode 100644
index 0000000..41afa54
--- /dev/null
+++ b/gio/giomodule-priv.c
@@ -0,0 +1,69 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2017 Collabora Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Xavier Claessens <xavier claessens collabora com>
+ */
+
+#include "config.h"
+#include "giomodule.h"
+#include "giomodule-priv.h"
+
+#include <string.h>
+
+/**
+ * _g_io_module_extract_name:
+ * @filename: filename of a GIOModule
+ *
+ * Extract the plugin name from its filename. It removes optional "lib" or
+ * "libgio" prefix, and removes everything after the first dot. For example:
+ * "libgiognutls.so" -> "gnutls".
+ *
+ * Returns: (transfer full): the module's name
+ */
+gchar *
+_g_io_module_extract_name (const char *filename)
+{
+ gchar *bname, *name;
+ const gchar *dot;
+ gsize prefix_len, len;
+ gsize i;
+
+ bname = g_path_get_basename (filename);
+ for (i = 0; bname[i]; ++i)
+ {
+ if (bname[i] == '-')
+ bname[i] = '_';
+ }
+
+ if (g_str_has_prefix (bname, "libgio"))
+ prefix_len = 6;
+ else if (g_str_has_prefix (bname, "lib"))
+ prefix_len = 3;
+ else
+ prefix_len = 0; /* use whole name (minus suffix) as plugin name */
+
+ dot = strchr (bname, '.');
+ if (dot != NULL)
+ len = dot - bname - prefix_len;
+ else
+ len = strlen (bname + prefix_len);
+
+ name = g_strndup (bname + prefix_len, len);
+ g_free (bname);
+
+ return name;
+}
diff --git a/gio/giomodule-priv.h b/gio/giomodule-priv.h
index e480593..68d46f2 100644
--- a/gio/giomodule-priv.h
+++ b/gio/giomodule-priv.h
@@ -41,6 +41,9 @@ GType _g_io_module_get_default_type (const gchar *extension_point,
void *_g_io_win32_get_module (void);
#endif
+gchar *_g_io_module_extract_name (const char *filename);
+
+
G_END_DECLS
#endif /* __G_IO_MODULE_PRIV_H__ */
diff --git a/gio/giomodule.c b/gio/giomodule.c
index 4047695..1adfd93 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -291,6 +291,43 @@ g_io_module_finalize (GObject *object)
}
static gboolean
+load_symbols (GIOModule *module)
+{
+ gchar *name;
+ gchar *load_symname;
+ gchar *unload_symname;
+ gboolean ret;
+
+ name = _g_io_module_extract_name (module->filename);
+ load_symname = g_strconcat ("g_io_", name, "_load", NULL);
+ unload_symname = g_strconcat ("g_io_", name, "_unload", NULL);
+
+ ret = g_module_symbol (module->library,
+ load_symname,
+ (gpointer) &module->load) &&
+ g_module_symbol (module->library,
+ unload_symname,
+ (gpointer) &module->unload);
+
+ if (!ret)
+ {
+ /* Fallback to old names */
+ ret = g_module_symbol (module->library,
+ "g_io_module_load",
+ (gpointer) &module->load) &&
+ g_module_symbol (module->library,
+ "g_io_module_unload",
+ (gpointer) &module->unload);
+ }
+
+ g_free (name);
+ g_free (load_symname);
+ g_free (unload_symname);
+
+ return ret;
+}
+
+static gboolean
g_io_module_load_module (GTypeModule *gmodule)
{
GIOModule *module = G_IO_MODULE (gmodule);
@@ -310,12 +347,7 @@ g_io_module_load_module (GTypeModule *gmodule)
}
/* Make sure that the loaded library contains the required methods */
- if (! g_module_symbol (module->library,
- "g_io_module_load",
- (gpointer) &module->load) ||
- ! g_module_symbol (module->library,
- "g_io_module_unload",
- (gpointer) &module->unload))
+ if (!load_symbols (module))
{
g_printerr ("%s\n", g_module_error ());
g_module_close (module->library);
diff --git a/gio/giomodule.h b/gio/giomodule.h
index 485f5eb..e94b809 100644
--- a/gio/giomodule.h
+++ b/gio/giomodule.h
@@ -112,6 +112,14 @@ GTypeClass* g_io_extension_ref_class (GIOExtension
* This function is run after the module has been loaded into GIO,
* to initialize the module. Typically, this function will call
* g_io_extension_point_implement().
+ *
+ * Since 2.56, this function should be named `g_io_<modulename>_load`, where
+ * `modulename` is the plugin’s filename with the `lib` or `libgio` prefix and
+ * everything after the first dot removed, and with `-` replaced with `_`
+ * throughout. For example, `libgiognutls-helper.so` becomes `gnutls_helper`.
+ * Using the new symbol names avoids name clashes when building modules
+ * statically. The old symbol names continue to be supported, but cannot be used
+ * for static builds.
**/
GLIB_AVAILABLE_IN_ALL
void g_io_module_load (GIOModule *module);
@@ -124,6 +132,14 @@ void g_io_module_load (GIOModule *module);
*
* This function is run when the module is being unloaded from GIO,
* to finalize the module.
+ *
+ * Since 2.56, this function should be named `g_io_<modulename>_unload`, where
+ * `modulename` is the plugin’s filename with the `lib` or `libgio` prefix and
+ * everything after the first dot removed, and with `-` replaced with `_`
+ * throughout. For example, `libgiognutls-helper.so` becomes `gnutls_helper`.
+ * Using the new symbol names avoids name clashes when building modules
+ * statically. The old symbol names continue to be supported, but cannot be used
+ * for static builds.
**/
GLIB_AVAILABLE_IN_ALL
void g_io_module_unload (GIOModule *module);
@@ -155,6 +171,14 @@ void g_io_module_unload (GIOModule *module);
* run gio-querymodules in order to build the cache files required for
* lazy loading.
*
+ * Since 2.56, this function should be named `g_io_<modulename>_query`, where
+ * `modulename` is the plugin’s filename with the `lib` or `libgio` prefix and
+ * everything after the first dot removed, and with `-` replaced with `_`
+ * throughout. For example, `libgiognutls-helper.so` becomes `gnutls_helper`.
+ * Using the new symbol names avoids name clashes when building modules
+ * statically. The old symbol names continue to be supported, but cannot be used
+ * for static builds.
+ *
* Returns: (transfer full): A %NULL-terminated array of strings,
* listing the supported extension points of the module. The array
* must be suitable for freeing with g_strfreev().
diff --git a/gio/meson.build b/gio/meson.build
index d7dcfa5..61a79d4 100644
--- a/gio/meson.build
+++ b/gio/meson.build
@@ -441,6 +441,7 @@ gio_sources = files(
'ginputstream.c',
'gioerror.c',
'giomodule.c',
+ 'giomodule-priv.c',
'gioscheduler.c',
'giostream.c',
'gloadableicon.c',
@@ -803,7 +804,7 @@ executable('gresource', 'gresource-tool.c',
link_args : noseh_link_args,
dependencies : [libelf, libintl, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
-executable('gio-querymodules', 'gio-querymodules.c',
+executable('gio-querymodules', 'gio-querymodules.c', 'giomodule-priv.c',
install : true,
c_args : ['-DHAVE_CONFIG_H=1'] + gio_c_args,
# intl.lib is not compatible with SAFESEH
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]