* Register a new helper hook function with a helper hook point. */
| 130 | * Register a new helper hook function with a helper hook point. |
| 131 | */ |
| 132 | int |
| 133 | hhook_add_hook(struct hhook_head *hhh, struct hookinfo *hki, uint32_t flags) |
| 134 | { |
| 135 | struct hhook *hhk, *tmp; |
| 136 | int error; |
| 137 | |
| 138 | error = 0; |
| 139 | |
| 140 | if (hhh == NULL) |
| 141 | return (ENOENT); |
| 142 | |
| 143 | hhk = malloc(sizeof(struct hhook), M_HHOOK, |
| 144 | M_ZERO | ((flags & HHOOK_WAITOK) ? M_WAITOK : M_NOWAIT)); |
| 145 | |
| 146 | if (hhk == NULL) |
| 147 | return (ENOMEM); |
| 148 | |
| 149 | hhk->hhk_helper = hki->hook_helper; |
| 150 | hhk->hhk_func = hki->hook_func; |
| 151 | hhk->hhk_udata = hki->hook_udata; |
| 152 | |
| 153 | HHH_WLOCK(hhh); |
| 154 | STAILQ_FOREACH(tmp, &hhh->hhh_hooks, hhk_next) { |
| 155 | if (tmp->hhk_func == hki->hook_func && |
| 156 | tmp->hhk_udata == hki->hook_udata) { |
| 157 | /* The helper hook function is already registered. */ |
| 158 | error = EEXIST; |
| 159 | break; |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | if (!error) { |
| 164 | STAILQ_INSERT_TAIL(&hhh->hhh_hooks, hhk, hhk_next); |
| 165 | hhh->hhh_nhooks++; |
| 166 | } else |
| 167 | free(hhk, M_HHOOK); |
| 168 | |
| 169 | HHH_WUNLOCK(hhh); |
| 170 | |
| 171 | return (error); |
| 172 | } |
| 173 | |
| 174 | /* |
| 175 | * Register a helper hook function with a helper hook point (including all |
no test coverage detected