/** * Add and initialise an external module with exports * * @param mp Pointer to allocated module object * @param me Module exports * * @return 0 if success, otherwise errorcode */ int mod_add(struct mod **mp, const struct mod_export *me) { struct mod *m; int err = 0; if (!mp || !me) return EINVAL; /* check if already loaded */ m = mod_find(me->name); if (m) { DEBUG_NOTICE("module already loaded: %s\n", me->name); return EALREADY; } m = mem_zalloc(sizeof(*m), mod_destructor); if (!m) return ENOMEM; list_append(&modl, &m->le, m); m->me = me; if (err) mem_deref(m); else *mp = m; return err; }
/** * Load and initialise a loadable module by name * * @param mp Pointer to allocated module object * @param name Name of loadable module * * @return 0 if success, otherwise errorcode */ int mod_load(struct mod **mp, const char *name) { struct mod *m; int err = 0; int rc; if (!mp || !name) return EINVAL; /* check if already loaded */ m = mod_find(name); if (m) { DEBUG_NOTICE("module already loaded: %s\n", name); return EALREADY; } m = mem_zalloc(sizeof(*m), mod_destructor); if (!m) return ENOMEM; list_append(&modl, &m->le, m); m->h = _mod_open(name); if (!m->h) { err = ENOENT; goto out; } m->me = _mod_sym(m->h, "exports"); if (!m->me) { err = ELIBBAD; goto out; } // if (m->me->init && ((err = m->me->init()) != 0)) // goto out; out: if (err) mem_deref(m); else *mp = m; return err; }
static int load_module(struct mod **modp, const struct pl *modpath, const struct pl *name) { char file[FS_PATH_MAX]; char namestr[256]; struct mod *m = NULL; int err = 0; if (!name) return EINVAL; #ifdef STATIC /* Try static first */ pl_strcpy(name, namestr, sizeof(namestr)); if (mod_find(namestr)) { info("static module already loaded: %r\n", name); return EALREADY; } err = mod_add(&m, lookup_static_module(name)); if (!err) goto out; #else (void)namestr; #endif /* Then dynamic */ if (re_snprintf(file, sizeof(file), "%r/%r", modpath, name) < 0) { err = ENOMEM; goto out; } err = mod_load(&m, file); if (err) goto out; out: if (err) { warning("module %r: %m\n", name, err); } else if (modp) *modp = m; return err; }
/** * Unload a module by name or by filename * * @param name module name incl/excl extension, excluding module path * * example: "foo" * example: "foo.so" */ void module_unload(const char *name) { char filename[256]; struct mod *mod; if (!str_isset(name)) return; append_extension(filename, sizeof(filename), name); mod = mod_find(filename); if (mod) { info("unloading module: %s\n", filename); mem_deref(mod); return; } info("ERROR: Module %s is not currently loaded\n", name); }