diff options
Diffstat (limited to 'src/lib/plugin.c')
-rw-r--r-- | src/lib/plugin.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/lib/plugin.c b/src/lib/plugin.c new file mode 100644 index 0000000..09df8de --- /dev/null +++ b/src/lib/plugin.c @@ -0,0 +1,74 @@ +/* + * (c) Copyright 2016 Olliver Schinagl + * Author: Olliver Schinagl <oliver@schinagl.nl> + * + * SPDX-License-Identifier: AGPL-3.0+ + */ + +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> + +#include <engagement/plugin.h> + +struct plugin *plugin_load(const char *path) +{ + struct plugin *plugin; + void *handle; + + handle = dlopen(path, RTLD_LAZY); /* TODO check if RTLD_LAZY is what we want */ + if (!handle) { + // TODO EINA_LOG + fprintf(stderr, "dlopen failed: %s\n", dlerror()); + return NULL; + } + + /* TODO use macro's to allow for static inclusion */ + /* TODO use dlvsym() if available */ + plugin = (struct plugin *)dlsym(handle, PLUGIN_SYMBOL); + if(!plugin) { + // TODO EINA_LOG + fprintf(stderr, "dlsym failed%s\n", dlerror()); + return NULL; + } + + if (plugin->magic != PLUGIN_MAGIC) { + // TODO EINA_LOG + fprintf(stderr, "Failed to init plugin, magic mismatch, plugin corrupt?\n"); + return NULL; + } + plugin->_handle = handle; + + if (plugin->load) + plugin->load(); + + return plugin; +} + +int plugin_unload(struct plugin *plugin) +{ + int error; + + if (!plugin) { + // TODO EINA_LOG + fprintf(stderr, "Cannot unload plugin %p.\n", plugin); + return -EFAULT; + } + + if (plugin->unload) + plugin->unload(); + + if (!plugin->_handle) { + // TODO EINA_LOG + fprintf(stderr, "Error, no handle for plugin %s\n", + plugin->info.name); + return -EFAULT; + } + error = dlclose(plugin->_handle); + if (error) + // TODO EINA_LOG + fprintf(stderr, "Failed to close %s\n", dlerror()); + + return error; +} |