diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/plugins/plugin_loader.c | 62 | ||||
-rw-r--r-- | src/libstrongswan/plugins/plugin_loader.h | 10 |
2 files changed, 69 insertions, 3 deletions
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index e4698fac0..e78762b2c 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -40,6 +40,13 @@ typedef struct registered_feature_t registered_feature_t; typedef struct provided_feature_t provided_feature_t; typedef struct plugin_entry_t plugin_entry_t; +#ifdef STATIC_PLUGIN_CONSTRUCTORS +/** + * Statically registered constructors + */ +static hashtable_t *plugin_constructors = NULL; +#endif + /** * private data of plugin_loader */ @@ -298,6 +305,46 @@ static plugin_t *static_features_create(const char *name, return &this->public; } +#ifdef STATIC_PLUGIN_CONSTRUCTORS +/* + * Described in header. + */ +void plugin_constructor_register(char *name, void *constructor) +{ + bool old = FALSE; + + if (lib && lib->leak_detective) + { + old = lib->leak_detective->set_state(lib->leak_detective, FALSE); + } + + if (!plugin_constructors) + { + chunk_hash_seed(); + plugin_constructors = hashtable_create(hashtable_hash_str, + hashtable_equals_str, 32); + } + if (constructor) + { + plugin_constructors->put(plugin_constructors, name, constructor); + } + else + { + plugin_constructors->remove(plugin_constructors, name); + if (!plugin_constructors->get_count(plugin_constructors)) + { + plugin_constructors->destroy(plugin_constructors); + plugin_constructors = NULL; + } + } + + if (lib && lib->leak_detective) + { + lib->leak_detective->set_state(lib->leak_detective, old); + } +} +#endif + /** * create a plugin * returns: NOT_FOUND, if the constructor was not found @@ -309,7 +356,7 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, { char create[128]; plugin_t *plugin; - plugin_constructor_t constructor; + plugin_constructor_t constructor = NULL; if (snprintf(create, sizeof(create), "%s_plugin_create", name) >= sizeof(create)) @@ -317,8 +364,17 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, return FAILED; } translate(create, "-", "_"); - constructor = dlsym(handle, create); - if (constructor == NULL) +#ifdef STATIC_PLUGIN_CONSTRUCTORS + if (plugin_constructors) + { + constructor = plugin_constructors->get(plugin_constructors, name); + } + if (!constructor) +#endif + { + constructor = dlsym(handle, create); + } + if (!constructor) { return NOT_FOUND; } diff --git a/src/libstrongswan/plugins/plugin_loader.h b/src/libstrongswan/plugins/plugin_loader.h index 6be6a909c..92a860615 100644 --- a/src/libstrongswan/plugins/plugin_loader.h +++ b/src/libstrongswan/plugins/plugin_loader.h @@ -168,4 +168,14 @@ plugin_loader_t *plugin_loader_create(); */ void plugin_loader_add_plugindirs(char *basedir, char *plugins); +#ifdef STATIC_PLUGIN_CONSTRUCTORS +/** + * Register a plugin constructor in case of static builds. + * + * @param name name of the plugin + * @param constructor constructor to register (set to NULL to unregister) + */ +void plugin_constructor_register(char *name, void *constructor); +#endif + #endif /** PLUGIN_LOADER_H_ @}*/ |