src/module.h
author Tero Marttila <terom@fixme.fi>
Sun, 15 Mar 2009 01:17:22 +0200
branchmodules
changeset 55 6f7f6ae729d0
parent 54 9f74e924b01a
child 56 942370000450
permissions -rw-r--r--
'working' modules code, and convert irc_log to use said interface, but we've hit the limits on our Makefile, and the compiled module doesn't really work
#ifndef MODULE_H
#define MODULE_H

/**
 * @file
 *
 * Dynamically loadable modules for use with nexus.
 *
 * The modules are loaded using dlopen(), and hence should be standard dynamic libraries. Module initialization happens
 * using a module_init_func_t named "<name>_init", which should return some kind of context pointer, which can later be
 * used to perform other operations on the module.
 */
#include "nexus.h"
#include "error.h"

#include <sys/queue.h>

/**
 * Information required to load/identify a module.
 */
struct module_info {
    /** Human-readable name */
    const char *name;
    
    /** Filesystem path to the .so */
    const char *path;
};

/**
 * A loaded module.
 */
struct module {
    /** The identifying info for the module */
    struct module_info info;

    /** The dlopen handle */
    void *handle;

    /** The module context object */
    void *ctx;

    /** Pointer back to the modules struct used to load this */
    struct modules *modules;

    /** Our entry in the list of modules */
    TAILQ_ENTRY(module) modules_list;
};

/**
 * A set of loaded modules, and functionality to load more
 */
struct modules {
    /** The nexus in use */
    struct nexus *nexus;

    /** List of loaded modules */
    TAILQ_HEAD(module_ctx_modules, module) list;
};

/**
 * Possible error codes
 */
enum module_error_code {
    _ERR_MODULE_BEGIN = _ERR_MODULE,
    
    ERR_MODULE_OPEN,        ///< dlopen() failed
    ERR_MODULE_NAME,        ///< invalid module_info.name
    ERR_MODULE_SYM,         ///< invalid symbol
    ERR_MODULE_INIT_FUNC,   ///< invalid module_init_func_t
};

/**
 * Module initialization function type
 *
 * @param modules the module-loading context, containing the nexus
 * @param err returned error info
 * @return context pointer, or NULL on errors
 */
typedef void* (*module_init_func_t) (struct modules *modules, struct error_info *err);

/**
 * Module configuration function type
 *
 * @param ctx the module's context pointer
 * @param name the name of the configuration setting
 * @param value the value of the configuration setting
 * @return error code
 */
typedef err_t (*module_conf_func_t) (struct module *module, const char *name, char *value);

/**
 * Maximum length of a module name
 */
#define MODULE_NAME_MAX 24

/**
 * Maximum length of module symbol suffix
 */
#define MODULE_SUFFIX_MAX 16

/**
 * Maximum length of symbol name name, including terminating NUL
 */
#define MODULE_SYMBOL_MAX (MODULE_NAME_MAX + 1 + MODULE_SUFFIX_MAX + 1)

/**
 * Create a new modules state
 */
err_t modules_create (struct modules **modules_ptr, struct nexus *nexus);

/**
 * Load a new module
 */
err_t module_load (struct modules *modules, struct module **module, const struct module_info *info, struct error_info *err);

/**
 * Set a module configuration option
 */
err_t module_conf (struct module *module, const char *name, char *value);

/**
 * Unload a module
 *
 * XXX: not implemented
 */
err_t module_unload (struct module *module);

#endif