bool init_backend(BuxtonLayer *layer, BuxtonBackend* backend) { void *handle, *cast; char *path; const char *name; char *error; int r; module_init_func i_func; module_destroy_func d_func; assert(layer); assert(backend); if (layer->backend == BACKEND_GDBM) name = "gdbm"; else if (layer->backend == BACKEND_MEMORY) name = "memory"; else return false; r = asprintf(&path, "%s/%s.so", MODULE_DIRECTORY, name); if (r == -1) return false; /* Load the module */ handle = dlopen(path, RTLD_LAZY); free(path); if (!handle) { buxton_log("dlopen(): %s\n", dlerror()); return false; } dlerror(); cast = dlsym(handle, "buxton_module_init"); if ((error = dlerror()) != NULL || !cast) { buxton_log("dlsym(): %s", error); dlclose(handle); return false; } memcpy(&i_func, &cast, sizeof(i_func)); dlerror(); cast = dlsym(handle, "buxton_module_destroy"); if ((error = dlerror()) != NULL || !cast) { buxton_log("dlsym(): %s", error); dlclose(handle); return false; } memcpy(&d_func, &cast, sizeof(d_func)); i_func(backend); if (backend == NULL) { buxton_log("buxton_module_init returned NULL"); dlclose(handle); return false; } backend->module = handle; backend->destroy = d_func; return true; }
static void init_backend(BuxtonConfig *config, BuxtonLayer *layer, BuxtonBackend **backend) { void *handle, *cast; _cleanup_free_ char *path = NULL; const char *name; char *error; int r; bool rb; module_init_func i_func; module_destroy_func d_func; BuxtonBackend *backend_tmp; assert(layer); assert(backend); if (layer->backend == BACKEND_GDBM) { name = "gdbm"; } else if (layer->backend == BACKEND_MEMORY) { name = "memory"; } else { buxton_log("Invalid backend type for layer: %s\n", layer->name); abort(); } backend_tmp = hashmap_get(config->backends, name); if (backend_tmp) { *backend = backend_tmp; return; } backend_tmp = malloc0(sizeof(BuxtonBackend)); if (!backend_tmp) { abort(); } r = asprintf(&path, "%s/%s.so", buxton_module_dir(), name); if (r == -1) { abort(); } /* Load the module */ handle = dlopen(path, RTLD_LAZY); if (!handle) { buxton_log("dlopen(): %s\n", dlerror()); abort(); } dlerror(); cast = dlsym(handle, "buxton_module_init"); if ((error = dlerror()) != NULL || !cast) { buxton_log("dlsym(): %s\n", error); abort(); } memcpy(&i_func, &cast, sizeof(i_func)); dlerror(); cast = dlsym(handle, "buxton_module_destroy"); if ((error = dlerror()) != NULL || !cast) { buxton_log("dlsym(): %s\n", error); abort(); } memcpy(&d_func, &cast, sizeof(d_func)); rb = i_func(backend_tmp); if (!rb) { buxton_log("buxton_module_init failed\n"); abort(); } if (!config->backends) { config->backends = hashmap_new(trivial_hash_func, trivial_compare_func); if (!config->backends) { abort(); } } r = hashmap_put(config->backends, name, backend_tmp); if (r != 1) { abort(); } backend_tmp->module = handle; backend_tmp->destroy = d_func; *backend = backend_tmp; }