2019-02-22 10:10:24 +04:00
|
|
|
//! System call
|
|
|
|
|
|
|
|
use alloc::{string::String, sync::Arc, vec::Vec};
|
2019-02-28 06:59:52 +04:00
|
|
|
use core::{slice, str, fmt};
|
2019-02-22 10:10:24 +04:00
|
|
|
|
|
|
|
use bitflags::bitflags;
|
2019-03-02 21:27:30 +04:00
|
|
|
use rcore_memory::VMError;
|
2019-02-22 19:48:05 +04:00
|
|
|
use rcore_fs::vfs::{FileType, FsError, INode, Metadata};
|
2019-02-22 10:10:24 +04:00
|
|
|
use spin::{Mutex, MutexGuard};
|
|
|
|
|
|
|
|
use crate::arch::interrupt::TrapFrame;
|
2019-02-25 21:44:13 +04:00
|
|
|
use crate::fs::FileHandle;
|
2019-02-22 10:10:24 +04:00
|
|
|
use crate::process::*;
|
|
|
|
use crate::thread;
|
|
|
|
use crate::util;
|
|
|
|
|
|
|
|
use self::fs::*;
|
2019-02-22 19:48:05 +04:00
|
|
|
use self::mem::*;
|
2019-02-22 10:10:24 +04:00
|
|
|
use self::proc::*;
|
|
|
|
use self::time::*;
|
2019-02-24 20:20:37 +04:00
|
|
|
use self::ctrl::*;
|
2019-02-28 08:31:10 +04:00
|
|
|
use self::net::*;
|
2019-02-22 10:10:24 +04:00
|
|
|
|
|
|
|
mod fs;
|
2019-02-22 19:48:05 +04:00
|
|
|
mod mem;
|
2019-02-22 10:10:24 +04:00
|
|
|
mod proc;
|
|
|
|
mod time;
|
2019-02-24 20:20:37 +04:00
|
|
|
mod ctrl;
|
2019-02-28 08:31:10 +04:00
|
|
|
mod net;
|
2019-02-22 10:10:24 +04:00
|
|
|
|
|
|
|
/// System call dispatcher
|
|
|
|
pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
|
|
|
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]),
|
2019-02-25 21:44:13 +04:00
|
|
|
002 => sys_open(args[0] as *const u8, args[1], args[2]),
|
2019-02-22 10:10:24 +04:00
|
|
|
003 => sys_close(args[0]),
|
2019-02-26 14:13:40 +04:00
|
|
|
004 => sys_stat(args[0] as *const u8, args[1] as *mut Stat),
|
2019-02-22 10:10:24 +04:00
|
|
|
005 => sys_fstat(args[0], args[1] as *mut Stat),
|
2019-03-02 13:17:57 +04:00
|
|
|
006 => sys_lstat(args[0] as *const u8, args[1] as *mut Stat),
|
2019-03-04 20:57:40 +04:00
|
|
|
007 => sys_poll(args[0] as *mut PollFd, args[1], args[2]),
|
2019-02-26 13:01:38 +04:00
|
|
|
008 => sys_lseek(args[0], args[1] as i64, args[2] as u8),
|
2019-02-27 20:15:33 +04:00
|
|
|
009 => sys_mmap(args[0], args[1], args[2], args[3], args[4] as i32, args[5]),
|
2019-02-22 19:48:05 +04:00
|
|
|
011 => sys_munmap(args[0], args[1]),
|
2019-02-26 14:13:40 +04:00
|
|
|
019 => sys_readv(args[0], args[1] as *const IoVec, args[2]),
|
|
|
|
020 => sys_writev(args[0], args[1] as *const IoVec, args[2]),
|
2019-02-22 10:10:24 +04:00
|
|
|
// 021 => sys_access(),
|
|
|
|
024 => sys_yield(),
|
|
|
|
033 => sys_dup2(args[0], args[1]),
|
|
|
|
// 034 => sys_pause(),
|
|
|
|
035 => sys_sleep(args[0]), // TODO: nanosleep
|
|
|
|
039 => sys_getpid(),
|
2019-02-28 08:31:10 +04:00
|
|
|
041 => sys_socket(args[0], args[1], args[2]),
|
2019-02-28 10:46:46 +04:00
|
|
|
042 => sys_connect(args[0], args[1] as *const u8, args[2]),
|
2019-02-22 10:10:24 +04:00
|
|
|
// 043 => sys_accept(),
|
2019-02-28 10:46:46 +04:00
|
|
|
044 => sys_sendto(args[0], args[1] as *const u8, args[2], args[3], args[4] as *const u8, args[5]),
|
2019-03-04 20:57:40 +04:00
|
|
|
045 => sys_recvfrom(args[0], args[1] as *mut u8, args[2], args[3], args[4] as *mut u8, args[5] as *mut u32),
|
2019-02-22 10:10:24 +04:00
|
|
|
// 046 => sys_sendmsg(),
|
|
|
|
// 047 => sys_recvmsg(),
|
|
|
|
// 048 => sys_shutdown(),
|
|
|
|
// 049 => sys_bind(),
|
|
|
|
// 050 => sys_listen(),
|
2019-02-28 10:46:46 +04:00
|
|
|
054 => sys_setsockopt(args[0], args[1], args[2], args[3] as *const u8, args[4]),
|
2019-02-22 10:10:24 +04:00
|
|
|
// 055 => sys_getsockopt(),
|
|
|
|
// 056 => sys_clone(),
|
|
|
|
057 => sys_fork(tf),
|
|
|
|
059 => sys_exec(args[0] as *const u8, args[1] as usize, args[2] as *const *const u8, tf),
|
|
|
|
060 => sys_exit(args[0] as isize),
|
|
|
|
061 => sys_wait(args[0], args[1] as *mut i32), // TODO: wait4
|
|
|
|
062 => sys_kill(args[0]),
|
|
|
|
// 072 => sys_fcntl(),
|
2019-03-02 19:16:11 +04:00
|
|
|
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]),
|
2019-03-02 16:25:30 +04:00
|
|
|
079 => sys_getcwd(args[0] as *mut u8, args[1]),
|
2019-03-02 17:25:36 +04:00
|
|
|
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]),
|
2019-03-02 19:16:11 +04:00
|
|
|
086 => sys_link(args[0] as *const u8, args[1] as *const u8),
|
|
|
|
087 => sys_unlink(args[0] as *const u8),
|
2019-03-04 19:52:19 +04:00
|
|
|
096 => sys_gettimeofday(args[0] as *mut TimeVal, args[1] as *const u8),
|
2019-02-22 10:10:24 +04:00
|
|
|
// 097 => sys_getrlimit(),
|
|
|
|
// 098 => sys_getrusage(),
|
2019-03-02 15:09:39 +04:00
|
|
|
110 => sys_getppid(),
|
2019-02-22 10:10:24 +04:00
|
|
|
// 133 => sys_mknod(),
|
|
|
|
141 => sys_set_priority(args[0]),
|
2019-03-02 16:15:55 +04:00
|
|
|
158 => sys_arch_prctl(args[0] as i32, args[1], tf),
|
2019-02-22 10:10:24 +04:00
|
|
|
// 160 => sys_setrlimit(),
|
|
|
|
// 162 => sys_sync(),
|
|
|
|
// 169 => sys_reboot(),
|
2019-03-02 16:15:55 +04:00
|
|
|
201 => sys_time(args[0] as *mut u64),
|
2019-03-02 13:17:57 +04:00
|
|
|
217 => sys_getdents64(args[0], args[1] as *mut LinuxDirent64, args[2]),
|
2019-02-22 10:10:24 +04:00
|
|
|
// 293 => sys_pipe(),
|
|
|
|
|
|
|
|
// for musl: empty impl
|
2019-02-22 19:48:05 +04:00
|
|
|
012 => {
|
|
|
|
warn!("sys_brk is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
|
|
|
013 => {
|
|
|
|
warn!("sys_sigaction is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
|
|
|
014 => {
|
|
|
|
warn!("sys_sigprocmask is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
2019-02-28 03:34:45 +04:00
|
|
|
016 => {
|
|
|
|
warn!("sys_ioctl is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
2019-02-28 10:46:46 +04:00
|
|
|
037 => {
|
|
|
|
warn!("sys_alarm is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
|
|
|
072 => {
|
|
|
|
warn!("sys_fcntl is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
2019-03-02 17:25:36 +04:00
|
|
|
095 => {
|
|
|
|
warn!("sys_umask is unimplemented");
|
|
|
|
Ok(0o777)
|
|
|
|
}
|
2019-02-28 03:34:45 +04:00
|
|
|
102 => {
|
|
|
|
warn!("sys_getuid is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
2019-02-28 10:46:46 +04:00
|
|
|
105 => {
|
|
|
|
warn!("sys_setuid is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
2019-02-28 03:34:45 +04:00
|
|
|
107 => {
|
|
|
|
warn!("sys_geteuid is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
|
|
|
108 => {
|
|
|
|
warn!("sys_getegid is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
2019-02-22 19:48:05 +04:00
|
|
|
131 => {
|
|
|
|
warn!("sys_sigaltstack is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
2019-02-22 10:10:24 +04:00
|
|
|
218 => {
|
|
|
|
warn!("sys_set_tid_address is unimplemented");
|
2019-02-25 21:44:13 +04:00
|
|
|
Ok(thread::current().id() as isize)
|
2019-02-22 10:10:24 +04:00
|
|
|
}
|
2019-03-02 13:17:57 +04:00
|
|
|
228 => {
|
|
|
|
warn!("sys_clock_gettime is unimplemented");
|
|
|
|
Ok(0)
|
|
|
|
}
|
2019-02-27 20:15:33 +04:00
|
|
|
231 => {
|
|
|
|
warn!("sys_exit_group is unimplemented");
|
|
|
|
sys_exit(args[0] as isize);
|
|
|
|
}
|
2019-02-22 10:10:24 +04:00
|
|
|
_ => {
|
|
|
|
error!("unknown syscall id: {:#x?}, args: {:x?}", id, args);
|
|
|
|
crate::trap::error(tf);
|
|
|
|
}
|
|
|
|
};
|
2019-02-28 10:46:46 +04:00
|
|
|
debug!("syscall id {} ret with {:?}", id, ret);
|
2019-02-22 10:10:24 +04:00
|
|
|
match ret {
|
|
|
|
Ok(code) => code,
|
|
|
|
Err(err) => -(err as isize),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type SysResult = Result<isize, SysError>;
|
|
|
|
|
2019-02-28 06:59:52 +04:00
|
|
|
#[allow(dead_code)]
|
2019-02-22 10:10:24 +04:00
|
|
|
#[repr(isize)]
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum SysError {
|
2019-02-28 06:59:52 +04:00
|
|
|
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,
|
2019-02-28 10:46:46 +04:00
|
|
|
ENOTSOCK = 80,
|
|
|
|
EPFNOSUPPORT = 96,
|
|
|
|
EAFNOSUPPORT = 97,
|
|
|
|
ENOBUFS = 105,
|
|
|
|
EISCONN = 106,
|
|
|
|
ENOTCONN = 107,
|
|
|
|
ECONNREFUSED = 111,
|
2019-02-28 06:59:52 +04:00
|
|
|
}
|
2019-02-22 10:10:24 +04:00
|
|
|
|
2019-02-28 06:59:52 +04:00
|
|
|
#[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",
|
|
|
|
_ => "Unknown error",
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
2019-02-22 10:10:24 +04:00
|
|
|
}
|
2019-03-02 21:27:30 +04:00
|
|
|
|
|
|
|
impl From<VMError> for SysError {
|
|
|
|
fn from(_: VMError) -> Self {
|
|
|
|
SysError::EFAULT
|
|
|
|
}
|
|
|
|
}
|