📄 syscall.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 + -