kern_syscalls.c revision 83366
142433Sdfr/*- 242433Sdfr * Copyright (c) 1999 Assar Westerlund 342433Sdfr * All rights reserved. 442433Sdfr * 542433Sdfr * Redistribution and use in source and binary forms, with or without 642433Sdfr * modification, are permitted provided that the following conditions 742433Sdfr * are met: 842433Sdfr * 1. Redistributions of source code must retain the above copyright 942433Sdfr * notice, this list of conditions and the following disclaimer. 1042433Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1142433Sdfr * notice, this list of conditions and the following disclaimer in the 1242433Sdfr * documentation and/or other materials provided with the distribution. 1342433Sdfr * 1442433Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1542433Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1642433Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1742433Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1842433Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1942433Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2042433Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2142433Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2242433Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2342433Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2442433Sdfr * SUCH DAMAGE. 2542433Sdfr * 2650477Speter * $FreeBSD: head/sys/kern/kern_syscalls.c 83366 2001-09-12 08:38:13Z julian $ 2742433Sdfr */ 2842433Sdfr 2942433Sdfr#include <sys/param.h> 3042433Sdfr#include <sys/sysproto.h> 3142433Sdfr#include <sys/sysent.h> 3242433Sdfr#include <sys/syscall.h> 3342433Sdfr#include <sys/module.h> 3442433Sdfr 3542756Speter/* 3642756Speter * Acts like "nosys" but can be identified in sysent for dynamic call 3742756Speter * number assignment for a limited number of calls. 3842756Speter * 3942756Speter * Place holder for system call slots reserved for loadable modules. 4042756Speter */ 4142433Sdfrint 4283366Sjulianlkmnosys(struct thread *td, struct nosys_args *args) 4342756Speter{ 4483366Sjulian return(nosys(td, args)); 4542756Speter} 4642756Speter 4742756Speterint 4883366Sjulianlkmressys(struct thread *td, struct nosys_args *args) 4969449Salfred{ 5083366Sjulian return(nosys(td, args)); 5169449Salfred} 5269449Salfred 5369449Salfredint 5442433Sdfrsyscall_register(int *offset, struct sysent *new_sysent, 5542433Sdfr struct sysent *old_sysent) 5642433Sdfr{ 5742433Sdfr if (*offset == NO_SYSCALL) { 5842433Sdfr int i; 5942433Sdfr 6042433Sdfr for (i = 1; i < SYS_MAXSYSCALL; ++i) 6142433Sdfr if (sysent[i].sy_call == (sy_call_t *)lkmnosys) 6242433Sdfr break; 6342433Sdfr if (i == SYS_MAXSYSCALL) 6442433Sdfr return ENFILE; 6542433Sdfr *offset = i; 6642433Sdfr } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL) 6742433Sdfr return EINVAL; 6869449Salfred else if (sysent[*offset].sy_call != (sy_call_t *)lkmnosys && 6969449Salfred sysent[*offset].sy_call != (sy_call_t *)lkmressys) 7042433Sdfr return EEXIST; 7142433Sdfr 7242433Sdfr *old_sysent = sysent[*offset]; 7342433Sdfr sysent[*offset] = *new_sysent; 7442433Sdfr return 0; 7542433Sdfr} 7642433Sdfr 7742433Sdfrint 7842433Sdfrsyscall_deregister(int *offset, struct sysent *old_sysent) 7942433Sdfr{ 8042433Sdfr if (*offset) 8142433Sdfr sysent[*offset] = *old_sysent; 8242433Sdfr return 0; 8342433Sdfr} 8442433Sdfr 8542433Sdfrint 8642433Sdfrsyscall_module_handler(struct module *mod, int what, void *arg) 8742433Sdfr{ 8842433Sdfr struct syscall_module_data *data = (struct syscall_module_data*)arg; 8942435Sdfr modspecific_t ms; 9042433Sdfr int error; 9142433Sdfr 9242433Sdfr switch (what) { 9342433Sdfr case MOD_LOAD : 9442433Sdfr error = syscall_register(data->offset, data->new_sysent, 9542433Sdfr &data->old_sysent); 9642433Sdfr if (error) 9742433Sdfr return error; 9842435Sdfr ms.intval = *data->offset; 9942435Sdfr module_setspecific(mod, &ms); 10048269Sdfr if (data->chainevh) 10148269Sdfr error = data->chainevh(mod, what, data->chainarg); 10248269Sdfr return error; 10348269Sdfr 10442433Sdfr case MOD_UNLOAD : 10548269Sdfr if (data->chainevh) { 10648269Sdfr error = data->chainevh(mod, what, data->chainarg); 10748269Sdfr if (error) 10848269Sdfr return error; 10948269Sdfr } 11042433Sdfr error = syscall_deregister(data->offset, &data->old_sysent); 11148269Sdfr return error; 11242433Sdfr } 11348269Sdfr 11442433Sdfr if (data->chainevh) 11542433Sdfr return data->chainevh(mod, what, data->chainarg); 11642433Sdfr else 11742433Sdfr return 0; 11842433Sdfr} 119