1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 16:16:16 +04:00
This commit is contained in:
function2-llx 2020-04-12 18:52:21 +08:00
parent d777f59118
commit b2e714d68d
4 changed files with 56 additions and 18 deletions

View File

@ -11,15 +11,29 @@ use rcore_fs::vfs::{FileType, FsError, INode, MMapArea, Metadata, PollStatus, Re
use rcore_memory::memory_set::handler::File;
use rcore_fs::vfs::FsError::NotSupported;
#[derive(Clone)]
use crate::sync::SpinLock as Mutex;
pub struct FileHandle {
inode: Arc<dyn INode>,
offset: u64,
offset: Arc<Mutex<u64>>,
pub options: OpenOptions,
pub path: String,
pub fd_cloexec: bool,
}
impl Clone for FileHandle {
// do not share offset
fn clone(&self) -> Self {
FileHandle {
inode: self.inode.clone(),
offset: Arc::new(Mutex::new(*self.offset.lock())),
options: self.options.clone(),
path: self.path.clone(),
fd_cloexec: self.fd_cloexec,
}
}
}
#[derive(Debug, Clone)]
pub struct OpenOptions {
pub read: bool,
@ -40,16 +54,29 @@ impl FileHandle {
pub fn new(inode: Arc<dyn INode>, options: OpenOptions, path: String) -> Self {
return FileHandle {
inode,
offset: 0,
offset: Arc::new(Mutex::new(0)),
options,
path,
fd_cloexec: false,
};
}
// do as default clone does, share the offset
pub fn dup(&self) -> Self {
FileHandle {
inode: self.inode.clone(),
offset: self.offset.clone(),
options: self.options.clone(),
path: self.path.clone(),
fd_cloexec: self.fd_cloexec,
}
}
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let len = self.read_at(self.offset as usize, buf)?;
self.offset += len as u64;
// let mut offset_inner = self.offset.lock();
let offset = *self.offset.lock() as usize;
let len = self.read_at(offset, buf)?;
*self.offset.lock() += len as u64;
Ok(len)
}
@ -81,10 +108,10 @@ impl FileHandle {
pub fn write(&mut self, buf: &[u8]) -> Result<usize> {
let offset = match self.options.append {
true => self.inode.metadata()?.size as u64,
false => self.offset,
false => *self.offset.lock(),
} as usize;
let len = self.write_at(offset, buf)?;
self.offset = (offset + len) as u64;
*self.offset.lock() += len as u64;
Ok(len)
}
@ -97,12 +124,13 @@ impl FileHandle {
}
pub fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
self.offset = match pos {
let mut offset_inner = self.offset.lock();
*offset_inner = match pos {
SeekFrom::Start(offset) => offset,
SeekFrom::End(offset) => (self.inode.metadata()?.size as i64 + offset) as u64,
SeekFrom::Current(offset) => (self.offset as i64 + offset) as u64,
SeekFrom::Current(offset) => (*offset_inner as i64 + offset) as u64,
};
Ok(self.offset)
Ok(*offset_inner)
}
pub fn set_len(&mut self, len: u64) -> Result<()> {
@ -133,8 +161,9 @@ impl FileHandle {
if !self.options.read {
return Err(FsError::InvalidParam); // FIXME: => EBADF
}
let name = self.inode.get_entry(self.offset as usize)?;
self.offset += 1;
let mut offset_inner = self.offset.lock();
let name = self.inode.get_entry(*offset_inner as usize)?;
*offset_inner += 1;
Ok(name)
}

View File

@ -18,6 +18,15 @@ pub enum FileLike {
}
impl FileLike {
pub fn dup(&self) -> FileLike {
use FileLike::File;
if let File(file) = self {
File(file.dup())
} else {
self.clone()
}
}
pub fn read(&mut self, buf: &mut [u8]) -> SysResult {
let len = match self {
FileLike::File(file) => file.read(buf)?,

View File

@ -130,7 +130,7 @@ impl Drop for KernelStack {
/// Handle page fault at `addr`.
/// Return true to continue, false to halt.
pub fn handle_page_fault(addr: usize) -> bool {
debug!("page fault @ {:#x}", addr);
// debug!("page fault @ {:#x}", addr);
let thread = unsafe { current_thread() };
thread.vm.lock().handle_page_fault(addr)

View File

@ -41,10 +41,10 @@ impl Syscall<'_> {
pub fn sys_write(&mut self, fd: usize, base: *const u8, len: usize) -> SysResult {
let mut proc = self.process();
if !proc.pid.is_init() {
// we trust pid 0 process
info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
}
// if !proc.pid.is_init() {
// we trust pid 0 process
info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
// }
let slice = unsafe { self.vm().check_read_array(base, len)? };
let file_like = proc.get_file_like(fd)?;
let len = file_like.write(slice)?;
@ -778,7 +778,7 @@ impl Syscall<'_> {
// close fd2 first if it is opened
proc.files.remove(&fd2);
let mut file_like = proc.get_file_like(fd1)?.clone();
let mut file_like = proc.get_file_like(fd1)?.dup();
if let FileLike::File(file) = &mut file_like {
// The two file descriptors do not share file descriptor flags (the
// close-on-exec flag).