#include <sys/stat.h>
#include <dirent.h>
-#define PLUGIN_SYMBOL_NAME "__bt_plugin_name"
-#define PLUGIN_SYMBOL_AUTHOR "__bt_plugin_author"
-#define PLUGIN_SYMBOL_LICENSE "__bt_plugin_license"
-#define PLUGIN_SYMBOL_INIT "__bt_plugin_init"
-#define PLUGIN_SYMBOL_EXIT "__bt_plugin_exit"
-#define PLUGIN_SYMBOL_DESCRIPTION "__bt_plugin_description"
#define NATIVE_PLUGIN_SUFFIX ".so"
#define NATIVE_PLUGIN_SUFFIX_LEN sizeof(NATIVE_PLUGIN_SUFFIX)
#define LIBTOOL_PLUGIN_SUFFIX ".la"
#define PLUGIN_SUFFIX_LEN max_t(size_t, sizeof(NATIVE_PLUGIN_SUFFIX), \
sizeof(LIBTOOL_PLUGIN_SUFFIX))
-#define SECTION_BEGIN(_name) &__start_##_name
-#define SECTION_END(_name) &__stop_##_name
+#define SECTION_BEGIN(_name) (&(__start_##_name))
+#define SECTION_END(_name) (&(__stop_##_name))
#define SECTION_ELEMENT_COUNT(_name) (SECTION_END(_name) - SECTION_BEGIN(_name))
#define DECLARE_SECTION(_type, _name) \
- extern _type const __start_##_name __attribute((weak)); \
- extern _type const __stop_##_name __attribute((weak))
-
-DECLARE_SECTION(bt_plugin_init_func, __bt_plugin_init_funcs);
-DECLARE_SECTION(bt_plugin_exit_func, __bt_plugin_exit_funcs);
-DECLARE_SECTION(const char *, __bt_plugin_names);
-DECLARE_SECTION(const char *, __bt_plugin_authors);
-DECLARE_SECTION(const char *, __bt_plugin_licenses);
-DECLARE_SECTION(const char *, __bt_plugin_descriptions);
-
-#define PRINT_SECTION(_printer, _name) \
- do { \
- _printer("Section " #_name " [%p - %p], (%zu elements)\n", \
- SECTION_BEGIN(_name), SECTION_END(_name), \
- SECTION_ELEMENT_COUNT(_name)); \
- } while (0)
-
-#define PRINT_PLUG_IN_SECTIONS(_printer) \
- do { \
- PRINT_SECTION(_printer, __bt_plugin_init_funcs); \
- PRINT_SECTION(_printer, __bt_plugin_exit_funcs); \
- PRINT_SECTION(_printer, __bt_plugin_names); \
- PRINT_SECTION(_printer, __bt_plugin_authors); \
- PRINT_SECTION(_printer, __bt_plugin_licenses); \
- PRINT_SECTION(_printer, __bt_plugin_descriptions); \
- } while (0)
+ extern _type __start_##_name __attribute((weak)); \
+ extern _type __stop_##_name __attribute((weak))
+
+DECLARE_SECTION(struct __bt_plugin_descriptor const *, __bt_plugin_descriptors);
+DECLARE_SECTION(struct __bt_plugin_descriptor_attribute const *, __bt_plugin_descriptor_attributes);
+DECLARE_SECTION(struct __bt_plugin_component_class_descriptor const *, __bt_plugin_component_class_descriptors);
+DECLARE_SECTION(struct __bt_plugin_component_class_descriptor_attribute const *, __bt_plugin_component_class_descriptor_attributes);
/*
* This hash table, global to the library, maps component class pointers
*
* 1. To allow this application:
*
- * my_plugin = bt_plugin_create_from_file("/path/to/my-plugin.so");
- * // instantiate components from the plugin's component classes
- * BT_PUT(my_plugin);
+ * my_plugins = bt_plugin_create_all_from_file("/path/to/my-plugin.so");
+ * // instantiate components from a plugin's component classes
+ * // put plugins and free my_plugins here
* // user code of instantiated components still exists
*
* 2. To decouple the plugin subsystem from the component subsystem:
enum bt_plugin_status status = shared_lib_handle->exit();
if (status < 0) {
- printf_verbose("Plugin `%s` exited with error %d\n",
- shared_lib_handle->name, status);
+ const char *path = shared_lib_handle->path ?
+ shared_lib_handle->path->str : "[built-in]";
+
+ printf_verbose("Plugin in module `%s` exited with error %d\n",
+ path, status);
}
}
const char *path)
{
struct bt_plugin_shared_lib_handle *shared_lib_handle = NULL;
- gpointer symbol = NULL;
shared_lib_handle = g_new0(struct bt_plugin_shared_lib_handle, 1);
if (!shared_lib_handle) {
goto error;
}
- if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_NAME,
- (gpointer *) &shared_lib_handle->name)) {
- printf_verbose("Unable to resolve plugin symbol %s from %s\n",
- PLUGIN_SYMBOL_NAME,
- g_module_name(shared_lib_handle->module));
- goto error;
- }
-
- if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_LICENSE,
- (gpointer *) &shared_lib_handle->license)) {
- printf_verbose("Unable to resolve plugin symbol %s from %s\n",
- PLUGIN_SYMBOL_LICENSE,
- g_module_name(shared_lib_handle->module));
- goto error;
- }
-
- if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_AUTHOR,
- (gpointer *) &shared_lib_handle->author)) {
- printf_verbose("Unable to resolve plugin symbol %s from %s\n",
- PLUGIN_SYMBOL_AUTHOR,
- g_module_name(shared_lib_handle->module));
- goto error;
- }
-
- if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_DESCRIPTION,
- (gpointer *) &shared_lib_handle->description)) {
- printf_verbose("Unable to resolve plugin symbol %s from %s\n",
- PLUGIN_SYMBOL_DESCRIPTION,
- g_module_name(shared_lib_handle->module));
- goto error;
- }
-
- if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_INIT,
- &symbol)) {
- printf_verbose("Unable to resolve plugin symbol %s from %s\n",
- PLUGIN_SYMBOL_INIT,
- g_module_name(shared_lib_handle->module));
- goto error;
- } else {
- shared_lib_handle->init = *((bt_plugin_init_func *) symbol);
- if (!shared_lib_handle->init) {
- printf_verbose("NULL %s symbol target\n",
- PLUGIN_SYMBOL_INIT);
- goto error;
- }
- }
-
- if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_EXIT,
- &symbol)) {
- printf_verbose("Unable to resolve plugin symbol %s from %s\n",
- PLUGIN_SYMBOL_EXIT,
- g_module_name(shared_lib_handle->module));
- goto error;
- } else {
- shared_lib_handle->exit = *((bt_plugin_exit_func *) symbol);
- if (!shared_lib_handle->exit) {
- printf_verbose("NULL %s symbol target\n",
- PLUGIN_SYMBOL_EXIT);
- goto error;
- }
- }
-
goto end;
error:
}
static
-enum bt_plugin_status init_plugin(struct bt_plugin *plugin)
+struct bt_plugin *bt_plugin_create_empty(
+ struct bt_plugin_shared_lib_handle *shared_lib_handle)
+{
+ struct bt_plugin *plugin = NULL;
+
+ plugin = g_new0(struct bt_plugin, 1);
+ if (!plugin) {
+ goto error;
+ }
+
+ bt_object_init(plugin, bt_plugin_destroy);
+ plugin->shared_lib_handle = bt_get(shared_lib_handle);
+
+ /* Create empty array of component classes */
+ plugin->comp_classes =
+ g_ptr_array_new_with_free_func((GDestroyNotify) bt_put);
+ if (!plugin->comp_classes) {
+ goto error;
+ }
+
+ goto end;
+
+error:
+ BT_PUT(plugin);
+
+end:
+ return plugin;
+}
+
+static
+enum bt_plugin_status bt_plugin_init(
+ struct bt_plugin *plugin,
+ const struct __bt_plugin_descriptor *descriptor,
+ struct __bt_plugin_descriptor_attribute const * const *attrs_begin,
+ struct __bt_plugin_descriptor_attribute const * const *attrs_end,
+ struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin,
+ struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end,
+ struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin,
+ struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end)
{
+ /*
+ * This structure's members point to the plugin's memory
+ * (do NOT free).
+ */
+ struct comp_class_full_descriptor {
+ const struct __bt_plugin_component_class_descriptor *descriptor;
+ const char *description;
+ };
+
enum bt_plugin_status status = BT_PLUGIN_STATUS_OK;
+ struct __bt_plugin_descriptor_attribute const * const *cur_attr_ptr;
+ struct __bt_plugin_component_class_descriptor const * const *cur_cc_descr_ptr;
+ struct __bt_plugin_component_class_descriptor_attribute const * const *cur_cc_descr_attr_ptr;
+ GArray *comp_class_full_descriptors;
+ size_t i;
+
+ comp_class_full_descriptors = g_array_new(FALSE, TRUE,
+ sizeof(struct comp_class_full_descriptor));
+ if (!comp_class_full_descriptors) {
+ status = BT_PLUGIN_STATUS_ERROR;
+ goto end;
+ }
- if (plugin->shared_lib_handle->init) {
- status = plugin->shared_lib_handle->init(plugin);
+ /* Set mandatory attributes */
+ plugin->descriptor = descriptor;
+ plugin->name = descriptor->name;
+ /*
+ * Find and set optional attributes attached to this plugin
+ * descriptor.
+ */
+ for (cur_attr_ptr = attrs_begin; cur_attr_ptr != attrs_end; cur_attr_ptr++) {
+ const struct __bt_plugin_descriptor_attribute *cur_attr =
+ *cur_attr_ptr;
+
+ if (cur_attr->plugin_descriptor != descriptor) {
+ continue;
+ }
+
+ switch (cur_attr->type) {
+ case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_INIT:
+ plugin->init = cur_attr->value.init;
+ break;
+ case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_EXIT:
+ plugin->shared_lib_handle->exit = cur_attr->value.exit;
+ break;
+ case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_AUTHOR:
+ plugin->author = cur_attr->value.author;
+ break;
+ case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_LICENSE:
+ plugin->license = cur_attr->value.license;
+ break;
+ case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_DESCRIPTION:
+ plugin->description = cur_attr->value.description;
+ break;
+ default:
+ printf_verbose("WARNING: Unknown attribute \"%s\" (type %d) for plugin %s\n",
+ cur_attr->type_name, cur_attr->type,
+ descriptor->name);
+ break;
+ }
+ }
+
+ /*
+ * Find component class descriptors attached to this plugin
+ * descriptor and initialize corresponding full component class
+ * descriptors in the array.
+ */
+ for (cur_cc_descr_ptr = cc_descriptors_begin; cur_cc_descr_ptr != cc_descriptors_end; cur_cc_descr_ptr++) {
+ const struct __bt_plugin_component_class_descriptor *cur_cc_descr =
+ *cur_cc_descr_ptr;
+ struct comp_class_full_descriptor full_descriptor;
+
+ if (cur_cc_descr->plugin_descriptor != descriptor) {
+ continue;
+ }
+
+ full_descriptor.descriptor = cur_cc_descr;
+ full_descriptor.description = NULL;
+ g_array_append_val(comp_class_full_descriptors,
+ full_descriptor);
+ }
+
+ /*
+ * Find component class descriptor attributes attached to this
+ * plugin descriptor and update corresponding full component
+ * class descriptors in the array.
+ */
+ for (cur_cc_descr_attr_ptr = cc_descr_attrs_begin; cur_cc_descr_attr_ptr != cc_descr_attrs_end; cur_cc_descr_attr_ptr++) {
+ const struct __bt_plugin_component_class_descriptor_attribute *cur_cc_descr_attr =
+ *cur_cc_descr_attr_ptr;
+
+ if (cur_cc_descr_attr->comp_class_descriptor->plugin_descriptor !=
+ descriptor) {
+ continue;
+ }
+
+ /* Find the corresponding component class descriptor entry */
+ for (i = 0; i < comp_class_full_descriptors->len; i++) {
+ struct comp_class_full_descriptor *cc_full_descr =
+ &g_array_index(comp_class_full_descriptors,
+ struct comp_class_full_descriptor, i);
+
+ if (cur_cc_descr_attr->comp_class_descriptor ==
+ cc_full_descr->descriptor) {
+ switch (cur_cc_descr_attr->type) {
+ case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_DESCRIPTION:
+ cc_full_descr->description =
+ cur_cc_descr_attr->value.description;
+ break;
+ default:
+ printf_verbose("WARNING: Unknown attribute \"%s\" (type %d) for component class %s (type %d) in plugin %s\n",
+ cur_cc_descr_attr->type_name,
+ cur_cc_descr_attr->type,
+ cur_cc_descr_attr->comp_class_descriptor->name,
+ cur_cc_descr_attr->comp_class_descriptor->type,
+ descriptor->name);
+ break;
+ }
+ }
+ }
+ }
+
+ /* Initialize plugin */
+ if (plugin->init) {
+ status = plugin->init(plugin);
if (status < 0) {
printf_verbose("Plugin `%s` initialization error: %d\n",
- plugin->shared_lib_handle->name, status);
+ plugin->name, status);
goto end;
}
}
plugin->shared_lib_handle->init_called = true;
+ for (i = 0; i < comp_class_full_descriptors->len; i++) {
+ struct comp_class_full_descriptor *cc_full_descr =
+ &g_array_index(comp_class_full_descriptors,
+ struct comp_class_full_descriptor, i);
+ struct bt_component_class *comp_class;
+
+ comp_class = bt_component_class_create(
+ cc_full_descr->descriptor->type,
+ cc_full_descr->descriptor->name,
+ cc_full_descr->description,
+ cc_full_descr->descriptor->init_cb);
+ if (!comp_class) {
+ status = BT_PLUGIN_STATUS_ERROR;
+ goto end;
+ }
+
+ status = bt_plugin_add_component_class(plugin,
+ comp_class);
+ BT_PUT(comp_class);
+ if (status < 0) {
+ printf_verbose("Cannot add component class %s (type %d) to plugin `%s`: status = %d\n",
+ cc_full_descr->descriptor->name,
+ cc_full_descr->descriptor->type,
+ plugin->name, status);
+ goto end;
+ }
+ }
+
/*
- * The initialization function should have added the component
- * classes at this point. We freeze the plugin so that it's not
- * possible to add component classes to this plugin object after
- * this stage (plugin object becomes immutable).
+ * All the plugin's component classes should be added at this
+ * point. We freeze the plugin so that it's not possible to add
+ * component classes to this plugin object after this stage
+ * (plugin object becomes immutable).
*/
plugin->frozen = true;
end:
+ g_array_free(comp_class_full_descriptors, TRUE);
return status;
}
-struct bt_plugin *bt_plugin_create_from_file(const char *path)
+static
+struct bt_plugin **bt_plugin_create_all_from_sections(
+ struct bt_plugin_shared_lib_handle *shared_lib_handle,
+ struct __bt_plugin_descriptor const * const *descriptors_begin,
+ struct __bt_plugin_descriptor const * const *descriptors_end,
+ struct __bt_plugin_descriptor_attribute const * const *attrs_begin,
+ struct __bt_plugin_descriptor_attribute const * const *attrs_end,
+ struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin,
+ struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end,
+ struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin,
+ struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end)
+{
+ size_t descriptor_count;
+ size_t attrs_count;
+ size_t cc_descriptors_count;
+ size_t cc_descr_attrs_count;
+ size_t i;
+ struct bt_plugin **plugins = NULL;
+
+ descriptor_count = descriptors_end - descriptors_begin;
+ attrs_count = attrs_end - attrs_begin;
+ cc_descriptors_count = cc_descriptors_end - cc_descriptors_begin;
+ cc_descr_attrs_count = cc_descr_attrs_end - cc_descr_attrs_begin;
+ printf_verbose("Section: Plugin descriptors: [%p - %p], (%zu elements)\n",
+ descriptors_begin, descriptors_end, descriptor_count);
+ printf_verbose("Section: Plugin descriptor attributes: [%p - %p], (%zu elements)\n",
+ attrs_begin, attrs_end, attrs_count);
+ printf_verbose("Section: Plugin component class descriptors: [%p - %p], (%zu elements)\n",
+ cc_descriptors_begin, cc_descriptors_end, cc_descriptors_count);
+ printf_verbose("Section: Plugin component class descriptor attributes: [%p - %p], (%zu elements)\n",
+ cc_descr_attrs_begin, cc_descr_attrs_end, attrs_count);
+ plugins = calloc(descriptor_count + 1, sizeof(*plugins));
+ if (!plugins) {
+ goto error;
+ }
+
+ for (i = 0; i < descriptor_count; i++) {
+ enum bt_plugin_status status;
+ const struct __bt_plugin_descriptor *descriptor =
+ descriptors_begin[i];
+ struct bt_plugin *plugin;
+
+ printf_verbose("Loading plugin %s (%d.%d)\n", descriptor->name,
+ descriptor->major, descriptor->minor);
+
+ if (descriptor->major > __BT_PLUGIN_VERSION_MAJOR) {
+ printf_error("Unknown plugin's major version: %d\n",
+ descriptor->major);
+ goto error;
+ }
+
+ plugin = bt_plugin_create_empty(shared_lib_handle);
+ if (!plugin) {
+ printf_error("Cannot allocate plugin object for plugin %s\n",
+ descriptor->name);
+ goto error;
+ }
+
+ status = bt_plugin_init(plugin, descriptor, attrs_begin,
+ attrs_end, cc_descriptors_begin, cc_descriptors_end,
+ cc_descr_attrs_begin, cc_descr_attrs_end);
+ if (status < 0) {
+ printf_error("Cannot initialize plugin object %s\n",
+ descriptor->name);
+ BT_PUT(plugin);
+ goto error;
+ }
+
+ /* Transfer ownership to the array */
+ plugins[i] = plugin;
+ }
+
+ goto end;
+
+error:
+ g_free(plugins);
+ plugins = NULL;
+
+end:
+ return plugins;
+}
+
+struct bt_plugin **bt_plugin_create_all_from_static(void)
+{
+ struct bt_plugin **plugins = NULL;
+ struct bt_plugin_shared_lib_handle *shared_lib_handle =
+ bt_plugin_shared_lib_handle_create(NULL);
+
+ if (!shared_lib_handle) {
+ goto end;
+ }
+
+ plugins = bt_plugin_create_all_from_sections(shared_lib_handle,
+ SECTION_BEGIN(__bt_plugin_descriptors),
+ SECTION_END(__bt_plugin_descriptors),
+ SECTION_BEGIN(__bt_plugin_descriptor_attributes),
+ SECTION_END(__bt_plugin_descriptor_attributes),
+ SECTION_BEGIN(__bt_plugin_component_class_descriptors),
+ SECTION_END(__bt_plugin_component_class_descriptors),
+ SECTION_BEGIN(__bt_plugin_component_class_descriptor_attributes),
+ SECTION_END(__bt_plugin_component_class_descriptor_attributes));
+
+end:
+ BT_PUT(shared_lib_handle);
+
+ return plugins;
+}
+
+struct bt_plugin **bt_plugin_create_all_from_file(const char *path)
{
size_t path_len;
- struct bt_plugin *plugin = NULL;
+ struct bt_plugin **plugins = NULL;
+ struct __bt_plugin_descriptor const * const *descriptors_begin = NULL;
+ struct __bt_plugin_descriptor const * const *descriptors_end = NULL;
+ struct __bt_plugin_descriptor_attribute const * const *attrs_begin = NULL;
+ struct __bt_plugin_descriptor_attribute const * const *attrs_end = NULL;
+ struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin = NULL;
+ struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end = NULL;
+ struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin = NULL;
+ struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end = NULL;
bool is_libtool_wrapper = false, is_shared_object = false;
+ struct bt_plugin_shared_lib_handle *shared_lib_handle = NULL;
if (!path) {
- goto error;
+ goto end;
}
path_len = strlen(path);
if (path_len <= PLUGIN_SUFFIX_LEN) {
- goto error;
+ goto end;
}
path_len++;
NATIVE_PLUGIN_SUFFIX_LEN);
if (!is_shared_object && !is_libtool_wrapper) {
/* Name indicates that this is not a plugin file. */
- goto error;
+ goto end;
}
- plugin = g_new0(struct bt_plugin, 1);
- if (!plugin) {
- goto error;
+ shared_lib_handle = bt_plugin_shared_lib_handle_create(path);
+ if (!shared_lib_handle) {
+ goto end;
}
- bt_object_init(plugin, bt_plugin_destroy);
+ if (!g_module_symbol(shared_lib_handle->module, "__start___bt_plugin_descriptors",
+ (gpointer *) &descriptors_begin)) {
+ printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+ "__start___bt_plugin_descriptors",
+ g_module_name(shared_lib_handle->module));
+ goto end;
+ }
- /* Create shared lib handle */
- plugin->shared_lib_handle = bt_plugin_shared_lib_handle_create(path);
- if (!plugin->shared_lib_handle) {
- printf_verbose("Failed to create a shared library handle (path `%s`)\n",
- path);
- goto error;
+ if (!g_module_symbol(shared_lib_handle->module, "__stop___bt_plugin_descriptors",
+ (gpointer *) &descriptors_end)) {
+ printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+ "__stop___bt_plugin_descriptors",
+ g_module_name(shared_lib_handle->module));
+ goto end;
}
- /* Create empty array of component classes */
- plugin->comp_classes =
- g_ptr_array_new_with_free_func((GDestroyNotify) bt_put);
- if (!plugin->comp_classes) {
- goto error;
+ if (!g_module_symbol(shared_lib_handle->module, "__start___bt_plugin_descriptor_attributes",
+ (gpointer *) &attrs_begin)) {
+ printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+ "__start___bt_plugin_descriptor_attributes",
+ g_module_name(shared_lib_handle->module));
}
- /* Initialize plugin */
- if (init_plugin(plugin) < 0) {
- goto error;
+ if (!g_module_symbol(shared_lib_handle->module, "__stop___bt_plugin_descriptor_attributes",
+ (gpointer *) &attrs_end)) {
+ printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+ "__stop___bt_plugin_descriptor_attributes",
+ g_module_name(shared_lib_handle->module));
}
- goto end;
+ if ((!!attrs_begin - !!attrs_end) != 0) {
+ printf_verbose("Found __start___bt_plugin_descriptor_attributes or __stop___bt_plugin_descriptor_attributes symbol, but not both in %s\n",
+ g_module_name(shared_lib_handle->module));
+ goto end;
+ }
-error:
- BT_PUT(plugin);
+ if (!g_module_symbol(shared_lib_handle->module, "__start___bt_plugin_component_class_descriptors",
+ (gpointer *) &cc_descriptors_begin)) {
+ printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+ "__start___bt_plugin_component_class_descriptors",
+ g_module_name(shared_lib_handle->module));
+ }
+
+ if (!g_module_symbol(shared_lib_handle->module, "__stop___bt_plugin_component_class_descriptors",
+ (gpointer *) &cc_descriptors_end)) {
+ printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+ "__stop___bt_plugin_component_class_descriptors",
+ g_module_name(shared_lib_handle->module));
+ }
+
+ if ((!!cc_descriptors_begin - !!cc_descriptors_end) != 0) {
+ printf_verbose("Found __start___bt_plugin_component_class_descriptors or __stop___bt_plugin_component_class_descriptors symbol, but not both in %s\n",
+ g_module_name(shared_lib_handle->module));
+ goto end;
+ }
+
+ if (!g_module_symbol(shared_lib_handle->module, "__start___bt_plugin_component_class_descriptor_attributes",
+ (gpointer *) &cc_descr_attrs_begin)) {
+ printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+ "__start___bt_plugin_component_class_descriptor_attributes",
+ g_module_name(shared_lib_handle->module));
+ }
+
+ if (!g_module_symbol(shared_lib_handle->module, "__stop___bt_plugin_component_class_descriptor_attributes",
+ (gpointer *) &cc_descr_attrs_end)) {
+ printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+ "__stop___bt_plugin_component_class_descriptor_attributes",
+ g_module_name(shared_lib_handle->module));
+ }
+
+ if ((!!cc_descr_attrs_begin - !!cc_descr_attrs_end) != 0) {
+ printf_verbose("Found __start___bt_plugin_component_class_descriptor_attributes or __stop___bt_plugin_component_class_descriptor_attributes symbol, but not both in %s\n",
+ g_module_name(shared_lib_handle->module));
+ goto end;
+ }
+
+ /* Initialize plugin */
+ plugins = bt_plugin_create_all_from_sections(shared_lib_handle,
+ descriptors_begin, descriptors_end, attrs_begin, attrs_end,
+ cc_descriptors_begin, cc_descriptors_end,
+ cc_descr_attrs_begin, cc_descr_attrs_end);
end:
- return plugin;
+ BT_PUT(shared_lib_handle);
+ return plugins;
}
/* Allocate dirent as recommended by READDIR(3), NOTES on readdir_r */
DIR *directory = NULL;
struct dirent *entry = NULL, *result = NULL;
char *file_path = NULL;
- size_t path_len = strlen(path);
+ size_t path_len;
enum bt_plugin_status ret = BT_PLUGIN_STATUS_OK;
+ if (!path) {
+ ret = BT_PLUGIN_STATUS_ERROR;
+ goto end;
+ }
+
+ path_len = strlen(path);
+
if (path_len >= PATH_MAX) {
ret = BT_PLUGIN_STATUS_ERROR;
goto end;
goto end;
}
} else if (S_ISREG(st.st_mode)) {
- struct bt_plugin *plugin = bt_plugin_create_from_file(file_path);
+ struct bt_plugin **plugins_from_file =
+ bt_plugin_create_all_from_file(file_path);
- if (plugin) {
- /* Transfer ownership to array */
- g_ptr_array_add(plugins, plugin);
+ if (plugins_from_file) {
+ struct bt_plugin **plugin;
+
+ for (plugin = plugins_from_file; *plugin; plugin++) {
+ /* Transfer ownership to array */
+ g_ptr_array_add(plugins, *plugin);
+ }
+
+ free(plugins_from_file);
}
}
}
struct bt_plugin **bt_plugin_create_all_from_dir(const char *path,
bool recurse)
{
- GPtrArray *plugins_array = NULL;
+ GPtrArray *plugins_array = g_ptr_array_new();
struct bt_plugin **plugins = NULL;
enum bt_plugin_status status;
- if (!path) {
- goto error;
- }
-
- plugins_array = g_ptr_array_new();
- if (!plugins_array) {
- goto error;
- }
-
/* Append found plugins to array */
status = bt_plugin_create_append_all_from_dir(plugins_array, path,
recurse);
return plugins;
}
-static
-struct bt_plugin *bt_plugin_create_from_static_at_index(size_t i)
-{
- struct bt_plugin *plugin = NULL;
-
- plugin = g_new0(struct bt_plugin, 1);
- if (!plugin) {
- goto error;
- }
-
- bt_object_init(plugin, bt_plugin_destroy);
-
- /* Create shared lib handle */
- plugin->shared_lib_handle = bt_plugin_shared_lib_handle_create(NULL);
- if (!plugin->shared_lib_handle) {
- goto error;
- }
-
- /* Fill shared lib handle */
- plugin->shared_lib_handle->init =
- (SECTION_BEGIN(__bt_plugin_init_funcs))[i];
- if (!plugin->shared_lib_handle->init) {
- goto error;
- }
-
- plugin->shared_lib_handle->exit =
- (SECTION_BEGIN(__bt_plugin_exit_funcs))[i];
- if (!plugin->shared_lib_handle->exit) {
- goto error;
- }
-
- plugin->shared_lib_handle->name = (SECTION_BEGIN(__bt_plugin_names))[i];
- plugin->shared_lib_handle->author =
- (SECTION_BEGIN(__bt_plugin_authors))[i];
- plugin->shared_lib_handle->license =
- (SECTION_BEGIN(__bt_plugin_licenses))[i];
- plugin->shared_lib_handle->description =
- (SECTION_BEGIN(__bt_plugin_descriptions))[i];
-
- /* Create empty array of component classes */
- plugin->comp_classes =
- g_ptr_array_new_with_free_func((GDestroyNotify) bt_put);
- if (!plugin->comp_classes) {
- goto error;
- }
-
- /* Initialize plugin */
- if (init_plugin(plugin) < 0) {
- goto error;
- }
-
- goto end;
-
-error:
- BT_PUT(plugin);
-
-end:
- return plugin;
-}
-
-struct bt_plugin **bt_plugin_create_all_from_static(void)
-{
- size_t count, i;
- struct bt_plugin **plugins = NULL;
-
- PRINT_PLUG_IN_SECTIONS(printf_verbose);
- count = SECTION_ELEMENT_COUNT(__bt_plugin_init_funcs);
- if (SECTION_ELEMENT_COUNT(__bt_plugin_exit_funcs) != count ||
- SECTION_ELEMENT_COUNT(__bt_plugin_names) != count ||
- SECTION_ELEMENT_COUNT(__bt_plugin_authors) != count ||
- SECTION_ELEMENT_COUNT(__bt_plugin_licenses) != count ||
- SECTION_ELEMENT_COUNT(__bt_plugin_descriptions) != count) {
- printf_error("Some statically-linked plug-ins do not define all the mandatory symbols\n");
- goto error;
- }
-
- printf_verbose("Detected %zu statically-linked plug-ins\n", count);
- plugins = g_new0(struct bt_plugin *, count + 1);
- if (!plugins) {
- goto error;
- }
-
- for (i = 0; i < count; i++) {
- struct bt_plugin *plugin =
- bt_plugin_create_from_static_at_index(i);
-
- if (!plugin) {
- printf_error("Cannot create statically-linked plug-in at index %zu\n",
- i);
- goto error;
- }
-
- /* Transfer ownership to the array */
- plugins[i] = plugin;
- }
-
- goto end;
-
-error:
- g_free(plugins);
-
-end:
- return plugins;
-}
-
const char *bt_plugin_get_name(struct bt_plugin *plugin)
{
- return plugin ? plugin->shared_lib_handle->name : NULL;
+ return plugin ? plugin->name : NULL;
}
const char *bt_plugin_get_author(struct bt_plugin *plugin)
{
- return plugin ? plugin->shared_lib_handle->author : NULL;
+ return plugin ? plugin->author : NULL;
}
const char *bt_plugin_get_license(struct bt_plugin *plugin)
{
- return plugin ? plugin->shared_lib_handle->license : NULL;
+ return plugin ? plugin->license : NULL;
}
const char *bt_plugin_get_path(struct bt_plugin *plugin)
const char *bt_plugin_get_description(struct bt_plugin *plugin)
{
- return plugin ? plugin->shared_lib_handle->description : NULL;
+ return plugin ? plugin->description : NULL;
}
int bt_plugin_get_component_class_count(struct bt_plugin *plugin)
bt_component_class_get_type(comp_class));
if (comp_class_dup) {
printf_verbose("Plugin `%s`: adding component class with existing name `%s` and type %d\n",
- plugin->shared_lib_handle->name,
+ plugin->name,
bt_component_class_get_name(comp_class),
bt_component_class_get_type(comp_class));
goto error;