diff options
author | Francesco Giudici <fgiudici@redhat.com> | 2017-12-21 10:36:13 +0100 |
---|---|---|
committer | Francesco Giudici <fgiudici@redhat.com> | 2017-12-23 02:00:58 +0100 |
commit | a47a882522e5003cf9628ae3040111c43444cb81 (patch) | |
tree | b414349daf89f6dd99ef6bfe4f4099264ddede6d | |
parent | 8342a66cb6d8b7f19950370a83cc74bf6638a526 (diff) | |
download | NetworkManager-a47a882522e5003cf9628ae3040111c43444cb81.tar.gz |
libnm-core: export a wrapper of json_object_iter_next () function
This is required in order to overcome the clash of the symbol in shared
libraries libjansson and libjson-glib: this happens in gnome-control-center,
which loads the libjson-glib shared library and the libnm one, which has
libjansson as a dependency.
Declare also the macro 'nm_json_object_foreach' and
'nm_json_object_foreach_safe' which are basically a clone of the
'json_object_foreach' and 'json_object_foreach_safe' ones, but drop the
clashing symbol in favor of the new wrapper.
-rw-r--r-- | shared/nm-utils/nm-jansson.h | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/shared/nm-utils/nm-jansson.h b/shared/nm-utils/nm-jansson.h index ac95a2916b..e6be2a3570 100644 --- a/shared/nm-utils/nm-jansson.h +++ b/shared/nm-utils/nm-jansson.h @@ -25,6 +25,82 @@ #if WITH_JANSSON #include <jansson.h> +#include <dlfcn.h> + +/* + * 'json_object_iter_next' symbol clashes with libjson-glib: as + * gnome-control-center links both libjson-glib and libnm, we would + * end up resolving 'json_object_iter_next' in the wrong library when + * calling libnm-core functions in g-c-c. + * Expose a wrapper to allow calling 'json_object_iter_next' from + * libjansson in libnm-core when a program binds both libjson-glib + * and libnm (leverage dlopen()). + */ +static void __attribute__((used)) +*nm_json_object_iter_next (json_t *json, void *iter, GError **error) +{ + const char *libjansson = "libjansson.so.4"; + const char *jsymbol = "json_object_iter_next"; + void *handle; + void *retval = NULL; + void *(*iter_next)(json_t *json, void *iter); + char *dl_error; + gboolean already_open = TRUE; + + g_return_val_if_fail (!error || !*error, NULL); + + handle = dlopen (libjansson, RTLD_NOLOAD | RTLD_LAZY); + if (!handle) { + dlerror (); + handle = dlopen (libjansson, RTLD_LAZY); + if (!handle) { + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + _("cannot dlopen '%s': %s"), libjansson, dlerror ()); + goto done; + } + already_open = FALSE; + } + + dlerror (); + *(void **) (&iter_next) = dlsym (handle, jsymbol); + dl_error = dlerror (); + + if (error != NULL) { + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + _("cannot dlsym symbol '%s':%s"), jsymbol, dl_error); + goto done; + } + + retval = iter_next (json, iter); +done: + if (!already_open) + dlclose (handle); + return retval; +} + +/* Clone of 'json_object_foreach' skipping 'json_object_iter_next' in + * favor of the 'nm_json_object_iter_next' wrapper */ +#define nm_json_object_foreach(object, key, value) \ + for(key = json_object_iter_key(json_object_iter(object)); \ + key && (value = json_object_iter_value(json_object_iter_at (object, key) )); \ + key = json_object_iter_key(nm_json_object_iter_next(object, json_object_iter_at (object, key), NULL))) +/* Clone of 'json_object_foreach_safe' skipping 'json_object_iter_next' + * in favor of the 'nm_json_object_iter_next' wrapper */ +#if JANSSON_VERSION_HEX < 0x020300 +#define nm_json_object_foreach_safe(object, n, key, value) \ + for (key = json_object_iter_key (json_object_iter (object)), \ + n = nm_json_object_iter_next (object, json_object_iter_at (object, key), NULL); \ + key && (value = json_object_iter_value (json_object_iter_at (object, key))); \ + key = json_object_iter_key (n), \ + n = nm_json_object_iter_next (object, json_object_iter_at (object, key), NULL)) +#else +#define nm_json_object_foreach_safe(object, n, key, value) \ + for(key = json_object_iter_key(json_object_iter(object)), \ + n = nm_json_object_iter_next(object, json_object_key_to_iter(key), NULL); \ + key && (value = json_object_iter_value(json_object_key_to_iter(key))); \ + key = json_object_iter_key(n), \ + n = nm_json_object_iter_next(object, json_object_key_to_iter(key), NULL)) +#endif /* Added in Jansson v2.3 (released Jan 27 2012) */ #ifndef json_object_foreach |