| 169 | } |
| 170 | |
| 171 | int |
| 172 | kern_syscall_module_handler(struct sysent *sysents, struct module *mod, |
| 173 | int what, void *arg) |
| 174 | { |
| 175 | struct syscall_module_data *data = arg; |
| 176 | modspecific_t ms; |
| 177 | int error; |
| 178 | |
| 179 | switch (what) { |
| 180 | case MOD_LOAD: |
| 181 | error = kern_syscall_register(sysents, data->offset, |
| 182 | data->new_sysent, &data->old_sysent, data->flags); |
| 183 | if (error) { |
| 184 | /* Leave a mark so we know to safely unload below. */ |
| 185 | data->offset = NULL; |
| 186 | return (error); |
| 187 | } |
| 188 | ms.intval = *data->offset; |
| 189 | MOD_XLOCK; |
| 190 | module_setspecific(mod, &ms); |
| 191 | MOD_XUNLOCK; |
| 192 | if (data->chainevh) |
| 193 | error = data->chainevh(mod, what, data->chainarg); |
| 194 | return (error); |
| 195 | case MOD_UNLOAD: |
| 196 | /* |
| 197 | * MOD_LOAD failed, so just return without calling the |
| 198 | * chained handler since we didn't pass along the MOD_LOAD |
| 199 | * event. |
| 200 | */ |
| 201 | if (data->offset == NULL) |
| 202 | return (0); |
| 203 | if (data->chainevh) { |
| 204 | error = data->chainevh(mod, what, data->chainarg); |
| 205 | if (error) |
| 206 | return error; |
| 207 | } |
| 208 | error = kern_syscall_deregister(sysents, *data->offset, |
| 209 | &data->old_sysent); |
| 210 | return (error); |
| 211 | default: |
| 212 | if (data->chainevh) |
| 213 | return (data->chainevh(mod, what, data->chainarg)); |
| 214 | return (EOPNOTSUPP); |
| 215 | } |
| 216 | |
| 217 | /* NOTREACHED */ |
| 218 | } |
| 219 | |
| 220 | int |
| 221 | syscall_helper_register(struct syscall_helper_data *sd, int flags) |
no test coverage detected