diff --git a/Cargo.lock b/Cargo.lock index 319e764..553b41a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,6 +69,9 @@ name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] [[package]] name = "byteorder" @@ -214,6 +217,7 @@ checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" name = "file_rpc" version = "0.1.0" dependencies = [ + "bitflags", "parking_lot", "postcard", "serde", diff --git a/src/main.rs b/src/main.rs index e807315..e08286e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,7 +36,7 @@ use std::{ use hba::Hba; use itertools::Itertools; -use parking_lot::Mutex; +use parking_lot::{Mutex, RwLock}; use port::DeviceEnum; use x86_64::structures::paging::PageTableFlags; @@ -44,29 +44,35 @@ use x86_64::structures::paging::PageTableFlags; struct AhciState { hba: Arc>, dev_port_map: Arc>, + files: Arc>>, } impl dev_driver_rpc::Server for AhciState { fn open(&self, path: &Path) -> Result { - Ok(*self.dev_port_map.get(path).ok_or(())? as u64) + let port = *self.dev_port_map.get(path).ok_or(())?; + let mut files = self.files.write(); + files.push((port, 0)); + Ok((files.len() - 1) as u64) } } impl file_rpc::Server for AhciState { #[allow(clippy::significant_drop_tightening)] - fn read(&self, fd: u64, pos: u64, len: usize) -> Result, ()> { + fn read(&self, fd: u64, len: usize) -> Result, ()> { let hba = self.hba.lock(); - let port = hba.ports().get(fd as usize).ok_or(())?; + let (port_no, pos) = self.files.read()[fd as usize]; + let port = hba.ports().get(port_no).ok_or(())?; let device = port.get_device().map_err(|_| ())?.ok_or(())?; let DeviceEnum::Ata(device) = device else { return Err(()); }; let mut buf = vec![0; len]; device.read(pos as usize, &mut buf).map_err(|_| ())?; + self.files.write()[fd as usize].1 += len as u64; Ok(buf.into()) } - fn write(&self, _fd: u64, _pos: u64, _data: &[u8]) -> Result<(), ()> { + fn write(&self, _fd: u64, _data: &[u8]) -> Result<(), ()> { todo!() } @@ -84,7 +90,41 @@ impl file_rpc::Server for AhciState { } fn dup(&self, fd: u64) -> Option { - Some(fd) + let mut files = self.files.write(); + let file = files[fd as usize].clone(); + files.push(file); + Some((files.len() - 1) as u64) + } + + #[allow(clippy::significant_drop_tightening)] + 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.1 = offset; + }, + file_rpc::SeekFrom::End(_offset) => { + todo!(); + //if offset <= 0 { + // file.1 = file.len as u64 - (-offset) as u64; + //} + }, + file_rpc::SeekFrom::Current(offset) => { + if offset > 0 { + //file.1 = u64::min(file.1 + offset as u64, file.len as u64); + file.1 += offset as u64; + } else { + let offset = (-offset) as u64; + if offset > file.1 { + file.1 = 0; + } else { + file.1 -= offset; + } + } + }, + } + file.1 } } @@ -202,6 +242,7 @@ fn main() { let state = AhciState { hba: Arc::new(Mutex::new(hba)), dev_port_map: Arc::new(dev_port_map.clone()), + files: Arc::new(RwLock::new(Vec::new())), }; dev_driver_rpc::register_server(Box::new(state.clone()));