mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 08:06:17 +04:00
fix dup
This commit is contained in:
parent
d777f59118
commit
b2e714d68d
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)?,
|
||||
|
@ -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)
|
||||
|
@ -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).
|
||||
|
Loading…
Reference in New Issue
Block a user