X-Git-Url: https://git.draconx.ca/gitweb/upkg.git/blobdiff_plain/dc739f280f430ad323594ab38adf1e85b5ac0efd..d42028c588b512b26c3c4fea718cffcab602b74c:/src/package.c diff --git a/src/package.c b/src/package.c index cbbaf09..bd97135 100644 --- a/src/package.c +++ b/src/package.c @@ -25,13 +25,13 @@ #include #include +#include "upkg.h" #define U_PKG_GET_PRIV(o) \ G_TYPE_INSTANCE_GET_PRIVATE(o, U_PKG_TYPE, struct upkg_priv) struct upkg_priv { lt_dlhandle native; - FILE *pkg_file; }; G_DEFINE_TYPE(UPkg, u_pkg, G_TYPE_TYPE_MODULE); @@ -85,13 +85,13 @@ static void dl_print_errors(const char *prefix) /* * Function for use with lt_dlforeachfile. The user data must point to * a UPkg with the GTypeModule name field initialized. If a suitable file - * is found and could be successfully opened for reading, the pkg_file member - * of struct upkg_priv will be filled in. + * is found and could be successfully opened for reading, the pkg class member + * will be filled in. */ -static int find_package_by_name(const char *filename, void *_pkg) +static int find_package_by_name(const char *filename, void *data) { - struct upkg_priv *priv = U_PKG_GET_PRIV(_pkg); - GTypeModule *m = _pkg; + GTypeModule *m = G_TYPE_MODULE(data); + UPkg *upkg = U_PKG(data); const char *base; size_t len; @@ -115,8 +115,8 @@ static int find_package_by_name(const char *filename, void *_pkg) for (unsigned i = 0; i < sizeof u_pkg_exts / sizeof *u_pkg_exts; i++) { strcpy(buf+len, u_pkg_exts[i]); - priv->pkg_file = fopen(buf, "rb"); - if (priv->pkg_file) { + upkg->pkg = upkg_fopen(buf); + if (!upkg->pkg) { free(buf); return 1; } @@ -131,20 +131,24 @@ static gboolean u_pkg_load(GTypeModule *m) struct upkg_priv *priv = U_PKG_GET_PRIV(m); int (*init_func)(GTypeModule *); - priv->native = lt_dlopenext(m->name); - if (!priv->native) { - dl_print_errors(m->name); - return FALSE; - } + if (m->name) { + priv->native = lt_dlopenext(m->name); + if (!priv->native) { + dl_print_errors(m->name); + return FALSE; + } - init_func = lt_dlsym(priv->native, "init"); - if (!init_func || init_func(m) != 0) { - dl_print_errors(__func__); - lt_dlclose(priv->native); - return FALSE; + init_func = lt_dlsym(priv->native, "init"); + if (!init_func || init_func(m) != 0) { + dl_print_errors(__func__); + lt_dlclose(priv->native); + return FALSE; + } } - lt_dlforeachfile(u_pkg_get_search_path(), find_package_by_name, m); + if (!U_PKG(m)->pkg) { + lt_dlforeachfile(u_pkg_get_search_path(), find_package_by_name, m); + } return TRUE; } @@ -153,6 +157,7 @@ static void u_pkg_unload(GTypeModule *m) { struct upkg_priv *priv = U_PKG_GET_PRIV(m); void (*exit_func)(GTypeModule *); + UPkg *upkg = U_PKG(m); if (priv->native) { exit_func = lt_dlsym(priv->native, "exit"); @@ -165,8 +170,9 @@ static void u_pkg_unload(GTypeModule *m) } } - if (priv->pkg_file) { - fclose(priv->pkg_file); + if (upkg->pkg) { + upkg_close(upkg->pkg); + upkg->pkg = NULL; } } @@ -175,9 +181,20 @@ static void u_pkg_init(UPkg *pkg) } +static void u_pkg_finalize(GObject *o) +{ + UPkg *upkg = U_PKG(o); + + if (upkg->pkg) { + upkg_close(upkg->pkg); + } +} + static void u_pkg_class_init(UPkgClass *class) { GTypeModuleClass *modclass = G_TYPE_MODULE_CLASS(class); + GObjectClass *objclass = G_OBJECT_CLASS(class); + const char *modpath = getenv("UOBJECT_MODULE_PATH"); g_type_class_add_private(class, sizeof (struct upkg_priv)); @@ -193,8 +210,9 @@ static void u_pkg_class_init(UPkgClass *class) dl_print_errors(__func__); } - modclass->load = u_pkg_load; - modclass->unload = u_pkg_unload; + modclass->load = u_pkg_load; + modclass->unload = u_pkg_unload; + objclass->finalize = u_pkg_finalize; } static int expand_search_path(size_t need) @@ -246,7 +264,7 @@ int u_pkg_add_search_dir(const char *path) return 0; } -GTypeModule *u_pkg_new(const char *name) +GTypeModule *u_pkg_new_by_name(const char *name) { g_return_val_if_fail(name != NULL, NULL); @@ -264,3 +282,21 @@ GTypeModule *u_pkg_new(const char *name) mod->name = str_cpy_lower(pkgname, name); return mod; } + +GTypeModule *u_pkg_new_by_file(const char *filename) +{ + struct upkg *pkg = upkg_fopen(filename); + if (!pkg) { + return NULL; + } + + GTypeModule *mod = g_object_new(U_PKG_TYPE, NULL); + if (!mod) { + upkg_close(pkg); + return NULL; + } + + mod->name = NULL; + U_PKG(mod)->pkg = pkg; + return mod; +}