#include #include #include #include "hook.h" #include "utils.h" int xce_hook_init(hooksys_t* s, int maxtypes) { int i; if ((s == NULL) || (maxtypes <= 0)) { return -EINVAL; } s->maxtypes = 0; s->hooks = (xlist_t*)calloc(maxtypes, sizeof(xlist_t)); if (s->hooks == NULL) { return -ENOMEM; } s->maxtypes = maxtypes; for (i = 0; i < s->maxtypes; i++) { xlist_init(&(s->hooks[i]), 8); } return 0; } int xce_add_hook(hooksys_t* s, int typ, hook_fn_t fn, void* data) { hook_item_t* it; if (s == NULL) { return -EINVAL; } if (fn == NULL) { return -EINVAL; } if ((typ < 0) || (typ >= s->maxtypes)) { return -EINVAL; } it = (hook_item_t*)calloc(1, sizeof(*it)); if (it == NULL) { return -ENOMEM; } it->fn = fn; it->data = data; xlist_store(&(s->hooks[typ]), it); return 0; } /* HOOK_BEFORE_EVENT returns * negative value will cause * fail */ int xce_run_hooks(hooksys_t* s, int type, int situation, int detail, ...) { xlist_t* l; int i; int rc = 0; if (s == NULL) { return -EINVAL; } if ((type < 0) || (type >= s->maxtypes)) { return -EINVAL; } l = &(s->hooks[type]); for (i = 0; i < l->count; i++) { hook_item_t* it = l->data[i]; va_list ap; if (it == NULL) { continue; } va_start(ap, detail); rc = (*(it->fn))(type, situation, detail, it->data, ap); va_end(ap); if ((situation == HOOK_BEFORE_EVENT) && (rc < 0)) { break; } } return rc; } static int free_hook_item(void* data1, void* data2) { if (data1 == NULL) { return -EINVAL; } free(data1); return 0; } void xce_hook_fini(hooksys_t* s) { int i; if (s == NULL) { return; } if (s->hooks == NULL) { return; } for (i = 0; i < s->maxtypes; i++) { xlist_iter(&(s->hooks[i]), (xlist_iter_fn_t)free_hook_item, NULL); xlist_fini(&(s->hooks[i])); } FREEUP(s->hooks); }