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
|
||||
/// on closing are ignored by the implementation of `Drop`.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct File {
|
||||
inode: Inode,
|
||||
block_size: usize,
|
||||
|
66
src/main.rs
66
src/main.rs
@ -4,17 +4,24 @@ use std::{
|
||||
borrow::Cow,
|
||||
fs::File,
|
||||
os::mikros::{ipc, syscalls},
|
||||
sync::Arc,
|
||||
sync::Arc, usize,
|
||||
};
|
||||
|
||||
use ext2::Ext2;
|
||||
use itertools::Itertools;
|
||||
use parking_lot::RwLock;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct OpenFile {
|
||||
file: ext2::File,
|
||||
pos: u64,
|
||||
mount_id: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Serv {
|
||||
mounts: Arc<RwLock<Vec<Ext2>>>,
|
||||
files: Arc<RwLock<Vec<(ext2::File, usize)>>>,
|
||||
files: Arc<RwLock<Vec<OpenFile>>>,
|
||||
dirs: Arc<RwLock<Vec<(Vec<String>, usize)>>>,
|
||||
}
|
||||
|
||||
@ -31,7 +38,11 @@ impl fs_rpc::Server for Serv {
|
||||
let mounts = self.mounts.read();
|
||||
let mount = &mounts[mount_id as usize];
|
||||
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));
|
||||
res
|
||||
}
|
||||
@ -49,18 +60,20 @@ impl fs_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 (file, mount_id) = &files[fd as usize];
|
||||
let file = &files[fd as usize];
|
||||
let mounts = self.mounts.read();
|
||||
let mount = &mounts[*mount_id];
|
||||
let mount = &mounts[file.mount_id];
|
||||
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);
|
||||
std::mem::drop(files);
|
||||
self.files.write()[fd as usize].pos += read_len as u64;
|
||||
Ok(buf.into())
|
||||
}
|
||||
|
||||
fn write(&self, _fd: u64, _pos: u64, _data: &[u8]) -> Result<(), ()> {
|
||||
fn write(&self, _fd: u64, _data: &[u8]) -> Result<(), ()> {
|
||||
Err(())
|
||||
}
|
||||
|
||||
@ -68,12 +81,43 @@ impl file_rpc::Server for Serv {
|
||||
|
||||
fn size(&self, fd: u64) -> Option<u64> {
|
||||
let files = self.files.read();
|
||||
let (file, _mount_id) = &files[fd as usize];
|
||||
Some(file.metadata().len())
|
||||
let file = &files[fd as usize];
|
||||
Some(file.file.metadata().len())
|
||||
}
|
||||
|
||||
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