diff options
Diffstat (limited to 'harness/src/plugin.c')
-rw-r--r-- | harness/src/plugin.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/harness/src/plugin.c b/harness/src/plugin.c new file mode 100644 index 0000000..9b71c49 --- /dev/null +++ b/harness/src/plugin.c @@ -0,0 +1,86 @@ +#include "plugin.h" + +#include <ctype.h> +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +static void shx(uint8_t *state, uint32_t sz) { + uint32_t i = 0; + while (i < sz) { + for (int j = 0; j < 16; ++j) { + if (i < sz) { + printf("%02x ", (unsigned int)state[i]); + } else { + printf(" "); + } + ++i; + } + + i -= 16; + + printf(" "); + + for (int j = 0; j < 16; ++j) { + if (i < sz) { + if (isprint(state[i]) && !isspace(state[i])) { + printf("%c", state[i]); + } else { + printf("."); + } + } else { + printf(" "); + } + ++i; + } + printf("\n"); + } +} + +int read_plugin_from_file(const char *filename, plugin_t *plugin) { + dlhandle_t lib = dlopen(filename, RTLD_LAZY); + + if (!lib) { + fprintf(stderr, "Failed to open library: %s: %s\n", filename, dlerror()); + return 1; + } + + return load_plugin_from_dl(lib, plugin); +} + +int plugin_hot_reload(int argc, char **argv, dlhandle_t library, + plugin_t *plugin) { + int ec = 0; + uint32_t sz = 0; + uint8_t *marshalled_state = NULL; + + printf("Hot Reloading %s\n", plugin->plugin_name); + pthread_mutex_lock(&plugin->lock); + + printf("Marshalling state ...\n"); + marshalled_state = plugin->plugin_marshal_state(plugin->state, &sz); + + printf("Calling teardown ...\n"); + plugin->plugin_teardown(plugin->state); + + printf("State Marshalled:\n"); + shx(marshalled_state, sz); + + if (library != plugin->library_handle) { + dlclose(plugin->library_handle); + } + + if ((ec = load_plugin_from_dl(library, plugin))) { + goto fail; + } + + printf("Loading plugin ...\n"); + plugin->plugin_load(argc, argv); + printf("Hot starting plugin ...\n"); + plugin->state = plugin->plugin_hot_start(marshalled_state, sz); + +fail: + free(marshalled_state); + pthread_mutex_unlock(&plugin->lock); + return ec; +} |