Add seek function

This commit is contained in:
pjht 2024-09-30 13:32:49 -05:00
parent 04bb2e97c6
commit 55de5d8841
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A
2 changed files with 56 additions and 12 deletions

View File

@ -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,

View File

@ -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
}
}