mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-26 11:23:37 +04:00
105 lines
2.3 KiB
Rust
105 lines
2.3 KiB
Rust
|
use easy_fs::{
|
||
|
EasyFileSystem,
|
||
|
Inode,
|
||
|
};
|
||
|
use crate::drivers::BLOCK_DEVICE;
|
||
|
use alloc::sync::Arc;
|
||
|
use lazy_static::*;
|
||
|
use bitflags::*;
|
||
|
use alloc::vec::Vec;
|
||
|
use spin::Mutex;
|
||
|
|
||
|
pub struct OSInode {
|
||
|
readable: bool,
|
||
|
writable: bool,
|
||
|
inner: Mutex<OSInodeInner>,
|
||
|
}
|
||
|
|
||
|
pub struct OSInodeInner {
|
||
|
offset: usize,
|
||
|
inode: Arc<Inode>,
|
||
|
}
|
||
|
|
||
|
impl OSInode {
|
||
|
pub fn new(
|
||
|
readable: bool,
|
||
|
writable: bool,
|
||
|
inode: Arc<Inode>,
|
||
|
) -> Self {
|
||
|
Self {
|
||
|
readable,
|
||
|
writable,
|
||
|
inner: Mutex::new(OSInodeInner {
|
||
|
offset: 0,
|
||
|
inode,
|
||
|
}),
|
||
|
}
|
||
|
}
|
||
|
pub fn read_all(&self) -> Vec<u8> {
|
||
|
let mut inner = self.inner.lock();
|
||
|
let mut buffer = [0u8; 512];
|
||
|
let mut v: Vec<u8> = Vec::new();
|
||
|
loop {
|
||
|
let len = inner.inode.read_at(inner.offset, &mut buffer);
|
||
|
if len == 0 {
|
||
|
break;
|
||
|
}
|
||
|
inner.offset += len;
|
||
|
v.extend_from_slice(&buffer[..len]);
|
||
|
}
|
||
|
v
|
||
|
}
|
||
|
}
|
||
|
|
||
|
lazy_static! {
|
||
|
pub static ref ROOT_INODE: Arc<Inode> = {
|
||
|
let efs = EasyFileSystem::open(BLOCK_DEVICE.clone());
|
||
|
Arc::new(EasyFileSystem::root_inode(&efs))
|
||
|
};
|
||
|
}
|
||
|
|
||
|
pub fn list_apps() {
|
||
|
println!("/**** APPS ****");
|
||
|
for app in ROOT_INODE.ls() {
|
||
|
println!("{}", app);
|
||
|
}
|
||
|
println!("**************/")
|
||
|
}
|
||
|
|
||
|
bitflags! {
|
||
|
pub struct OpenFlags: u32 {
|
||
|
const RDONLY = 0;
|
||
|
const WRONLY = 1 << 0;
|
||
|
const RDWR = 1 << 1;
|
||
|
const CREATE = 1 << 9;
|
||
|
const TRUNC = 1 << 10;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl OpenFlags {
|
||
|
/// Do not check validity for simplicity
|
||
|
/// Return (readable, writable)
|
||
|
pub fn read_write(&self) -> (bool, bool) {
|
||
|
if self.is_empty() {
|
||
|
(true, false)
|
||
|
} else if self.contains(Self::WRONLY) {
|
||
|
(false, true)
|
||
|
} else {
|
||
|
(true, true)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn open_file(name: &str, flags: OpenFlags) -> Option<Arc<OSInode>> {
|
||
|
let (readable, writable) = flags.read_write();
|
||
|
// TODO: do not support CREATE or TRUNC flags now
|
||
|
ROOT_INODE.find(name)
|
||
|
.map(|inode| {
|
||
|
Arc::new(OSInode::new(
|
||
|
readable,
|
||
|
writable,
|
||
|
inode
|
||
|
))
|
||
|
})
|
||
|
}
|