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

View File

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