Blame libnm-core/nm-json.c

Packit Service b23acc
// SPDX-License-Identifier: LGPL-2.1+
Packit Service b23acc
/*
Packit Service b23acc
 * Copyright (C) 2017, 2018 Red Hat, Inc.
Packit Service b23acc
 */
Packit Service b23acc
Packit Service b23acc
#include "nm-default.h"
Packit Service b23acc
Packit Service b23acc
#define NM_JANSSON_C
Packit Service b23acc
#include "nm-json.h"
Packit Service b23acc
Packit Service b23acc
#include <dlfcn.h>
Packit Service b23acc
Packit Service b23acc
void *_nm_jansson_json_object_iter_value;
Packit Service b23acc
void *_nm_jansson_json_object_key_to_iter;
Packit Service b23acc
void *_nm_jansson_json_integer;
Packit Service b23acc
void *_nm_jansson_json_object_del;
Packit Service b23acc
void *_nm_jansson_json_array_get;
Packit Service b23acc
void *_nm_jansson_json_array_size;
Packit Service b23acc
void *_nm_jansson_json_array_append_new;
Packit Service b23acc
void *_nm_jansson_json_string;
Packit Service b23acc
void *_nm_jansson_json_object_iter_next;
Packit Service b23acc
void *_nm_jansson_json_loads;
Packit Service b23acc
void *_nm_jansson_json_dumps;
Packit Service b23acc
void *_nm_jansson_json_object_iter_key;
Packit Service b23acc
void *_nm_jansson_json_object;
Packit Service b23acc
void *_nm_jansson_json_object_get;
Packit Service b23acc
void *_nm_jansson_json_array;
Packit Service b23acc
void *_nm_jansson_json_false;
Packit Service b23acc
void *_nm_jansson_json_delete;
Packit Service b23acc
void *_nm_jansson_json_true;
Packit Service b23acc
void *_nm_jansson_json_object_size;
Packit Service b23acc
void *_nm_jansson_json_object_set_new;
Packit Service b23acc
void *_nm_jansson_json_object_iter;
Packit Service b23acc
void *_nm_jansson_json_integer_value;
Packit Service b23acc
void *_nm_jansson_json_string_value;
Packit Service b23acc
Packit Service b23acc
#define TRY_BIND_SYMBOL(symbol) \
Packit Service b23acc
	G_STMT_START { \
Packit Service b23acc
		void *sym = dlsym (handle, #symbol); \
Packit Service b23acc
		if (_nm_jansson_ ## symbol && sym != _nm_jansson_ ## symbol) \
Packit Service b23acc
			return FALSE; \
Packit Service b23acc
		_nm_jansson_ ## symbol = sym; \
Packit Service b23acc
	} G_STMT_END
Packit Service b23acc
Packit Service b23acc
static gboolean
Packit Service b23acc
bind_symbols (void *handle)
Packit Service b23acc
{
Packit Service b23acc
	TRY_BIND_SYMBOL (json_object_iter_value);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_object_key_to_iter);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_integer);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_object_del);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_array_get);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_array_size);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_array_append_new);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_string);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_object_iter_next);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_loads);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_dumps);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_object_iter_key);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_object);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_object_get);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_array);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_false);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_delete);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_true);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_object_size);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_object_set_new);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_object_iter);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_integer_value);
Packit Service b23acc
	TRY_BIND_SYMBOL (json_string_value);
Packit Service b23acc
Packit Service b23acc
	return TRUE;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
gboolean
Packit Service b23acc
nm_jansson_load (void)
Packit Service b23acc
{
Packit Service b23acc
	static enum {
Packit Service b23acc
		UNKNOWN,
Packit Service b23acc
		AVAILABLE,
Packit Service b23acc
		MISSING,
Packit Service b23acc
	} state = UNKNOWN;
Packit Service b23acc
	void *handle;
Packit Service b23acc
	int mode;
Packit Service b23acc
Packit Service b23acc
	if (G_LIKELY (state != UNKNOWN))
Packit Service b23acc
		goto out;
Packit Service b23acc
Packit Service b23acc
	/* First just resolve the symbols to see if there's a conflict already. */
Packit Service b23acc
	if (!bind_symbols (RTLD_DEFAULT))
Packit Service b23acc
		goto out;
Packit Service b23acc
Packit Service b23acc
	mode = RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE | RTLD_DEEPBIND;
Packit Service b23acc
#if defined (ASAN_BUILD)
Packit Service b23acc
	/* Address sanitizer is incompatible with RTLD_DEEPBIND. */
Packit Service b23acc
	mode &= ~RTLD_DEEPBIND;
Packit Service b23acc
#endif
Packit Service b23acc
	handle = dlopen (JANSSON_SONAME, mode);
Packit Service b23acc
Packit Service b23acc
	if (!handle)
Packit Service b23acc
		goto out;
Packit Service b23acc
Packit Service b23acc
	/* Now do the actual binding. */
Packit Service b23acc
	if (!bind_symbols (handle))
Packit Service b23acc
		goto out;
Packit Service b23acc
Packit Service b23acc
	state = AVAILABLE;
Packit Service b23acc
out:
Packit Service b23acc
	return state == AVAILABLE;
Packit Service b23acc
}