1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-27 02:03:29 +04:00
rCore/kernel/src/syscall/mod.rs

358 lines
12 KiB
Rust

//! System call
use alloc::{string::String, sync::Arc, vec::Vec};
use core::{slice, str, fmt};
use bitflags::bitflags;
use rcore_memory::VMError;
use rcore_fs::vfs::{FileType, FsError, INode, Metadata};
use crate::arch::interrupt::TrapFrame;
use crate::sync::Condvar;
use crate::process::*;
use crate::thread;
use crate::util;
use crate::arch::cpu;
use self::fs::*;
use self::mem::*;
use self::proc::*;
use self::time::*;
use self::net::*;
use self::misc::*;
mod fs;
mod mem;
mod proc;
mod time;
mod net;
mod misc;
/// System call dispatcher
pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
let cid = cpu::id();
let pid = {
process().pid.clone()
};
let tid = processor().tid();
debug!("{}:{}:{} syscall id {} begin", cid, pid, tid, id);
let ret = match id {
// file
000 => sys_read(args[0], args[1] as *mut u8, args[2]),
001 => sys_write(args[0], args[1] as *const u8, args[2]),
002 => sys_open(args[0] as *const u8, args[1], args[2]),
003 => sys_close(args[0]),
004 => sys_stat(args[0] as *const u8, args[1] as *mut Stat),
005 => sys_fstat(args[0], args[1] as *mut Stat),
006 => sys_lstat(args[0] as *const u8, args[1] as *mut Stat),
007 => sys_poll(args[0] as *mut PollFd, args[1], args[2]),
008 => sys_lseek(args[0], args[1] as i64, args[2] as u8),
009 => sys_mmap(args[0], args[1], args[2], args[3], args[4] as i32, args[5]),
010 => sys_mprotect(args[0], args[1], args[2]),
011 => sys_munmap(args[0], args[1]),
017 => sys_pread(args[0], args[1] as *mut u8, args[2], args[3]),
018 => sys_pwrite(args[0], args[1] as *const u8, args[2], args[3]),
019 => sys_readv(args[0], args[1] as *const IoVec, args[2]),
020 => sys_writev(args[0], args[1] as *const IoVec, args[2]),
021 => sys_access(args[0] as *const u8, args[1]),
022 => sys_pipe(args[0] as *mut u32),
023 => sys_select(args[0], args[1] as *mut u32, args[2] as *mut u32, args[3] as *mut u32, args[4] as *const TimeVal),
024 => sys_yield(),
033 => sys_dup2(args[0], args[1]),
// 034 => sys_pause(),
035 => sys_nanosleep(args[0] as *const TimeSpec),
039 => sys_getpid(),
041 => sys_socket(args[0], args[1], args[2]),
042 => sys_connect(args[0], args[1] as *const SockAddr, args[2]),
043 => sys_accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32),
044 => sys_sendto(args[0], args[1] as *const u8, args[2], args[3], args[4] as *const SockAddr, args[5]),
045 => sys_recvfrom(args[0], args[1] as *mut u8, args[2], args[3], args[4] as *mut SockAddr, args[5] as *mut u32),
// 046 => sys_sendmsg(),
// 047 => sys_recvmsg(),
048 => sys_shutdown(args[0], args[1]),
049 => sys_bind(args[0], args[1] as *const SockAddr, args[2]),
050 => sys_listen(args[0], args[1]),
051 => sys_getsockname(args[0], args[1] as *mut SockAddr, args[2] as *mut u32),
052 => sys_getpeername(args[0], args[1] as *mut SockAddr, args[2] as *mut u32),
054 => sys_setsockopt(args[0], args[1], args[2], args[3] as *const u8, args[4]),
055 => sys_getsockopt(args[0], args[1], args[2], args[3] as *mut u8, args[4] as *mut u32),
056 => sys_clone(args[0], args[1], args[2] as *mut u32, args[3] as *mut u32, args[4], tf),
057 => sys_fork(tf),
// use fork for vfork
058 => sys_fork(tf),
059 => sys_exec(args[0] as *const u8, args[1] as *const *const u8, args[2] as *const *const u8, tf),
060 => sys_exit(args[0] as usize),
061 => sys_wait4(args[0] as isize, args[1] as *mut i32), // TODO: wait4
062 => sys_kill(args[0], args[1]),
063 => sys_uname(args[0] as *mut u8),
// 072 => sys_fcntl(),
074 => sys_fsync(args[0]),
075 => sys_fdatasync(args[0]),
076 => sys_truncate(args[0] as *const u8, args[1]),
077 => sys_ftruncate(args[0], args[1]),
079 => sys_getcwd(args[0] as *mut u8, args[1]),
080 => sys_chdir(args[0] as *const u8),
082 => sys_rename(args[0] as *const u8, args[1] as *const u8),
083 => sys_mkdir(args[0] as *const u8, args[1]),
086 => sys_link(args[0] as *const u8, args[1] as *const u8),
087 => sys_unlink(args[0] as *const u8),
096 => sys_gettimeofday(args[0] as *mut TimeVal, args[1] as *const u8),
// 097 => sys_getrlimit(),
098 => sys_getrusage(args[0], args[1] as *mut RUsage),
099 => sys_sysinfo(args[0] as *mut SysInfo),
110 => sys_getppid(),
// 133 => sys_mknod(),
141 => sys_set_priority(args[0]),
158 => sys_arch_prctl(args[0] as i32, args[1], tf),
// 160 => sys_setrlimit(),
// 162 => sys_sync(),
169 => sys_reboot(args[0] as u32, args[1] as u32, args[2] as u32, args[3] as *const u8),
186 => sys_gettid(),
201 => sys_time(args[0] as *mut u64),
202 => sys_futex(args[0], args[1] as u32, args[2] as i32, args[3] as *const TimeSpec),
204 => sys_sched_getaffinity(args[0], args[1], args[2] as *mut u32),
217 => sys_getdents64(args[0], args[1] as *mut LinuxDirent64, args[2]),
228 => sys_clock_gettime(args[0], args[1] as *mut TimeSpec),
231 => sys_exit_group(args[0]),
288 => sys_accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32), // use accept for accept4
// 293 => sys_pipe(),
// for musl: empty impl
012 => {
warn!("sys_brk is unimplemented");
Ok(0)
}
013 => {
warn!("sys_sigaction is unimplemented");
Ok(0)
}
014 => {
warn!("sys_sigprocmask is unimplemented");
Ok(0)
}
016 => {
warn!("sys_ioctl is unimplemented");
Ok(0)
}
028 => {
warn!("sys_madvise is unimplemented");
Ok(0)
}
037 => {
warn!("sys_alarm is unimplemented");
Ok(0)
}
072 => {
warn!("sys_fcntl is unimplemented");
Ok(0)
}
089 => {
warn!("sys_readlink is unimplemented");
Err(SysError::ENOENT)
}
092 => {
warn!("sys_chown is unimplemented");
Ok(0)
}
095 => {
warn!("sys_umask is unimplemented");
Ok(0o777)
}
102 => {
warn!("sys_getuid is unimplemented");
Ok(0)
}
105 => {
warn!("sys_setuid is unimplemented");
Ok(0)
}
107 => {
warn!("sys_geteuid is unimplemented");
Ok(0)
}
108 => {
warn!("sys_getegid is unimplemented");
Ok(0)
}
112 => {
warn!("sys_setsid is unimplemented");
Ok(0)
}
131 => {
warn!("sys_sigaltstack is unimplemented");
Ok(0)
}
162 => {
warn!("sys_sync is unimplemented");
Ok(0)
}
213 => {
warn!("sys_epoll_create is unimplemented");
Err(SysError::ENOSYS)
}
218 => {
warn!("sys_set_tid_address is unimplemented");
Ok(thread::current().id())
}
280 => {
warn!("sys_utimensat is unimplemented");
Ok(0)
}
291 => {
warn!("sys_epoll_create1 is unimplemented");
Err(SysError::ENOSYS)
}
302 => {
warn!("sys_prlimit64 is unimplemented");
Ok(0)
}
_ => {
error!("unknown syscall id: {:#x?}, args: {:x?}", id, args);
crate::trap::error(tf);
}
};
debug!("{}:{}:{} syscall id {} ret with {:x?}", cid, pid, tid, id, ret);
match ret {
Ok(code) => code as isize,
Err(err) => -(err as isize),
}
}
pub type SysResult = Result<usize, SysError>;
#[allow(dead_code)]
#[repr(isize)]
#[derive(Debug)]
pub enum SysError {
EUNDEF = 0,
EPERM = 1,
ENOENT = 2,
ESRCH = 3,
EINTR = 4,
EIO = 5,
ENXIO = 6,
E2BIG = 7,
ENOEXEC = 8,
EBADF = 9,
ECHILD = 10,
EAGAIN = 11,
ENOMEM = 12,
EACCES = 13,
EFAULT = 14,
ENOTBLK = 15,
EBUSY = 16,
EEXIST = 17,
EXDEV = 18,
ENODEV = 19,
ENOTDIR = 20,
EISDIR = 21,
EINVAL = 22,
ENFILE = 23,
EMFILE = 24,
ENOTTY = 25,
ETXTBSY = 26,
EFBIG = 27,
ENOSPC = 28,
ESPIPE = 29,
EROFS = 30,
EMLINK = 31,
EPIPE = 32,
EDOM = 33,
ERANGE = 34,
EDEADLK = 35,
ENAMETOOLONG = 36,
ENOLCK = 37,
ENOSYS = 38,
ENOTEMPTY = 39,
ENOTSOCK = 80,
ENOPROTOOPT = 92,
EPFNOSUPPORT = 96,
EAFNOSUPPORT = 97,
ENOBUFS = 105,
EISCONN = 106,
ENOTCONN = 107,
ECONNREFUSED = 111,
}
#[allow(non_snake_case)]
impl fmt::Display for SysError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}",
match self {
EPERM => "Operation not permitted",
ENOENT => "No such file or directory",
ESRCH => "No such process",
EINTR => "Interrupted system call",
EIO => "I/O error",
ENXIO => "No such device or address",
E2BIG => "Argument list too long",
ENOEXEC => "Exec format error",
EBADF => "Bad file number",
ECHILD => "No child processes",
EAGAIN => "Try again",
ENOMEM => "Out of memory",
EACCES => "Permission denied",
EFAULT => "Bad address",
ENOTBLK => "Block device required",
EBUSY => "Device or resource busy",
EEXIST => "File exists",
EXDEV => "Cross-device link",
ENODEV => "No such device",
ENOTDIR => "Not a directory",
EISDIR => "Is a directory",
EINVAL => "Invalid argument",
ENFILE => "File table overflow",
EMFILE => "Too many open files",
ENOTTY => "Not a typewriter",
ETXTBSY => "Text file busy",
EFBIG => "File too large",
ENOSPC => "No space left on device",
ESPIPE => "Illegal seek",
EROFS => "Read-only file system",
EMLINK => "Too many links",
EPIPE => "Broken pipe",
EDOM => "Math argument out of domain of func",
ERANGE => "Math result not representable",
EDEADLK => "Resource deadlock would occur",
ENAMETOOLONG => "File name too long",
ENOLCK => "No record locks available",
ENOSYS => "Function not implemented",
ENOTEMPTY => "Directory not empty",
ENOTSOCK => "Socket operation on non-socket",
ENOPROTOOPT => "Protocol not available",
EPFNOSUPPORT => "Protocol family not supported",
EAFNOSUPPORT => "Address family not supported by protocol",
ENOBUFS => "No buffer space available",
EISCONN => "Transport endpoint is already connected",
ENOTCONN => "Transport endpoint is not connected",
ECONNREFUSED => "Connection refused",
_ => "Unknown error",
},
)
}
}
impl From<VMError> for SysError {
fn from(_: VMError) -> Self {
SysError::EFAULT
}
}
const SPIN_WAIT_TIMES: usize = 100;
pub fn spin_and_wait(condvars: &[&Condvar], mut action: impl FnMut() -> Option<SysResult>) -> SysResult {
for i in 0..SPIN_WAIT_TIMES {
if let Some(result) = action() {
return result;
}
}
loop {
if let Some(result) = action() {
return result;
}
Condvar::wait_any(&condvars);
}
}