Merge remote-tracking branch 'origin/biscuit' into biscuit

master
Jiajie Chen 6 years ago
commit 984df11971

@ -9,6 +9,6 @@ pub fn sys_arch_prctl(code: i32, addr: usize, tf: &mut TrapFrame) -> SysResult {
tf.fsbase = addr; tf.fsbase = addr;
Ok(0) Ok(0)
} }
_ => Err(SysError::Inval), _ => Err(SysError::EINVAL),
} }
} }

@ -11,7 +11,7 @@ pub fn sys_read(fd: usize, base: *mut u8, len: usize) -> SysResult {
info!("read: fd: {}, base: {:?}, len: {:#x}", fd, base, len); info!("read: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
let mut proc = process(); let mut proc = process();
if !proc.memory_set.check_mut_array(base, len) { if !proc.memory_set.check_mut_array(base, len) {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
let slice = unsafe { slice::from_raw_parts_mut(base, len) }; let slice = unsafe { slice::from_raw_parts_mut(base, len) };
let len = get_file(&mut proc, fd)?.read(slice)?; let len = get_file(&mut proc, fd)?.read(slice)?;
@ -22,7 +22,7 @@ pub fn sys_write(fd: usize, base: *const u8, len: usize) -> SysResult {
info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len); info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
let mut proc = process(); let mut proc = process();
if !proc.memory_set.check_array(base, len) { if !proc.memory_set.check_array(base, len) {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
let slice = unsafe { slice::from_raw_parts(base, len) }; let slice = unsafe { slice::from_raw_parts(base, len) };
let len = get_file(&mut proc, fd)?.write(slice)?; let len = get_file(&mut proc, fd)?.write(slice)?;
@ -57,7 +57,7 @@ pub fn sys_writev(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResu
pub fn sys_open(path: *const u8, flags: usize, mode: usize) -> SysResult { pub fn sys_open(path: *const u8, flags: usize, mode: usize) -> SysResult {
let mut proc = process(); let mut proc = process();
let path = unsafe { proc.memory_set.check_and_clone_cstr(path) } let path = unsafe { proc.memory_set.check_and_clone_cstr(path) }
.ok_or(SysError::Inval)?; .ok_or(SysError::EINVAL)?;
let flags = OpenFlags::from_bits_truncate(flags); let flags = OpenFlags::from_bits_truncate(flags);
info!("open: path: {:?}, flags: {:?}, mode: {:#o}", path, flags, mode); info!("open: path: {:?}, flags: {:?}, mode: {:#o}", path, flags, mode);
@ -71,7 +71,7 @@ pub fn sys_open(path: *const u8, flags: usize, mode: usize) -> SysResult {
match dir_inode.find(file_name) { match dir_inode.find(file_name) {
Ok(file_inode) => { Ok(file_inode) => {
if flags.contains(OpenFlags::EXCLUSIVE) { if flags.contains(OpenFlags::EXCLUSIVE) {
return Err(SysError::Exists); return Err(SysError::EEXIST);
} }
file_inode file_inode
}, },
@ -100,16 +100,16 @@ pub fn sys_close(fd: usize) -> SysResult {
info!("close: fd: {:?}", fd); info!("close: fd: {:?}", fd);
match process().files.remove(&fd) { match process().files.remove(&fd) {
Some(_) => Ok(0), Some(_) => Ok(0),
None => Err(SysError::Inval), None => Err(SysError::EINVAL),
} }
} }
pub fn sys_stat(path: *const u8, stat_ptr: *mut Stat) -> SysResult { pub fn sys_stat(path: *const u8, stat_ptr: *mut Stat) -> SysResult {
let mut proc = process(); let mut proc = process();
let path = unsafe { proc.memory_set.check_and_clone_cstr(path) } let path = unsafe { proc.memory_set.check_and_clone_cstr(path) }
.ok_or(SysError::Inval)?; .ok_or(SysError::EINVAL)?;
if !proc.memory_set.check_mut_ptr(stat_ptr) { if !proc.memory_set.check_mut_ptr(stat_ptr) {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
info!("stat: path: {}", path); info!("stat: path: {}", path);
@ -123,7 +123,7 @@ pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult {
info!("fstat: fd: {}", fd); info!("fstat: fd: {}", fd);
let mut proc = process(); let mut proc = process();
if !proc.memory_set.check_mut_ptr(stat_ptr) { if !proc.memory_set.check_mut_ptr(stat_ptr) {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
let file = get_file(&mut proc, fd)?; let file = get_file(&mut proc, fd)?;
let stat = Stat::from(file.info()?); let stat = Stat::from(file.info()?);
@ -136,7 +136,7 @@ pub fn sys_lseek(fd: usize, offset: i64, whence: u8) -> SysResult {
SEEK_SET => SeekFrom::Start(offset as u64), SEEK_SET => SeekFrom::Start(offset as u64),
SEEK_END => SeekFrom::End(offset), SEEK_END => SeekFrom::End(offset),
SEEK_CUR => SeekFrom::Current(offset), SEEK_CUR => SeekFrom::Current(offset),
_ => return Err(SysError::Inval), _ => return Err(SysError::EINVAL),
}; };
info!("lseek: fd: {}, pos: {:?}", fd, pos); info!("lseek: fd: {}, pos: {:?}", fd, pos);
@ -153,16 +153,16 @@ pub fn sys_getdirentry(fd: usize, dentry_ptr: *mut DirEntry) -> SysResult {
info!("getdirentry: {}", fd); info!("getdirentry: {}", fd);
let mut proc = process(); let mut proc = process();
if !proc.memory_set.check_mut_ptr(dentry_ptr) { if !proc.memory_set.check_mut_ptr(dentry_ptr) {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
let file = get_file(&mut proc, fd)?; let file = get_file(&mut proc, fd)?;
let dentry = unsafe { &mut *dentry_ptr }; let dentry = unsafe { &mut *dentry_ptr };
if !dentry.check() { if !dentry.check() {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
let info = file.info()?; let info = file.info()?;
if info.type_ != FileType::Dir || info.size <= dentry.entry_id() { if info.type_ != FileType::Dir || info.size <= dentry.entry_id() {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
let name = file.get_entry(dentry.entry_id())?; let name = file.get_entry(dentry.entry_id())?;
dentry.set_name(name.as_str()); dentry.set_name(name.as_str());
@ -173,7 +173,7 @@ pub fn sys_dup2(fd1: usize, fd2: usize) -> SysResult {
info!("dup2: {} {}", fd1, fd2); info!("dup2: {} {}", fd1, fd2);
let mut proc = process(); let mut proc = process();
if proc.files.contains_key(&fd2) { if proc.files.contains_key(&fd2) {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
let file = get_file(&mut proc, fd1)?.clone(); let file = get_file(&mut proc, fd1)?.clone();
proc.files.insert(fd2, file); proc.files.insert(fd2, file);
@ -181,25 +181,25 @@ pub fn sys_dup2(fd1: usize, fd2: usize) -> SysResult {
} }
fn get_file<'a>(proc: &'a mut MutexGuard<'static, Process>, fd: usize) -> Result<&'a mut FileHandle, SysError> { fn get_file<'a>(proc: &'a mut MutexGuard<'static, Process>, fd: usize) -> Result<&'a mut FileHandle, SysError> {
proc.files.get_mut(&fd).ok_or(SysError::Inval) proc.files.get_mut(&fd).ok_or(SysError::EINVAL)
} }
impl From<FsError> for SysError { impl From<FsError> for SysError {
fn from(error: FsError) -> Self { fn from(error: FsError) -> Self {
match error { match error {
FsError::NotSupported => SysError::Unimp, FsError::NotSupported => SysError::ENOSYS,
FsError::NotFile => SysError::Isdir, FsError::NotFile => SysError::EISDIR,
FsError::IsDir => SysError::Isdir, FsError::IsDir => SysError::EISDIR,
FsError::NotDir => SysError::Notdir, FsError::NotDir => SysError::ENOTDIR,
FsError::EntryNotFound => SysError::Noent, FsError::EntryNotFound => SysError::ENOENT,
FsError::EntryExist => SysError::Exists, FsError::EntryExist => SysError::EEXIST,
FsError::NotSameFs => SysError::Xdev, FsError::NotSameFs => SysError::EXDEV,
FsError::InvalidParam => SysError::Inval, FsError::InvalidParam => SysError::EINVAL,
FsError::NoDeviceSpace => SysError::Nomem, FsError::NoDeviceSpace => SysError::ENOMEM,
FsError::DirRemoved => SysError::Noent, FsError::DirRemoved => SysError::ENOENT,
FsError::DirNotEmpty => SysError::Notempty, FsError::DirNotEmpty => SysError::ENOTEMPTY,
FsError::WrongFs => SysError::Inval, FsError::WrongFs => SysError::EINVAL,
FsError::DeviceError => SysError::Io, FsError::DeviceError => SysError::EIO,
} }
} }
} }
@ -407,14 +407,14 @@ struct IoVecs(Vec<&'static mut [u8]>);
impl IoVecs { impl IoVecs {
fn check_and_new(iov_ptr: *const IoVec, iov_count: usize, vm: &MemorySet, readv: bool) -> Result<Self, SysError> { fn check_and_new(iov_ptr: *const IoVec, iov_count: usize, vm: &MemorySet, readv: bool) -> Result<Self, SysError> {
if !vm.check_array(iov_ptr, iov_count) { if !vm.check_array(iov_ptr, iov_count) {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
let iovs = unsafe { slice::from_raw_parts(iov_ptr, iov_count) }.to_vec(); let iovs = unsafe { slice::from_raw_parts(iov_ptr, iov_count) }.to_vec();
// check all bufs in iov // check all bufs in iov
for iov in iovs.iter() { for iov in iovs.iter() {
if readv && !vm.check_mut_array(iov.base, iov.len as usize) if readv && !vm.check_mut_array(iov.base, iov.len as usize)
|| !readv && !vm.check_array(iov.base, iov.len as usize) { || !readv && !vm.check_array(iov.base, iov.len as usize) {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
} }
let slices = iovs.iter().map(|iov| unsafe { slice::from_raw_parts_mut(iov.base, iov.len as usize) }).collect(); let slices = iovs.iter().map(|iov| unsafe { slice::from_raw_parts_mut(iov.base, iov.len as usize) }).collect();

@ -15,7 +15,7 @@ pub fn sys_mmap(mut addr: usize, len: usize, prot: usize, flags: usize, fd: i32,
if flags.contains(MmapFlags::ANONYMOUS) { if flags.contains(MmapFlags::ANONYMOUS) {
if flags.contains(MmapFlags::SHARED) { if flags.contains(MmapFlags::SHARED) {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
let handler = Delay::new(prot_to_attr(prot), GlobalFrameAlloc); let handler = Delay::new(prot_to_attr(prot), GlobalFrameAlloc);
proc.memory_set.push(addr, addr + len, handler, "mmap"); proc.memory_set.push(addr, addr + len, handler, "mmap");

@ -1,7 +1,7 @@
//! System call //! System call
use alloc::{string::String, sync::Arc, vec::Vec}; use alloc::{string::String, sync::Arc, vec::Vec};
use core::{slice, str}; use core::{slice, str, fmt};
use bitflags::bitflags; use bitflags::bitflags;
use rcore_fs::vfs::{FileType, FsError, INode, Metadata}; use rcore_fs::vfs::{FileType, FsError, INode, Metadata};
@ -144,26 +144,98 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
pub type SysResult = Result<isize, SysError>; pub type SysResult = Result<isize, SysError>;
#[allow(dead_code)]
#[repr(isize)] #[repr(isize)]
#[derive(Debug)] #[derive(Debug)]
pub enum SysError { pub enum SysError {
// TODO: Linux Error Code EUNDEF = 0,
// ucore compatible error code EPERM = 1,
// note that ucore_plus use another error code table, which is a modified version of the ones used in linux ENOENT = 2,
// name conversion E_XXXXX -> SysError::Xxxxx ESRCH = 3,
// see https://github.com/oscourse-tsinghua/ucore_os_lab/blob/master/labcodes/lab8/libs/error.h EINTR = 4,
// we only add current used errors here EIO = 5,
Inval = 3,// Invalid argument, also Invaild fd number. ENXIO = 6,
Nomem = 4,// Out of memory, also used as no device space in ucore E2BIG = 7,
Noent = 16,// No such file or directory ENOEXEC = 8,
Isdir = 17,// Fd is a directory EBADF = 9,
Notdir = 18,// Fd is not a directory ECHILD = 10,
Xdev = 19,// Cross-device link EAGAIN = 11,
Unimp = 20,// Not implemented ENOMEM = 12,
Exists = 23,// File exists EACCES = 13,
Notempty = 24,// Directory is not empty EFAULT = 14,
Io = 5,// I/O Error 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,
}
#[allow(dead_code)] #[allow(non_snake_case)]
Unspcified = 1,// A really really unknown error. 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",
},
)
}
} }

@ -18,12 +18,12 @@ pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResu
Ok(fd as isize) Ok(fd as isize)
} }
_ => { _ => {
Err(SysError::Inval) Err(SysError::EINVAL)
} }
} }
} }
_ => { _ => {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
} }
} }

@ -60,7 +60,7 @@ pub fn sys_exec(name: *const u8, argc: usize, argv: *const *const u8, tf: &mut T
}; };
if args.len() <= 0 { if args.len() <= 0 {
return Err(SysError::Inval); return Err(SysError::EINVAL);
} }
// Read program file // Read program file
let path = args[0].as_str(); let path = args[0].as_str();

Loading…
Cancel
Save