From d9c693a31ce09e87171888f6139b746a21b1543b Mon Sep 17 00:00:00 2001 From: Mackenzie Clark Date: Thu, 28 Mar 2019 12:50:37 -0700 Subject: [PATCH] make file like implement the std::io traits instead and wrap zbox file --- lib/runtime-abi/src/vfs/device_file.rs | 73 +++++++++++++++++-------- lib/runtime-abi/src/vfs/file_like.rs | 9 ++- lib/runtime-abi/src/vfs/vfs.rs | 3 +- lib/runtime-abi/src/vfs/virtual_file.rs | 50 +++++++++++------ 4 files changed, 89 insertions(+), 46 deletions(-) diff --git a/lib/runtime-abi/src/vfs/device_file.rs b/lib/runtime-abi/src/vfs/device_file.rs index 5dfdba495..3013d32b2 100644 --- a/lib/runtime-abi/src/vfs/device_file.rs +++ b/lib/runtime-abi/src/vfs/device_file.rs @@ -1,7 +1,6 @@ use crate::vfs::file_like::{FileLike, Metadata}; use failure::Error; use std::io; -use std::io::{Seek, Write}; pub struct Stdin; pub struct Stdout; @@ -12,19 +11,27 @@ impl FileLike for Stdin { unimplemented!() } - fn write_file(&mut self, _buf: &[u8], _offset: usize) -> Result { - unimplemented!() - } - - fn read_file(&mut self, _buf: &mut [u8], _offset: usize) -> Result { - unimplemented!() - } - fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> { panic!("Cannot set length of stdin"); } } +impl io::Read for Stdin { + fn read(&mut self, _buf: &mut [u8]) -> Result { + unimplemented!() + } +} + +impl io::Write for Stdin { + fn write(&mut self, _buf: &[u8]) -> Result { + unimplemented!() + } + + fn flush(&mut self) -> Result<(), io::Error> { + unimplemented!() + } +} + impl io::Seek for Stdin { fn seek(&mut self, _pos: io::SeekFrom) -> Result { unimplemented!() @@ -36,18 +43,28 @@ impl FileLike for Stdout { unimplemented!() } - fn write_file(&mut self, buf: &[u8], _offset: usize) -> Result { + fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> { + panic!("Cannot set length of stdout"); + } +} + +impl io::Read for Stdout { + fn read(&mut self, _buf: &mut [u8]) -> Result { + unimplemented!() + } +} + +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> Result { let stdout = io::stdout(); let mut handle = stdout.lock(); handle.write(buf) } - fn read_file(&mut self, _buf: &mut [u8], _offset: usize) -> Result { - unimplemented!() - } - - fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> { - panic!("Cannot set length of stdout"); + fn flush(&mut self) -> Result<(), io::Error> { + let stdout = io::stdout(); + let mut handle = stdout.lock(); + handle.flush() } } @@ -62,18 +79,28 @@ impl FileLike for Stderr { unimplemented!() } - fn write_file(&mut self, buf: &[u8], _offset: usize) -> Result { + fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> { + panic!("Cannot set length of stderr"); + } +} + +impl io::Read for Stderr { + fn read(&mut self, _buf: &mut [u8]) -> Result { + unimplemented!() + } +} + +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> Result { let stderr = io::stderr(); let mut handle = stderr.lock(); handle.write(buf) } - fn read_file(&mut self, _buf: &mut [u8], _offset: usize) -> Result { - unimplemented!() - } - - fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> { - panic!("Cannot set length of stderr"); + fn flush(&mut self) -> Result<(), io::Error> { + let stderr = io::stderr(); + let mut handle = stderr.lock(); + handle.flush() } } diff --git a/lib/runtime-abi/src/vfs/file_like.rs b/lib/runtime-abi/src/vfs/file_like.rs index 0aee10290..36c734ce3 100644 --- a/lib/runtime-abi/src/vfs/file_like.rs +++ b/lib/runtime-abi/src/vfs/file_like.rs @@ -1,5 +1,3 @@ -use std::io; - pub type Fd = isize; #[derive(Debug)] @@ -8,16 +6,17 @@ pub struct Metadata { pub is_file: bool, } -pub trait FileLike: std::io::Seek { +pub trait FileLike: std::io::Write + std::io::Read + std::io::Seek { // get metadata fn metadata(&self) -> Result; // write - fn write_file(&mut self, buf: &[u8], offset: usize) -> Result; +// fn write_file(&mut self, buf: &[u8]) -> Result; // read - fn read_file(&mut self, buf: &mut [u8], offset: usize) -> Result; +// fn read_file(&mut self, buf: &mut [u8]) -> Result; // set_file_len fn set_file_len(&mut self, len: usize) -> Result<(), failure::Error>; } + diff --git a/lib/runtime-abi/src/vfs/vfs.rs b/lib/runtime-abi/src/vfs/vfs.rs index 83f7173db..bbdeee25f 100644 --- a/lib/runtime-abi/src/vfs/vfs.rs +++ b/lib/runtime-abi/src/vfs/vfs.rs @@ -8,6 +8,7 @@ use std::path::{Path, PathBuf}; use std::rc::Rc; use tar::EntryType; use zbox::{init_env, OpenOptions, Repo, RepoOpener}; +use crate::vfs::virtual_file::VirtualFile; pub struct Vfs { repo: Repo, @@ -103,7 +104,7 @@ impl Vfs { init_env(); let path = convert_to_absolute_path(path); if let Ok(file) = OpenOptions::new().write(true).open(&mut self.repo, &path) { - Some(Rc::new(RefCell::new(file))) + Some(Rc::new(RefCell::new(VirtualFile::new(file)))) } else if let Some(dev_file) = self.device_files.get(&path) { Some(dev_file.clone()) } else { diff --git a/lib/runtime-abi/src/vfs/virtual_file.rs b/lib/runtime-abi/src/vfs/virtual_file.rs index 20bfa097e..097199350 100644 --- a/lib/runtime-abi/src/vfs/virtual_file.rs +++ b/lib/runtime-abi/src/vfs/virtual_file.rs @@ -1,12 +1,16 @@ use failure::Error; - use crate::vfs::file_like::{FileLike, Metadata}; use std::io; -use std::io::{Read, Seek, SeekFrom, Write}; -impl FileLike for zbox::File { +pub struct VirtualFile(zbox::File); + +impl VirtualFile { + pub fn new(file: zbox::File) -> Self { VirtualFile(file) } +} + +impl FileLike for VirtualFile { fn metadata(&self) -> Result { - self.metadata() + self.0.metadata() .map(|m| Metadata { len: m.content_len(), is_file: m.is_file(), @@ -14,19 +18,31 @@ impl FileLike for zbox::File { .map_err(|e: zbox::Error| e.into()) } - fn write_file(&mut self, buf: &[u8], offset: usize) -> Result { - self.seek(SeekFrom::Start(offset as _))?; - let result = self.write(buf); - self.finish().unwrap(); - result - } - - fn read_file(&mut self, buf: &mut [u8], offset: usize) -> Result { - self.seek(io::SeekFrom::Start(offset as u64))?; - self.read(buf) - } - fn set_file_len(&mut self, len: usize) -> Result<(), failure::Error> { - self.set_len(len).map_err(|e| e.into()) + self.0.set_len(len).map_err(|e| e.into()) + } +} + +impl io::Write for VirtualFile { + fn write(&mut self, buf: &[u8]) -> Result { + let result = self.0.write(buf)?; + self.0.finish().unwrap(); + Ok(result) + } + + fn flush(&mut self) -> Result<(), io::Error> { + self.0.flush() + } +} + +impl io::Read for VirtualFile { + fn read(&mut self, buf: &mut [u8]) -> Result { + self.0.read(buf) + } +} + +impl io::Seek for VirtualFile { + fn seek(&mut self, pos: io::SeekFrom) -> Result { + self.0.seek(pos) } }