From d42028c588b512b26c3c4fea718cffcab602b74c Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Wed, 16 Sep 2009 10:05:38 -0400 Subject: [PATCH] package: Allow opening by filename in addition to package name. Ultimately, libupkg will be merged into libuobject. This is step one of that merger, and doesn't affect very much. --- src/module.c | 2 +- src/package.c | 84 ++++++++++++++++++++++++++++++------------- src/uobject/package.h | 4 ++- src/upkg.c | 13 +++---- 4 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/module.c b/src/module.c index d7db268..1872a8d 100644 --- a/src/module.c +++ b/src/module.c @@ -84,7 +84,7 @@ GType u_object_module_get_class(const char *package, const char *class) if (!mod) { void **p; - mod = u_pkg_new(package); + mod = u_pkg_new_by_name(package); if (!mod) { return 0; } 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; +} diff --git a/src/uobject/package.h b/src/uobject/package.h index 697abd2..5e60a18 100644 --- a/src/uobject/package.h +++ b/src/uobject/package.h @@ -38,6 +38,7 @@ typedef struct UPkgClass UPkgClass; struct UPkg { GTypeModule parent; + struct upkg *pkg; }; struct UPkgClass { @@ -45,7 +46,8 @@ struct UPkgClass { }; GType u_pkg_get_type(void); -GTypeModule *u_pkg_new(const char *name); +GTypeModule *u_pkg_new_by_name(const char *name); +GTypeModule *u_pkg_new_by_file(const char *filename); const char *u_pkg_get_search_path(void); int u_pkg_set_search_path(const char *path); diff --git a/src/upkg.c b/src/upkg.c index 94ace92..b3e27a3 100644 --- a/src/upkg.c +++ b/src/upkg.c @@ -28,6 +28,7 @@ #include #include #include +#include enum { MODE_INFO, @@ -285,7 +286,7 @@ int package_export(struct upkg *pkg) int main(int argc, char **argv) { - struct upkg *pkg; + UPkg *upkg; unsigned mode = MODE_INFO; int opt, rc = EXIT_FAILURE; @@ -322,22 +323,22 @@ int main(int argc, char **argv) if (u_object_module_init() != 0) return EXIT_FAILURE; - pkg = upkg_fopen(argv[optind]); - if (!pkg) { + upkg = U_PKG(u_pkg_new_by_file(argv[optind])); + if (!upkg) { fprintf(stderr, "failed to open package!\n"); return EXIT_FAILURE; } switch (mode) { case MODE_INFO: - rc = package_info(pkg); + rc = package_info(upkg->pkg); break; case MODE_EXPORT: - rc = package_export(pkg); + rc = package_export(upkg->pkg); break; } - upkg_close(pkg); + g_object_unref(upkg); u_object_module_exit(); return rc; } -- 2.43.2