Line data Source code
1 : /*
2 : * Copyright (c) 2016 David Lamparter, for NetDEF, Inc.
3 : *
4 : * Permission to use, copy, modify, and distribute this software for any
5 : * purpose with or without fee is hereby granted, provided that the above
6 : * copyright notice and this permission notice appear in all copies.
7 : *
8 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 : */
16 :
17 : #ifdef HAVE_CONFIG_H
18 : #include "config.h"
19 : #endif
20 :
21 : #include <string.h>
22 :
23 : #include "memory.h"
24 : #include "hook.h"
25 :
26 22 : DEFINE_MTYPE_STATIC(LIB, HOOK_ENTRY, "Hook entry");
27 :
28 128 : void _hook_register(struct hook *hook, struct hookent *stackent, void *funcptr,
29 : void *arg, bool has_arg, struct frrmod_runtime *module,
30 : const char *funcname, int priority)
31 : {
32 128 : struct hookent *he, **pos;
33 :
34 128 : if (!stackent->ent_used)
35 : he = stackent;
36 : else {
37 0 : he = XCALLOC(MTYPE_HOOK_ENTRY, sizeof(*he));
38 0 : he->ent_on_heap = true;
39 : }
40 128 : he->ent_used = true;
41 128 : he->hookfn = funcptr;
42 128 : he->hookarg = arg;
43 128 : he->has_arg = has_arg;
44 128 : he->module = module;
45 128 : he->fnname = funcname;
46 128 : he->priority = priority;
47 :
48 220 : for (pos = &hook->entries; *pos; pos = &(*pos)->next)
49 108 : if (hook->reverse ? (*pos)->priority < priority
50 8 : : (*pos)->priority >= priority)
51 : break;
52 :
53 128 : he->next = *pos;
54 128 : *pos = he;
55 128 : }
56 :
57 14 : void _hook_unregister(struct hook *hook, void *funcptr, void *arg, bool has_arg)
58 : {
59 14 : struct hookent *he, **prev;
60 :
61 20 : for (prev = &hook->entries; (he = *prev) != NULL; prev = &he->next)
62 20 : if (he->hookfn == funcptr && he->hookarg == arg
63 14 : && he->has_arg == has_arg) {
64 14 : *prev = he->next;
65 14 : if (he->ent_on_heap)
66 0 : XFREE(MTYPE_HOOK_ENTRY, he);
67 : else
68 14 : memset(he, 0, sizeof(*he));
69 : break;
70 : }
71 14 : }
|