diff options
-rw-r--r-- | src/module.c | 70 | ||||
-rw-r--r-- | src/module.h | 7 | ||||
-rw-r--r-- | src/protocol-simple-tcp.moddep | 2 | ||||
-rw-r--r-- | src/protocol-simple.moddep | 1 | ||||
-rw-r--r-- | src/sink-pipe.moddep | 1 | ||||
-rw-r--r-- | src/socket-server.moddep | 1 |
6 files changed, 80 insertions, 2 deletions
diff --git a/src/module.c b/src/module.c index 94a43124..4aa9fd68 100644 --- a/src/module.c +++ b/src/module.c @@ -1,9 +1,68 @@ +#include <limits.h> +#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <string.h> #include "module.h" + +static void free_deps(struct dependency_module** deps) { + assert(deps); + + while (*deps) { + struct dependency_module *next = (*deps)->next; + lt_dlclose((*deps)->dl); + free(deps); + *deps = next; + } +} + +static int load_deps(const char *fname, struct dependency_module **deps) { + char line[PATH_MAX]; + FILE *f; + char depfile[PATH_MAX]; + assert(fname && deps); + + snprintf(depfile, sizeof(depfile), "%s.moddep", fname); + + if (!(f = fopen(depfile, "r"))) + return -1; + + while (fgets(line, sizeof(line)-1, f)) { + lt_dlhandle dl; + char *p; + size_t l; + struct dependency_module* d; + + p = line + strspn(line, " \t"); + + l = strlen(p); + if (p[l-1] == '\n') + p[l-1] = 0; + + if (*p == '#' || *p == 0) + continue; + + load_deps(p, deps); + + if (!(dl = lt_dlopenext(p))) { + free_deps(deps); + fclose(f); + return -1; + } + + d = malloc(sizeof(struct dependency_module)); + assert(d); + d->dl = dl; + d->next = *deps; + *deps = d; + } + + fclose(f); + return 0; +} + struct module* module_load(struct core *c, const char *name, const char *argument) { struct module *m = NULL; int r; @@ -13,6 +72,12 @@ struct module* module_load(struct core *c, const char *name, const char *argumen m = malloc(sizeof(struct module)); assert(m); + m->dl = NULL; + + m->dependencies = NULL; + if (load_deps(name, &m->dependencies) < 0) + goto fail; + if (!(m->dl = lt_dlopenext(name))) goto fail; @@ -33,7 +98,6 @@ struct module* module_load(struct core *c, const char *name, const char *argumen if (!c->modules) c->modules = idxset_new(NULL, NULL); - assert(c->modules); r = idxset_put(c->modules, m, &m->index); @@ -45,6 +109,7 @@ fail: if (m->dl) lt_dlclose(m->dl); + free_deps(&m->dependencies); free(m); } @@ -56,11 +121,13 @@ static void module_free(struct module *m) { m->done(m->core, m); lt_dlclose(m->dl); + free_deps(&m->dependencies); free(m->name); free(m->argument); free(m); } + void module_unload(struct core *c, struct module *m) { assert(c && m); @@ -82,7 +149,6 @@ void module_unload_by_index(struct core *c, uint32_t index) { module_free(m); } - void free_callback(void *p, void *userdata) { struct module *m = p; assert(m); diff --git a/src/module.h b/src/module.h index 4ecef86e..d16c25cd 100644 --- a/src/module.h +++ b/src/module.h @@ -6,12 +6,19 @@ #include "core.h" +struct dependency_module { + lt_dlhandle dl; + struct dependency_module *next; +}; + struct module { struct core *core; char *name, *argument; uint32_t index; lt_dlhandle dl; + struct dependency_module *dependencies; + int (*init)(struct core *c, struct module*m); void (*done)(struct core *c, struct module*m); diff --git a/src/protocol-simple-tcp.moddep b/src/protocol-simple-tcp.moddep new file mode 100644 index 00000000..88f964a0 --- /dev/null +++ b/src/protocol-simple-tcp.moddep @@ -0,0 +1,2 @@ +socket-server +protocol-simple diff --git a/src/protocol-simple.moddep b/src/protocol-simple.moddep new file mode 100644 index 00000000..c49501d8 --- /dev/null +++ b/src/protocol-simple.moddep @@ -0,0 +1 @@ +socket-server diff --git a/src/sink-pipe.moddep b/src/sink-pipe.moddep new file mode 100644 index 00000000..6958f9fc --- /dev/null +++ b/src/sink-pipe.moddep @@ -0,0 +1 @@ +iochannel diff --git a/src/socket-server.moddep b/src/socket-server.moddep new file mode 100644 index 00000000..6958f9fc --- /dev/null +++ b/src/socket-server.moddep @@ -0,0 +1 @@ +iochannel |