X-Git-Url: https://git.draconx.ca/gitweb/upkg.git/blobdiff_plain/9d3cb178db367962f68521985ef9e239e1d03fa9..90b53df329f9a114770dccab6b7e41f9094dfac9:/src/module.c diff --git a/src/module.c b/src/module.c index 5edc5e2..f97bc65 100644 --- a/src/module.c +++ b/src/module.c @@ -1,9 +1,14 @@ #include +#include +#include +#include #include #include #include "module.h" +G_DEFINE_TYPE(UPkgModule, upkg_module, G_TYPE_TYPE_MODULE); + static unsigned initialized; static void dl_print_errors(const char *prefix) @@ -11,8 +16,80 @@ static void dl_print_errors(const char *prefix) const char *err; while (err = lt_dlerror()) { if (prefix) fprintf(stderr, "%s: ", prefix); - puts(lt_dlerror()); + puts(err); + } +} + +static gboolean module_load(GTypeModule *m) +{ + UPkgModule *mod = UPKG_MODULE(m); + int (*init_func)(GTypeModule *); + + mod->dl = lt_dlopenext(G_TYPE_MODULE(m)->name); + if (!mod->dl) { + dl_print_errors(__func__); + return FALSE; + } + + init_func = lt_dlsym(mod->dl, "init"); + if (!init_func || init_func(m) != 0) { + dl_print_errors(__func__); + lt_dlclose(mod->dl); + return FALSE; + } + + return TRUE; +} + +static void module_unload(GTypeModule *m) +{ + UPkgModule *mod = UPKG_MODULE(m); + + if (lt_dlclose(mod->dl) != 0) { + dl_print_errors(__func__); + } +} + +static void upkg_module_init(UPkgModule *mod) +{ +} + +static void upkg_module_class_init(UPkgModuleClass *class) +{ + GTypeModuleClass *modclass = G_TYPE_MODULE_CLASS(class); + + modclass->load = module_load; + modclass->unload = module_unload; +} + +UPkgModule *upkg_module_new(const char *name) +{ + char *name2; + size_t len; + + if (!name) { + return NULL; } + + len = strlen(name); + name2 = malloc(len+1); + if (!name2) { + return NULL; + } + + UPkgModule *mod = g_object_new(UPKG_MODULE_TYPE, NULL); + if (!mod) { + free(name2); + return NULL; + } + + G_TYPE_MODULE(mod)->name = name2; + for (size_t i = 0; i < len; i++) { + name2[i] = tolower(name[i]); + } + name2[len] = 0; + + return mod; } int module_init(void)