From 344a537684833372f2b36082c679a350b5ac06f5 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 28 Feb 2019 10:59:52 +0800 Subject: [PATCH] fix SysError to match Linux error code --- kernel/src/syscall/ctrl.rs | 2 +- kernel/src/syscall/fs.rs | 58 +++++++++---------- kernel/src/syscall/mem.rs | 2 +- kernel/src/syscall/mod.rs | 110 ++++++++++++++++++++++++++++++------- kernel/src/syscall/proc.rs | 2 +- 5 files changed, 123 insertions(+), 51 deletions(-) diff --git a/kernel/src/syscall/ctrl.rs b/kernel/src/syscall/ctrl.rs index 3a18f50..4c09151 100644 --- a/kernel/src/syscall/ctrl.rs +++ b/kernel/src/syscall/ctrl.rs @@ -9,6 +9,6 @@ pub fn sys_arch_prctl(code: i32, addr: usize, tf: &mut TrapFrame) -> SysResult { tf.fsbase = addr; Ok(0) } - _ => Err(SysError::Inval), + _ => Err(SysError::EINVAL), } } diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 92f8cdf..086f13e 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -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); let mut proc = process(); 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 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); let mut proc = process(); 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 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 { let mut proc = process(); 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); 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) { Ok(file_inode) => { if flags.contains(OpenFlags::EXCLUSIVE) { - return Err(SysError::Exists); + return Err(SysError::EEXIST); } file_inode }, @@ -100,16 +100,16 @@ pub fn sys_close(fd: usize) -> SysResult { info!("close: fd: {:?}", fd); match process().files.remove(&fd) { Some(_) => Ok(0), - None => Err(SysError::Inval), + None => Err(SysError::EINVAL), } } pub fn sys_stat(path: *const u8, stat_ptr: *mut Stat) -> SysResult { let mut proc = process(); 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) { - return Err(SysError::Inval); + return Err(SysError::EINVAL); } info!("stat: path: {}", path); @@ -123,7 +123,7 @@ pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult { info!("fstat: fd: {}", fd); let mut proc = process(); 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 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_END => SeekFrom::End(offset), SEEK_CUR => SeekFrom::Current(offset), - _ => return Err(SysError::Inval), + _ => return Err(SysError::EINVAL), }; info!("lseek: fd: {}, pos: {:?}", fd, pos); @@ -153,16 +153,16 @@ pub fn sys_getdirentry(fd: usize, dentry_ptr: *mut DirEntry) -> SysResult { info!("getdirentry: {}", fd); let mut proc = process(); 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 dentry = unsafe { &mut *dentry_ptr }; if !dentry.check() { - return Err(SysError::Inval); + return Err(SysError::EINVAL); } let info = file.info()?; 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())?; dentry.set_name(name.as_str()); @@ -173,7 +173,7 @@ pub fn sys_dup2(fd1: usize, fd2: usize) -> SysResult { info!("dup2: {} {}", fd1, fd2); let mut proc = process(); if proc.files.contains_key(&fd2) { - return Err(SysError::Inval); + return Err(SysError::EINVAL); } let file = get_file(&mut proc, fd1)?.clone(); 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> { - proc.files.get_mut(&fd).ok_or(SysError::Inval) + proc.files.get_mut(&fd).ok_or(SysError::EINVAL) } impl From for SysError { fn from(error: FsError) -> Self { match error { - FsError::NotSupported => SysError::Unimp, - FsError::NotFile => SysError::Isdir, - FsError::IsDir => SysError::Isdir, - FsError::NotDir => SysError::Notdir, - FsError::EntryNotFound => SysError::Noent, - FsError::EntryExist => SysError::Exists, - FsError::NotSameFs => SysError::Xdev, - FsError::InvalidParam => SysError::Inval, - FsError::NoDeviceSpace => SysError::Nomem, - FsError::DirRemoved => SysError::Noent, - FsError::DirNotEmpty => SysError::Notempty, - FsError::WrongFs => SysError::Inval, - FsError::DeviceError => SysError::Io, + FsError::NotSupported => SysError::ENOSYS, + FsError::NotFile => SysError::EISDIR, + FsError::IsDir => SysError::EISDIR, + FsError::NotDir => SysError::ENOTDIR, + FsError::EntryNotFound => SysError::ENOENT, + FsError::EntryExist => SysError::EEXIST, + FsError::NotSameFs => SysError::EXDEV, + FsError::InvalidParam => SysError::EINVAL, + FsError::NoDeviceSpace => SysError::ENOMEM, + FsError::DirRemoved => SysError::ENOENT, + FsError::DirNotEmpty => SysError::ENOTEMPTY, + FsError::WrongFs => SysError::EINVAL, + FsError::DeviceError => SysError::EIO, } } } @@ -407,14 +407,14 @@ struct IoVecs(Vec<&'static mut [u8]>); impl IoVecs { fn check_and_new(iov_ptr: *const IoVec, iov_count: usize, vm: &MemorySet, readv: bool) -> Result { 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(); // check all bufs in iov for iov in iovs.iter() { if readv && !vm.check_mut_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(); diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index 3d3290c..bdc021e 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -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::SHARED) { - return Err(SysError::Inval); + return Err(SysError::EINVAL); } let handler = Delay::new(prot_to_attr(prot), GlobalFrameAlloc); proc.memory_set.push(addr, addr + len, handler, "mmap"); diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 9145fde..cff717f 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -1,7 +1,7 @@ //! System call use alloc::{string::String, sync::Arc, vec::Vec}; -use core::{slice, str}; +use core::{slice, str, fmt}; use bitflags::bitflags; use rcore_fs::vfs::{FileType, FsError, INode, Metadata}; @@ -142,26 +142,98 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { pub type SysResult = Result; +#[allow(dead_code)] #[repr(isize)] #[derive(Debug)] pub enum SysError { - // TODO: Linux Error Code - // ucore compatible error code - // note that ucore_plus use another error code table, which is a modified version of the ones used in linux - // name conversion E_XXXXX -> SysError::Xxxxx - // see https://github.com/oscourse-tsinghua/ucore_os_lab/blob/master/labcodes/lab8/libs/error.h - // we only add current used errors here - Inval = 3,// Invalid argument, also Invaild fd number. - Nomem = 4,// Out of memory, also used as no device space in ucore - Noent = 16,// No such file or directory - Isdir = 17,// Fd is a directory - Notdir = 18,// Fd is not a directory - Xdev = 19,// Cross-device link - Unimp = 20,// Not implemented - Exists = 23,// File exists - Notempty = 24,// Directory is not empty - Io = 5,// I/O Error + 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, +} - #[allow(dead_code)] - Unspcified = 1,// A really really unknown error. +#[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", + }, + ) + } } diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index c93ea92..8a61025 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -60,7 +60,7 @@ pub fn sys_exec(name: *const u8, argc: usize, argv: *const *const u8, tf: &mut T }; if args.len() <= 0 { - return Err(SysError::Inval); + return Err(SysError::EINVAL); } // Read program file let path = args[0].as_str();