add sys_pread, sys_pwrite

This commit is contained in:
WangRunji 2019-03-19 23:17:42 +08:00 committed by Tate Tian
parent c1c61c4e21
commit fc145097b2
5 changed files with 134 additions and 35 deletions

@ -2,12 +2,15 @@ use super::*;
use std;
use std::borrow::BorrowMut;
use std::fmt;
use std::io::SeekFrom;
pub trait File: Debug + Sync + Send {
fn read(&self, buf: &mut [u8]) -> Result<usize, Error>;
fn write(&self, buf: &[u8]) -> Result<usize, Error>;
fn readv<'a, 'b>(&self, bufs: &'a mut [&'b mut [u8]]) -> Result<usize, Error>;
fn writev<'a, 'b>(&self, bufs: &'a [&'b [u8]]) -> Result<usize, Error>;
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, Error>;
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize, Error>;
fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize, Error>;
fn writev(&self, bufs: &[&[u8]]) -> Result<usize, Error>;
fn seek(&self, pos: SeekFrom) -> Result<off_t, Error>;
fn metadata(&self) -> Result<Metadata, Error>;
fn set_len(&self, len: u64) -> Result<(), Error>;
@ -60,13 +63,27 @@ impl File for SgxFile {
inner.write(buf)
}
fn readv<'a, 'b>(&self, bufs: &'a mut [&'b mut [u8]]) -> Result<usize, Error> {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, Error> {
let mut inner_guard = self.inner.lock().unwrap();
let inner = inner_guard.borrow_mut();
inner.seek(SeekFrom::Start(offset as u64))?;
inner.read(buf)
}
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize, Error> {
let mut inner_guard = self.inner.lock().unwrap();
let inner = inner_guard.borrow_mut();
inner.seek(SeekFrom::Start(offset as u64))?;
inner.write(buf)
}
fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize, Error> {
let mut inner_guard = self.inner.lock().unwrap();
let inner = inner_guard.borrow_mut();
inner.readv(bufs)
}
fn writev<'a, 'b>(&self, bufs: &'a [&'b [u8]]) -> Result<usize, Error> {
fn writev(&self, bufs: &[&[u8]]) -> Result<usize, Error> {
let mut inner_guard = self.inner.lock().unwrap();
let inner = inner_guard.borrow_mut();
inner.writev(bufs)
@ -287,6 +304,10 @@ impl StdoutFile {
}
impl File for StdoutFile {
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
Err(Error::new(Errno::EBADF, "Stdout does not support read"))
}
fn write(&self, buf: &[u8]) -> Result<usize, Error> {
let write_len = {
self.inner
@ -297,11 +318,19 @@ impl File for StdoutFile {
Ok(write_len)
}
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, Error> {
unimplemented!()
}
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize, Error> {
unimplemented!()
}
fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize, Error> {
Err(Error::new(Errno::EBADF, "Stdout does not support read"))
}
fn writev<'a, 'b>(&self, bufs: &'a [&'b [u8]]) -> Result<usize, Error> {
fn writev(&self, bufs: &[&[u8]]) -> Result<usize, Error> {
let mut guard = self.inner.lock();
let mut total_bytes = 0;
for buf in bufs {
@ -325,10 +354,6 @@ impl File for StdoutFile {
Ok(total_bytes)
}
fn readv<'a, 'b>(&self, bufs: &'a mut [&'b mut [u8]]) -> Result<usize, Error> {
Err(Error::new(Errno::EBADF, "Stdout does not support read"))
}
fn seek(&self, seek_pos: SeekFrom) -> Result<off_t, Error> {
Err(Error::new(Errno::ESPIPE, "Stdout does not support seek"))
}
@ -390,11 +415,15 @@ impl File for StdinFile {
Err(Error::new(Errno::EBADF, "Stdin does not support write"))
}
fn seek(&self, pos: SeekFrom) -> Result<off_t, Error> {
Err(Error::new(Errno::ESPIPE, "Stdin does not support seek"))
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, Error> {
unimplemented!()
}
fn readv<'a, 'b>(&self, bufs: &'a mut [&'b mut [u8]]) -> Result<usize, Error> {
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize, Error> {
unimplemented!()
}
fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize, Error> {
let mut guard = self.inner.lock();
let mut total_bytes = 0;
for buf in bufs {
@ -418,10 +447,14 @@ impl File for StdinFile {
Ok(total_bytes)
}
fn writev<'a, 'b>(&self, bufs: &'a [&'b [u8]]) -> Result<usize, Error> {
fn writev(&self, bufs: &[&[u8]]) -> Result<usize, Error> {
Err(Error::new(Errno::EBADF, "Stdin does not support write"))
}
fn seek(&self, pos: SeekFrom) -> Result<off_t, Error> {
Err(Error::new(Errno::ESPIPE, "Stdin does not support seek"))
}
fn metadata(&self) -> Result<Metadata, Error> {
unimplemented!()
}

@ -53,6 +53,23 @@ impl File for INodeFile {
Ok(len)
}
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, Error> {
if !self.options.read {
return Err(Error::new(Errno::EBADF, "File not readable"));
}
let len = self.inode.read_at(offset, buf)?;
Ok(len)
}
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize, Error> {
if !self.options.write {
return Err(Error::new(Errno::EBADF, "File not writable"));
}
let len = self.inode.write_at(offset, buf)?;
Ok(len)
}
fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize, Error> {
Err(Error::new(Errno::ENOSYS, "Not implemented"))
}

@ -75,20 +75,34 @@ pub fn do_read(fd: FileDesc, buf: &mut [u8]) -> Result<usize, Error> {
file_ref.read(buf)
}
pub fn do_writev<'a, 'b>(fd: FileDesc, bufs: &'a [&'b [u8]]) -> Result<usize, Error> {
pub fn do_writev(fd: FileDesc, bufs: &[&[u8]]) -> Result<usize, Error> {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().get(fd)?;
file_ref.writev(bufs)
}
pub fn do_readv<'a, 'b>(fd: FileDesc, bufs: &'a mut [&'b mut [u8]]) -> Result<usize, Error> {
pub fn do_readv(fd: FileDesc, bufs: &mut [&mut [u8]]) -> Result<usize, Error> {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().get(fd)?;
file_ref.readv(bufs)
}
pub fn do_pwrite(fd: FileDesc, buf: &[u8], offset: usize) -> Result<usize, Error> {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().get(fd)?;
file_ref.write_at(offset, buf)
}
pub fn do_pread(fd: FileDesc, buf: &mut [u8], offset: usize) -> Result<usize, Error> {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().get(fd)?;
file_ref.read_at(offset, buf)
}
pub fn do_stat(path: &str) -> Result<Stat, Error> {
warn!("stat is partial implemented as lstat");
do_lstat(path)
@ -114,7 +128,7 @@ pub fn do_lstat(path: &str) -> Result<Stat, Error> {
Ok(stat)
}
pub fn do_lseek<'a, 'b>(fd: FileDesc, offset: SeekFrom) -> Result<off_t, Error> {
pub fn do_lseek(fd: FileDesc, offset: SeekFrom) -> Result<off_t, Error> {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().get(fd)?;

@ -36,7 +36,22 @@ impl File for PipeReader {
ringbuf.read(buf)
}
fn readv<'a, 'b>(&self, bufs: &'a mut [&'b mut [u8]]) -> Result<usize, Error> {
fn write(&self, buf: &[u8]) -> Result<usize, Error> {
Err(Error::new(
Errno::EBADF,
"PipeReader does not support write",
))
}
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, Error> {
unimplemented!()
}
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize, Error> {
unimplemented!()
}
fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize, Error> {
let mut ringbuf = self.inner.lock().unwrap();
let mut total_bytes = 0;
for buf in bufs {
@ -60,14 +75,7 @@ impl File for PipeReader {
Ok(total_bytes)
}
fn write(&self, buf: &[u8]) -> Result<usize, Error> {
Err(Error::new(
Errno::EBADF,
"PipeReader does not support write",
))
}
fn writev<'a, 'b>(&self, bufs: &'a [&'b [u8]]) -> Result<usize, Error> {
fn writev(&self, bufs: &[&[u8]]) -> Result<usize, Error> {
Err(Error::new(
Errno::EBADF,
"PipeReader does not support write",
@ -108,12 +116,27 @@ pub struct PipeWriter {
}
impl File for PipeWriter {
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
Err(Error::new(Errno::EBADF, "PipeWriter does not support read"))
}
fn write(&self, buf: &[u8]) -> Result<usize, Error> {
let ringbuf = self.inner.lock().unwrap();
ringbuf.write(buf)
}
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, Error> {
unimplemented!()
}
fn writev<'a, 'b>(&self, bufs: &'a [&'b [u8]]) -> Result<usize, Error> {
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize, Error> {
unimplemented!()
}
fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize, Error> {
Err(Error::new(Errno::EBADF, "PipeWriter does not support read"))
}
fn writev(&self, bufs: &[&[u8]]) -> Result<usize, Error> {
let ringbuf = self.inner.lock().unwrap();
let mut total_bytes = 0;
for buf in bufs {
@ -137,14 +160,6 @@ impl File for PipeWriter {
Ok(total_bytes)
}
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
Err(Error::new(Errno::EBADF, "PipeWriter does not support read"))
}
fn readv<'a, 'b>(&self, bufs: &'a mut [&'b mut [u8]]) -> Result<usize, Error> {
Err(Error::new(Errno::EBADF, "PipeWriter does not support read"))
}
fn seek(&self, seek_pos: SeekFrom) -> Result<off_t, Error> {
Err(Error::new(Errno::ESPIPE, "Pipe does not support seek"))
}

@ -34,6 +34,8 @@ pub extern "C" fn dispatch_syscall(
SYS_CLOSE => do_close(arg0 as FileDesc),
SYS_READ => do_read(arg0 as FileDesc, arg1 as *mut u8, arg2 as usize),
SYS_WRITE => do_write(arg0 as FileDesc, arg1 as *const u8, arg2 as usize),
SYS_PREAD64 => do_pread(arg0 as FileDesc, arg1 as *mut u8, arg2 as usize, arg3 as usize),
SYS_PWRITE64 => do_pwrite(arg0 as FileDesc, arg1 as *const u8, arg2 as usize, arg3 as usize),
SYS_READV => do_readv(arg0 as FileDesc, arg1 as *mut iovec_t, arg2 as i32),
SYS_WRITEV => do_writev(arg0 as FileDesc, arg1 as *mut iovec_t, arg2 as i32),
SYS_STAT => do_stat(arg0 as *const i8, arg1 as *mut fs::Stat),
@ -250,6 +252,24 @@ fn do_readv(fd: FileDesc, iov: *mut iovec_t, count: i32) -> Result<isize, Error>
Ok(len as isize)
}
fn do_pread(fd: FileDesc, buf: *mut u8, size: usize, offset: usize) -> Result<isize, Error> {
let safe_buf = {
check_mut_array(buf, size)?;
unsafe { std::slice::from_raw_parts_mut(buf, size) }
};
let len = fs::do_pread(fd, safe_buf, offset)?;
Ok(len as isize)
}
fn do_pwrite(fd: FileDesc, buf: *const u8, size: usize, offset: usize) -> Result<isize, Error> {
let safe_buf = {
check_array(buf, size)?;
unsafe { std::slice::from_raw_parts(buf, size) }
};
let len = fs::do_pwrite(fd, safe_buf, offset)?;
Ok(len as isize)
}
fn do_stat(path: *const i8, stat_buf: *mut fs::Stat) -> Result<isize, Error> {
let path = clone_cstring_safely(path)?.to_string_lossy().into_owned();
check_mut_ptr(stat_buf)?;