#include <ltdl.h>
#include <uobject/package.h>
+#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);
/*
* 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;
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;
}
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;
}
{
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");
}
}
- if (priv->pkg_file) {
- fclose(priv->pkg_file);
+ if (upkg->pkg) {
+ upkg_close(upkg->pkg);
+ upkg->pkg = NULL;
}
}
}
+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));
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)
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);
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;
+}