2019-02-25 21:44:13 +04:00
|
|
|
//! File handle for process
|
2019-02-22 08:54:42 +04:00
|
|
|
|
|
|
|
use alloc::{string::String, sync::Arc};
|
|
|
|
|
2019-02-25 21:44:13 +04:00
|
|
|
use rcore_fs::vfs::{Metadata, INode, Result, FsError};
|
2019-02-22 08:54:42 +04:00
|
|
|
|
|
|
|
#[derive(Clone)]
|
2019-02-25 21:44:13 +04:00
|
|
|
pub struct FileHandle {
|
2019-02-22 08:54:42 +04:00
|
|
|
inode: Arc<INode>,
|
|
|
|
offset: usize,
|
2019-02-25 21:44:13 +04:00
|
|
|
options: OpenOptions,
|
2019-02-22 08:54:42 +04:00
|
|
|
}
|
|
|
|
|
2019-02-25 21:44:13 +04:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct OpenOptions {
|
|
|
|
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,
|
|
|
|
}
|
2019-02-22 08:54:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
2019-02-25 21:44:13 +04:00
|
|
|
if !self.options.read {
|
|
|
|
return Err(FsError::InvalidParam); // FIXME: => EBADF
|
|
|
|
}
|
2019-02-22 08:54:42 +04:00
|
|
|
let len = self.inode.read_at(self.offset, buf)?;
|
|
|
|
self.offset += len;
|
|
|
|
Ok(len)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
2019-02-25 21:44:13 +04:00
|
|
|
if !self.options.write {
|
|
|
|
return Err(FsError::InvalidParam); // FIXME: => EBADF
|
|
|
|
}
|
|
|
|
if self.options.append {
|
|
|
|
let info = self.inode.metadata()?;
|
|
|
|
self.offset = info.size;
|
|
|
|
}
|
2019-02-22 08:54:42 +04:00
|
|
|
let len = self.inode.write_at(self.offset, buf)?;
|
|
|
|
self.offset += len;
|
|
|
|
Ok(len)
|
|
|
|
}
|
|
|
|
|
2019-02-22 13:10:07 +04:00
|
|
|
pub fn info(&self) -> Result<Metadata> {
|
|
|
|
self.inode.metadata()
|
2019-02-22 08:54:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_entry(&self, id: usize) -> Result<String> {
|
|
|
|
self.inode.get_entry(id)
|
|
|
|
}
|
|
|
|
}
|