rename File to FileHandle. impl create for sys_open.

toolchain_update
WangRunji 6 years ago
parent 6d78206f77
commit cab19688d5

9
kernel/Cargo.lock generated

@ -103,6 +103,11 @@ name = "cfg-if"
version = "0.1.6" version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "deque"
version = "0.3.2"
source = "git+https://github.com/wangrunji0408/deque.git?branch=no_std#907d03935b9badde1902d9c84d138872f34c6763"
[[package]] [[package]]
name = "device_tree" name = "device_tree"
version = "1.0.3" version = "1.0.3"
@ -296,8 +301,9 @@ dependencies = [
name = "rcore-thread" name = "rcore-thread"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"deque 0.3.2 (git+https://github.com/wangrunji0408/deque.git?branch=no_std)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -511,6 +517,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" "checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum deque 0.3.2 (git+https://github.com/wangrunji0408/deque.git?branch=no_std)" = "<none>"
"checksum device_tree 1.0.3 (git+https://github.com/jiegec/device_tree-rs)" = "<none>" "checksum device_tree 1.0.3 (git+https://github.com/jiegec/device_tree-rs)" = "<none>"
"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" "checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0"
"checksum fuchsia-cprng 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81f7f8eb465745ea9b02e2704612a9946a59fa40572086c6fd49d6ddcf30bf31" "checksum fuchsia-cprng 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81f7f8eb465745ea9b02e2704612a9946a59fa40572086c6fd49d6ddcf30bf31"

@ -1,31 +1,50 @@
//! File structure for process //! File handle for process
use alloc::{string::String, sync::Arc}; use alloc::{string::String, sync::Arc};
use rcore_fs::vfs::{Metadata, INode, Result}; use rcore_fs::vfs::{Metadata, INode, Result, FsError};
#[derive(Clone)] #[derive(Clone)]
pub struct File { pub struct FileHandle {
inode: Arc<INode>, inode: Arc<INode>,
offset: usize, offset: usize,
readable: bool, options: OpenOptions,
writable: bool,
} }
impl File { #[derive(Debug, Clone)]
pub fn new(inode: Arc<INode>, readable: bool, writable: bool) -> Self { pub struct OpenOptions {
File { inode, offset: 0, readable, writable } pub read: bool,
pub write: bool,
/// Before each write, the file offset is positioned at the end of the file.
pub append: bool,
}
impl FileHandle {
pub fn new(inode: Arc<INode>, options: OpenOptions) -> Self {
FileHandle {
inode,
offset: 0,
options,
}
} }
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> { pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
assert!(self.readable); if !self.options.read {
return Err(FsError::InvalidParam); // FIXME: => EBADF
}
let len = self.inode.read_at(self.offset, buf)?; let len = self.inode.read_at(self.offset, buf)?;
self.offset += len; self.offset += len;
Ok(len) Ok(len)
} }
pub fn write(&mut self, buf: &[u8]) -> Result<usize> { pub fn write(&mut self, buf: &[u8]) -> Result<usize> {
assert!(self.writable); if !self.options.write {
return Err(FsError::InvalidParam); // FIXME: => EBADF
}
if self.options.append {
let info = self.inode.metadata()?;
self.offset = info.size;
}
let len = self.inode.write_at(self.offset, buf)?; let len = self.inode.write_at(self.offset, buf)?;
self.offset += len; self.offset += len;
Ok(len) Ok(len)

@ -10,7 +10,7 @@ use crate::arch::driver::ide;
use crate::drivers::{self, AsAny}; use crate::drivers::{self, AsAny};
use crate::drivers::block::virtio_blk::VirtIOBlkDriver; use crate::drivers::block::virtio_blk::VirtIOBlkDriver;
pub use self::file::File; pub use self::file::*;
pub use self::stdio::{STDIN, STDOUT}; pub use self::stdio::{STDIN, STDOUT};
mod file; mod file;

@ -7,7 +7,7 @@ use xmas_elf::{ElfFile, header, program::{Flags, Type}};
use crate::arch::interrupt::{Context, TrapFrame}; use crate::arch::interrupt::{Context, TrapFrame};
use crate::memory::{ByFrame, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet}; use crate::memory::{ByFrame, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet};
use crate::fs::File; use crate::fs::{FileHandle, OpenOptions};
use super::abi::ProcInitInfo; use super::abi::ProcInitInfo;
@ -20,7 +20,7 @@ pub struct Thread {
pub struct Process { pub struct Process {
pub memory_set: MemorySet, pub memory_set: MemorySet,
pub files: BTreeMap<usize, File>, pub files: BTreeMap<usize, FileHandle>,
pub cwd: String, pub cwd: String,
} }
@ -112,9 +112,9 @@ impl Thread {
let kstack = KernelStack::new(); let kstack = KernelStack::new();
let mut files = BTreeMap::new(); let mut files = BTreeMap::new();
files.insert(0, File::new(crate::fs::STDIN.clone(), true, false)); files.insert(0, FileHandle::new(crate::fs::STDIN.clone(), OpenOptions { read: true, write: false, append: false }));
files.insert(1, File::new(crate::fs::STDOUT.clone(), false, true)); files.insert(1, FileHandle::new(crate::fs::STDOUT.clone(), OpenOptions { read: false, write: true, append: false }));
files.insert(2, File::new(crate::fs::STDOUT.clone(), false, true)); files.insert(2, FileHandle::new(crate::fs::STDOUT.clone(), OpenOptions { read: false, write: true, append: false }));
Box::new(Thread { Box::new(Thread {
context: unsafe { context: unsafe {

@ -2,6 +2,8 @@
use super::*; use super::*;
use crate::fs::{ROOT_INODE, OpenOptions};
pub fn sys_read(fd: usize, base: *mut u8, len: usize) -> SysResult { 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();
@ -24,22 +26,44 @@ pub fn sys_write(fd: usize, base: *const u8, len: usize) -> SysResult {
Ok(len as isize) Ok(len as isize)
} }
pub fn sys_open(path: *const u8, flags: 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::Inval)?;
let flags = VfsFlags::from_ucore_flags(flags); let flags = OpenFlags::from_bits_truncate(flags);
info!("open: path: {:?}, flags: {:?}", path, flags); info!("open: path: {:?}, flags: {:?}, mode: {:#o}", path, flags, mode);
let (fd, inode) = match path.as_str() {
"stdin:" => (0, crate::fs::STDIN.clone() as Arc<INode>), let inode =
"stdout:" => (1, crate::fs::STDOUT.clone() as Arc<INode>), if flags.contains(OpenFlags::CREATE) {
_ => { // FIXME: assume path start from root now
let fd = (3..).find(|i| !proc.files.contains_key(i)).unwrap(); let mut split = path.as_str().rsplitn(2, '/');
let inode = crate::fs::ROOT_INODE.lookup(path.as_str())?; let file_name = split.next().unwrap();
(fd, inode) let dir_path = split.next().unwrap_or(".");
let dir_inode = ROOT_INODE.lookup(dir_path)?;
match dir_inode.find(file_name) {
Ok(file_inode) => {
if flags.contains(OpenFlags::EXCLUSIVE) {
return Err(SysError::Exists);
}
file_inode
},
Err(FsError::EntryNotFound) => {
dir_inode.create(file_name, FileType::File, mode as u32)?
}
Err(e) => return Err(SysError::from(e)),
}
} else {
// TODO: remove "stdin:" "stdout:"
match path.as_str() {
"stdin:" => crate::fs::STDIN.clone() as Arc<INode>,
"stdout:" => crate::fs::STDOUT.clone() as Arc<INode>,
_ => ROOT_INODE.lookup(path.as_str())?,
} }
}; };
let file = File::new(inode, flags.contains(VfsFlags::READABLE), flags.contains(VfsFlags::WRITABLE));
let fd = (3..).find(|i| !proc.files.contains_key(i)).unwrap();
let file = FileHandle::new(inode, flags.to_options());
proc.files.insert(fd, file); proc.files.insert(fd, file);
Ok(fd as isize) Ok(fd as isize)
} }
@ -98,30 +122,44 @@ pub fn sys_dup2(fd1: usize, fd2: usize) -> SysResult {
Ok(0) Ok(0)
} }
fn get_file<'a>(proc: &'a mut MutexGuard<'static, Process>, fd: usize) -> Result<&'a mut File, 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::Inval)
} }
bitflags! { bitflags! {
struct VfsFlags: usize { struct OpenFlags: usize {
// WARNING: different from origin uCore /// read only
const READABLE = 1 << 0; const RDONLY = 0;
const WRITABLE = 1 << 1; /// write only
const WRONLY = 1;
/// read write
const RDWR = 2;
/// create file if it does not exist /// create file if it does not exist
const CREATE = 1 << 2; const CREATE = 1 << 6;
/// error if O_CREAT and the file exists /// error if CREATE and the file exists
const EXCLUSIVE = 1 << 3; const EXCLUSIVE = 1 << 7;
/// truncate file upon open /// truncate file upon open
const TRUNCATE = 1 << 4; const TRUNCATE = 1 << 9;
/// append on each write /// append on each write
const APPEND = 1 << 5; const APPEND = 1 << 10;
} }
} }
impl VfsFlags { impl OpenFlags {
fn from_ucore_flags(f: usize) -> Self { fn readable(&self) -> bool {
assert_ne!(f & 0b11, 0b11); let b = self.bits() & 0b11;
Self::from_bits_truncate(f + 1) b == OpenFlags::RDONLY.bits() || b == OpenFlags::RDWR.bits()
}
fn writable(&self) -> bool {
let b = self.bits() & 0b11;
b == OpenFlags::WRONLY.bits() || b == OpenFlags::RDWR.bits()
}
fn to_options(&self) -> OpenOptions {
OpenOptions {
read: self.readable(),
write: self.writable(),
append: self.contains(OpenFlags::APPEND),
}
} }
} }

@ -8,7 +8,7 @@ use rcore_fs::vfs::{FileType, FsError, INode, Metadata};
use spin::{Mutex, MutexGuard}; use spin::{Mutex, MutexGuard};
use crate::arch::interrupt::TrapFrame; use crate::arch::interrupt::TrapFrame;
use crate::fs::File; use crate::fs::FileHandle;
use crate::process::*; use crate::process::*;
use crate::thread; use crate::thread;
use crate::util; use crate::util;
@ -31,7 +31,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
// file // file
000 => sys_read(args[0], args[1] as *mut u8, args[2]), 000 => sys_read(args[0], args[1] as *mut u8, args[2]),
001 => sys_write(args[0], args[1] as *const 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]), 002 => sys_open(args[0] as *const u8, args[1], args[2]),
003 => sys_close(args[0]), 003 => sys_close(args[0]),
// 004 => sys_stat(), // 004 => sys_stat(),
005 => sys_fstat(args[0], args[1] as *mut Stat), 005 => sys_fstat(args[0], args[1] as *mut Stat),
@ -107,7 +107,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
158 => sys_arch_prctl(args[0] as i32, args[1], tf), 158 => sys_arch_prctl(args[0] as i32, args[1], tf),
218 => { 218 => {
warn!("sys_set_tid_address is unimplemented"); warn!("sys_set_tid_address is unimplemented");
Ok(0) Ok(thread::current().id() as isize)
} }
_ => { _ => {
error!("unknown syscall id: {:#x?}, args: {:x?}", id, args); error!("unknown syscall id: {:#x?}, args: {:x?}", id, args);

Loading…
Cancel
Save