Add seek function
This commit is contained in:
parent
04bb2e97c6
commit
55de5d8841
@ -11,7 +11,7 @@ use std::io::{self, Read};
|
|||||||
///
|
///
|
||||||
/// Files are automatically closed when they go out of scope. Errors detected
|
/// Files are automatically closed when they go out of scope. Errors detected
|
||||||
/// on closing are ignored by the implementation of `Drop`.
|
/// on closing are ignored by the implementation of `Drop`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct File {
|
pub struct File {
|
||||||
inode: Inode,
|
inode: Inode,
|
||||||
block_size: usize,
|
block_size: usize,
|
||||||
|
66
src/main.rs
66
src/main.rs
@ -4,17 +4,24 @@ use std::{
|
|||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
fs::File,
|
fs::File,
|
||||||
os::mikros::{ipc, syscalls},
|
os::mikros::{ipc, syscalls},
|
||||||
sync::Arc,
|
sync::Arc, usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ext2::Ext2;
|
use ext2::Ext2;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct OpenFile {
|
||||||
|
file: ext2::File,
|
||||||
|
pos: u64,
|
||||||
|
mount_id: usize,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Serv {
|
struct Serv {
|
||||||
mounts: Arc<RwLock<Vec<Ext2>>>,
|
mounts: Arc<RwLock<Vec<Ext2>>>,
|
||||||
files: Arc<RwLock<Vec<(ext2::File, usize)>>>,
|
files: Arc<RwLock<Vec<OpenFile>>>,
|
||||||
dirs: Arc<RwLock<Vec<(Vec<String>, usize)>>>,
|
dirs: Arc<RwLock<Vec<(Vec<String>, usize)>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +38,11 @@ impl fs_rpc::Server for Serv {
|
|||||||
let mounts = self.mounts.read();
|
let mounts = self.mounts.read();
|
||||||
let mount = &mounts[mount_id as usize];
|
let mount = &mounts[mount_id as usize];
|
||||||
let file = mount.open(path).map_err(|_| ())?;
|
let file = mount.open(path).map_err(|_| ())?;
|
||||||
self.files.write().push((file, mount_id as usize));
|
self.files.write().push(OpenFile {
|
||||||
|
file,
|
||||||
|
pos: 0,
|
||||||
|
mount_id: mount_id as usize
|
||||||
|
});
|
||||||
let res = Ok((None, (self.files.read().len() - 1) as u64));
|
let res = Ok((None, (self.files.read().len() - 1) as u64));
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
@ -49,18 +60,20 @@ impl fs_rpc::Server for Serv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl file_rpc::Server for Serv {
|
impl file_rpc::Server for Serv {
|
||||||
fn read(&self, fd: u64, pos: u64, len: usize) -> Result<Cow<'_, [u8]>, ()> {
|
fn read(&self, fd: u64, len: usize) -> Result<Cow<'_, [u8]>, ()> {
|
||||||
let files = self.files.read();
|
let files = self.files.read();
|
||||||
let (file, mount_id) = &files[fd as usize];
|
let file = &files[fd as usize];
|
||||||
let mounts = self.mounts.read();
|
let mounts = self.mounts.read();
|
||||||
let mount = &mounts[*mount_id];
|
let mount = &mounts[file.mount_id];
|
||||||
let mut buf = vec![0; len];
|
let mut buf = vec![0; len];
|
||||||
let read_len = file.read_at(&mut buf, pos, mount).map_err(|_| ())?;
|
let read_len = file.file.read_at(&mut buf, file.pos, mount).map_err(|_| ())?;
|
||||||
buf.truncate(read_len);
|
buf.truncate(read_len);
|
||||||
|
std::mem::drop(files);
|
||||||
|
self.files.write()[fd as usize].pos += read_len as u64;
|
||||||
Ok(buf.into())
|
Ok(buf.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, _fd: u64, _pos: u64, _data: &[u8]) -> Result<(), ()> {
|
fn write(&self, _fd: u64, _data: &[u8]) -> Result<(), ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,12 +81,43 @@ impl file_rpc::Server for Serv {
|
|||||||
|
|
||||||
fn size(&self, fd: u64) -> Option<u64> {
|
fn size(&self, fd: u64) -> Option<u64> {
|
||||||
let files = self.files.read();
|
let files = self.files.read();
|
||||||
let (file, _mount_id) = &files[fd as usize];
|
let file = &files[fd as usize];
|
||||||
Some(file.metadata().len())
|
Some(file.file.metadata().len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dup(&self, fd: u64) -> Option<u64> {
|
fn dup(&self, fd: u64) -> Option<u64> {
|
||||||
Some(fd)
|
let mut files = self.files.write();
|
||||||
|
let file = files[fd as usize].clone();
|
||||||
|
files.push(file);
|
||||||
|
Some((files.len() - 1) as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seek(&self, fd: u64, pos: file_rpc::SeekFrom) -> u64 {
|
||||||
|
let mut files = self.files.write();
|
||||||
|
let file = &mut files[fd as usize];
|
||||||
|
match pos {
|
||||||
|
file_rpc::SeekFrom::Start(offset) => {
|
||||||
|
file.pos = offset;
|
||||||
|
},
|
||||||
|
file_rpc::SeekFrom::End(offset) => {
|
||||||
|
if offset <= 0 {
|
||||||
|
file.pos = file.file.metadata().len() - (-offset) as u64;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
file_rpc::SeekFrom::Current(offset) => {
|
||||||
|
if offset > 0 {
|
||||||
|
file.pos = u64::min(file.pos + offset as u64, file.file.metadata().len());
|
||||||
|
} else {
|
||||||
|
let offset = (-offset) as u64;
|
||||||
|
if offset > file.pos {
|
||||||
|
file.pos = 0;
|
||||||
|
} else {
|
||||||
|
file.pos -= offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
file.pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user