⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syscall.c

📁 一款类linux的操作系统源码
💻 C
字号:
/* *  Roadrunner/pk *    Copyright (C) 1989-2001  Cornfed Systems, Inc. * *  The Roadrunner/pk operating system is free software; you can *  redistribute and/or modify it under the terms of the GNU General *  Public License, version 2, as published by the Free Software *  Foundation. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public *  License along with this program; if not, write to the Free *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, *  MA 02111-1307 USA * *  More information about the Roadrunner/pk operating system of *  which this file is a part is available on the World-Wide Web *  at: http://www.cornfed.com. * */#include <dev.h>#include <errno.h>#include <fcntl.h>#include <fs.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys.h>#include <sys/intr.h>#include <sys/proc.h>#include <sys/segment.h>#include <sys/socket.h>#include <sys/syscall.h>#include <sys/types.h>#include <sys/utsname.h>#include <unistd.h>#include <dev/cons.h>#define KERNEL_MODE							\    disable;								\    /* kern_data_segs(); */					\    enable#define USER_MODE							\    disable;								\    /* user_data_segs(); */					\    enableintsyscall(int syscallno, void *params){    KERNEL_MODE;        switch (syscallno) {    case SYSCALL_ACCEPT:	{	    int result, s;	    s = *((int *) params);	    if (s < 0 || s >= FILES || filetab[s].type != FT_SOCKET) {		USER_MODE;		return EINVAL;	    }	    result = accept(s, *((struct sockaddr **) ((u_long)params + 4)),			    *((int **) ((u_long)params + 8)));	    USER_MODE;	    return result;	}    case SYSCALL_ATTR:	{	    int fileno;	    file_t file;	    int result;	    fileno = *((int *) params);	    if (fileno < 0 || fileno >= FILES) {		USER_MODE;		return EINVAL;	    }	    file = &(filetab[fileno]);	    result = file_attr(file, *((attrlist_t *) ((u_long)params + 4)));	    USER_MODE;	    return result;	}    case SYSCALL_BIND:	{	    int result, s;	    s = *((int *) params);	    if (s < 0 || s >= FILES || filetab[s].type != FT_SOCKET) {		USER_MODE;		return EINVAL;	    }	    result = bind(s, *((struct sockaddr **) ((u_long)params + 4)),			  *((int *) ((u_long)params + 8)));	    USER_MODE;	    return result;	}    case SYSCALL_CHDIR:	{	    int result = proc_chdir(*((char **) params));	    USER_MODE;	    return result;	}    case SYSCALL_CLOSE:	{	    int fileno;	    file_t file;	    int result;	    fileno = *((int *) params);	    if (fileno < 0 || fileno >= FILES) {		USER_MODE;		return EINVAL;	    }	    file = &(filetab[fileno]);	    result = file_close(file);	    USER_MODE;	    return result;	}    case SYSCALL_CONNECT:	{	    int result, s;	    s = *((int *) params);	    if (s < 0 || s >= FILES || filetab[s].type != FT_SOCKET) {		USER_MODE;		return EINVAL;	    }	    result = connect(s, *((struct sockaddr **) ((u_long)params + 4)),			     *((int *) ((u_long)params + 8)));	    USER_MODE;	    return result;	}    case SYSCALL_EXEC:	{	    pid_t pid = proc_exec(*((char **) params),				  *((int *) ((u_long)params + 4)),				  *((char ***) ((u_long)params + 8)));	    USER_MODE;	    return (int) pid;	}    case SYSCALL_EXIT:	proc_exit(*((int *) params));	/* Not reached */    case SYSCALL_FREE:	free(*((void **) params));	USER_MODE;	return 0;		       /* Return value ignored */    case SYSCALL_GETCWD:	{	    char *cwd = proc_getcwd(*((char **) params),				    *((size_t *) ((u_long)params + 4)));	    USER_MODE;	    return (int) cwd;	}    case SYSCALL_GETFSTAB:	{	    int result = fs_getfstab(*((fsrectab_t **) params));	    USER_MODE;	    return result;	}    case SYSCALL_GETPID:	{	    pid_t pid = proc_getpid();	    USER_MODE;	    return pid;	}    case SYSCALL_GETSTDPATH:	{	    int fd = proc_getstdpath(*((pid_t *) params),				     *((int *) ((u_long)params + 4)));	    USER_MODE;	    return fd;	}    case SYSCALL_GETTIMEOFDAY:	{	    timeval_t tv;	    tv = *((timeval_t *) params);	    if (tv == NULL) {		USER_MODE;		return EINVAL;	    }	    utime(&(tv->tv_sec), &(tv->tv_usec));	    USER_MODE;	    return 0;	}    case SYSCALL_HALT:	//halt(); //2002年10月15日修改	return 0;	/* Not reached */    case SYSCALL_IOCTL:	{	    int fileno;	    file_t file;	    int result;	    fileno = *((int *) params);	    if (fileno == STDIN)		fileno = current->fd[PFD_STDIN];	    else if (fileno == STDOUT)		fileno = current->fd[PFD_STDOUT];	    else if (fileno == STDERR)		fileno = current->fd[PFD_STDERR];	    if (fileno < 0 || fileno >= FILES) {		USER_MODE;		return EINVAL;	    }	    file = &(filetab[fileno]);	    result = file_ioctl(file, *((int *) ((u_long)params + 4)),				*((void **) ((u_long)params + 8)));	    USER_MODE;	    return result;	}    case SYSCALL_LISTEN:	{	    int result, s;	    s = *((int *) params);	    if (s < 0 || s >= FILES || filetab[s].type != FT_SOCKET) {		USER_MODE;		return EINVAL;	    }	    result = listen(s, *((int *) ((u_long)params + 4)));	    USER_MODE;	    return result;	}    case SYSCALL_LOAD:	{	    int result = load(*((char **) params),			      *((char ***) ((u_long)params + 4)),			      *((u_long **) ((u_long)params + 8)),			      *((char ***) ((u_long)params + 12)));	    USER_MODE;	    return result;	}    case SYSCALL_MALLOC:	{	    void *ptr = malloc(*((size_t *) params));	    USER_MODE;	    return (int) ptr;	}    case SYSCALL_MKDIR:	{	    file_t file;	    int result;	    /* XXX Ignore mode parameter for the moment... */	    result = file_open(*((char **) params),			       O_MKDIR | O_CREAT | O_RDWR, &file);	    if (result < 0) {		USER_MODE;		return result;	    }	    USER_MODE;	    return file->slot;	}    case SYSCALL_MOUNT:	{	    fs_t fs;	    int devno, i, result;	    devno = dev_open(*((char **) ((u_long)params + 8)));	    if (devno < 0) {		USER_MODE;		return devno;	    }	    for (i = 0; i < FILE_SYSTEM_TYPES; i++)		if (strcmp(fsopstab[i].name, "rrfs") == 0)		    break;	    if (i == FILE_SYSTEM_TYPES) {		USER_MODE;		return ENOFSTYPE;	    }	    result = fs_mount(&(fsopstab[i]), *((char **) ((u_long)params + 4)),			      devno, &fs);	    USER_MODE;	    return result;	}    case SYSCALL_OPEN:	{	    file_t file;	    int result;	    result = file_open(*((char **) params),			       *((int *) ((u_long)params + 4)), &file);	    if (result < 0) {		USER_MODE;		return result;	    }	    USER_MODE;	    return file->slot;	}    case SYSCALL_READ:	{	    int fileno;	    file_t file;	    int len, result;	    fileno = *((int *) params);	    if (fileno == STDIN)		fileno = current->fd[PFD_STDIN];	    else if (fileno == STDOUT)		fileno = current->fd[PFD_STDOUT];	    else if (fileno == STDERR)		fileno = current->fd[PFD_STDERR];	    if (fileno < 0 || fileno >= FILES) {		USER_MODE;		return EINVAL;	    }	    file = &(filetab[fileno]);	    len = *((int *) ((u_long)params + 8));	    result = file_read(file, *((char **) ((u_long)params + 4)), &len);	    USER_MODE;	    if (result < 0)		return result;	    return len;	}    case SYSCALL_READDIR:	{	    int fileno;	    file_t file;	    int result;	    fileno = *((int *) params);	    if (fileno < 0 || fileno >= FILES) {		USER_MODE;		return EINVAL;	    }	    file = &(filetab[fileno]);	    result = file_readdir(file, *((char **) ((u_long)params + 4)));	    USER_MODE;	    return result;	}    case SYSCALL_REBOOT:	//reboot(); //2002年10月15日修改	return 0;	/* Not reached */    case SYSCALL_RECV:	{	    int s;	    ssize_t count;	    s = *((int *) params);	    if (s < 0 || s >= FILES || filetab[s].type != FT_SOCKET) {		USER_MODE;		return EINVAL;	    }	    count = recv(s, *((void **) ((u_long)params + 4)),			 *((size_t *) ((u_long)params + 8)),			 *((int *) ((u_long)params + 12)));	    USER_MODE;	    return (int) count;	}    case SYSCALL_SEND:	{	    int s;	    ssize_t count;	    s = *((int *) params);	    if (s < 0 || s >= FILES || filetab[s].type != FT_SOCKET) {		USER_MODE;		return EINVAL;	    }	    count = send(s, *((void **) ((u_long)params + 4)),			 *((size_t *) ((u_long)params + 8)),			 *((int *) ((u_long)params + 12)));	    USER_MODE;	    return (int) count;	}    case SYSCALL_SETSTDPATH:	proc_setstdpath(*((pid_t *) params),			*((int *) ((u_long)params + 4)), *((int *) ((u_long)params + 8)));	USER_MODE;	return 0;		       /* Return value ignored */    case SYSCALL_SHUTDOWN:	{	    int result, s;	    s = *((int *) params);	    if (s < 0 || s >= FILES || filetab[s].type != FT_SOCKET) {		USER_MODE;		return EINVAL;	    }	    result = shutdown(s, *((int *) ((u_long)params + 4)));	    USER_MODE;	    return result;	}    case SYSCALL_SOCKET:	{	    int s = socket(*((int *) params),			   *((int *) ((u_long)params + 4)),			   *((int *) ((u_long)params + 8)));	    USER_MODE;	    return s;	}    case SYSCALL_UNAME:	{	    int result = uname(*((utsname_t *) params));	    USER_MODE;	    return result;	}    case SYSCALL_UNLINK:	{	    int result = file_unlink(*((char **) params));	    USER_MODE;	    return result;	}    case SYSCALL_UNMOUNT:	{	    fs_t fs;	    int result;	    fs = fs_lookup(*((char **) params));	    if (fs == NULL) {		USER_MODE;		return EINVAL;	    }	    result = fs_unmount(fs);	    USER_MODE;	    return result;	}    case SYSCALL_WAIT:	{	    int result = proc_wait(*((pid_t *) params));	    USER_MODE;	    return result;	}    case SYSCALL_WRITE:	{	    int fileno;	    file_t file;	    int len, result;	    fileno = *((int *) params);	    	    //2002年10月16日修改	    //if (fileno == STDIN)		//fileno = current->fd[PFD_STDIN];	    //else if (fileno == STDOUT)		//fileno = current->fd[PFD_STDOUT];	    //else if (fileno == STDERR)		//fileno = current->fd[PFD_STDERR];			    if (fileno == STDIN)	    {	       return 0;	    }	    else if ((fileno == STDOUT) || (fileno == STDERR))	    {	    	       cons_put(**(u_long **)((u_long)params + 4));		   return 0;        }                	    if (fileno < 0 || fileno >= FILES) {		USER_MODE;		return EINVAL;	    }	    file = &(filetab[fileno]);	    len = *((int *) ((u_long)params + 8));	    	    //2002年10月15日修改	    //result = file_write(file, *((char **) ((u_long)params + 4)), &len);	    result = file_write(file, (*((char **) ((u_long)params + 4)) + 4 -len%8), &len);	    USER_MODE;	    if (result < 0)		return result;	    return len;	}    default:	USER_MODE;	return ENOSYS;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -