Mor work on dynamic loading of modules
FossilOrigin-Name: b02170339426d0c9efc42d700e891a90f7ddb0961a67b679909a1c929e1501e1
This commit is contained in:
@ -3,7 +3,8 @@ include ../CWConfig.mak
|
||||
-include ../Config.local.mak
|
||||
|
||||
|
||||
LIBARCHDIR := ../../lib/$(ARCH)
|
||||
LIBDIR := ../../lib
|
||||
LIBARCHDIR := $(LIBDIR)/$(ARCH)
|
||||
OBJDIR := ../../obj/cw/$(ARCH)
|
||||
|
||||
SNAME := $(LIBARCHDIR)/libcw.a
|
||||
|
42
src/cw/mod.c
42
src/cw/mod.c
@ -144,9 +144,9 @@ struct cw_actiondef *mod_cache_add(struct conn *conn, struct cw_Mod *c, struct c
|
||||
/* static mavl to store modules */
|
||||
static struct mavl * modlist = NULL;
|
||||
static int mod_cmp(const void *e1, const void *e2){
|
||||
struct cw_Mod * (*m1fn)() = e1;
|
||||
struct cw_Mod * (*m2fn)() = e2;
|
||||
return strcmp(m1fn()->name,m2fn()->name);
|
||||
struct cw_Mod * m1 = e1;
|
||||
struct cw_Mod * m2 = e2;
|
||||
return strcmp(m1->name,m2->name);
|
||||
}
|
||||
|
||||
|
||||
@ -182,32 +182,50 @@ int cw_mod_add(struct cw_Mod * (*modfn)() ){
|
||||
}
|
||||
|
||||
|
||||
int cw_mod_add_dynamic(const char * path, const char * mod_name){
|
||||
|
||||
char * filename = malloc(strlen(path)+strlen(mod_name)+8);
|
||||
struct cw_Mod * cw_mod_add_dynamic(const char * path, const char * mod_name){
|
||||
|
||||
/* Search for the module in modlist, to see if it is
|
||||
* already loaded or was statically linked */
|
||||
struct cw_Mod search;
|
||||
memset(&search,0,sizeof(search));
|
||||
search.name=mod_name;
|
||||
struct cw_Mod * mod;
|
||||
mod = mavl_find(modlist,&search);
|
||||
if (mod){
|
||||
return mod;
|
||||
}
|
||||
|
||||
|
||||
int n = strlen(path)+strlen(mod_name)+8;
|
||||
|
||||
char * filename = malloc(n);
|
||||
|
||||
if (!filename)
|
||||
return 0;
|
||||
strcpy(filename,path);
|
||||
strcat(filename,"/");
|
||||
strcat(filename,mod_name);
|
||||
strcat(filename,".so");
|
||||
|
||||
int rc=0;
|
||||
|
||||
|
||||
/* Open the DLL */
|
||||
void * handle;
|
||||
handle = dlopen(filename,RTLD_NOW);
|
||||
|
||||
if (!handle){
|
||||
cw_log(LOG_ERROR,"Failed to load module: %s",dlerror());
|
||||
goto errX;
|
||||
}
|
||||
|
||||
void * ifu = dlsym(handle,"mod_get_interface");
|
||||
if (!ifu){
|
||||
struct cw_Mod * (*mod_get_interface)();
|
||||
mod_get_interface = dlsym(handle,"mod_get_interface");
|
||||
if (!mod_get_interface){
|
||||
cw_log(LOG_ERROR,"Failed to load module: %s",dlerror());
|
||||
goto errX;
|
||||
}
|
||||
|
||||
mod = mod_get_interface();
|
||||
mod->init();
|
||||
errX:
|
||||
free(filename);
|
||||
return rc;
|
||||
return mod;
|
||||
}
|
@ -64,6 +64,11 @@ struct cw_Mod {
|
||||
int (*register_actions) (struct cw_actiondef * def,int mode);
|
||||
|
||||
struct cw_MsgSet * (*register_messages)(struct cw_MsgSet set, int mode);
|
||||
|
||||
/**
|
||||
* Handle returned by dlopen, if this module was loaded dynamically
|
||||
* with dlopen */
|
||||
void * handle;
|
||||
};
|
||||
|
||||
|
||||
@ -84,6 +89,6 @@ extern int mod_caching;
|
||||
#define mod_set_caching(var) (mod_caching=var)
|
||||
#define mod_get_caching() (mod_caching)
|
||||
|
||||
extern int cw_mod_add_dynamic(const char * path, const char * file);
|
||||
struct cw_Mod * cw_mod_add_dynamic(const char * path, const char * file);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user