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

@ -53,6 +53,23 @@ impl File for INodeFile {
Ok(len) 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> { fn readv(&self, bufs: &mut [&mut [u8]]) -> Result<usize, Error> {
Err(Error::new(Errno::ENOSYS, "Not implemented")) 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) 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_ref = process::get_current();
let current_process = current_ref.lock().unwrap(); let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().get(fd)?; let file_ref = current_process.get_files().get(fd)?;
file_ref.writev(bufs) 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_ref = process::get_current();
let current_process = current_ref.lock().unwrap(); let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().get(fd)?; let file_ref = current_process.get_files().get(fd)?;
file_ref.readv(bufs) 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> { pub fn do_stat(path: &str) -> Result<Stat, Error> {
warn!("stat is partial implemented as lstat"); warn!("stat is partial implemented as lstat");
do_lstat(path) do_lstat(path)
@ -114,7 +128,7 @@ pub fn do_lstat(path: &str) -> Result<Stat, Error> {
Ok(stat) 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_ref = process::get_current();
let current_process = current_ref.lock().unwrap(); let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().get(fd)?; let file_ref = current_process.get_files().get(fd)?;

@ -36,7 +36,22 @@ impl File for PipeReader {
ringbuf.read(buf) 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 ringbuf = self.inner.lock().unwrap();
let mut total_bytes = 0; let mut total_bytes = 0;
for buf in bufs { for buf in bufs {
@ -60,14 +75,7 @@ impl File for PipeReader {
Ok(total_bytes) Ok(total_bytes)
} }
fn write(&self, buf: &[u8]) -> Result<usize, Error> { fn writev(&self, bufs: &[&[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> {
Err(Error::new( Err(Error::new(
Errno::EBADF, Errno::EBADF,
"PipeReader does not support write", "PipeReader does not support write",
@ -108,12 +116,27 @@ pub struct PipeWriter {
} }
impl File for 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> { fn write(&self, buf: &[u8]) -> Result<usize, Error> {
let ringbuf = self.inner.lock().unwrap(); let ringbuf = self.inner.lock().unwrap();
ringbuf.write(buf) 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 ringbuf = self.inner.lock().unwrap();
let mut total_bytes = 0; let mut total_bytes = 0;
for buf in bufs { for buf in bufs {
@ -137,14 +160,6 @@ impl File for PipeWriter {
Ok(total_bytes) 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> { fn seek(&self, seek_pos: SeekFrom) -> Result<off_t, Error> {
Err(Error::new(Errno::ESPIPE, "Pipe does not support seek")) 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_CLOSE => do_close(arg0 as FileDesc),
SYS_READ => do_read(arg0 as FileDesc, arg1 as *mut u8, arg2 as usize), 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_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_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_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), 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) 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> { 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(); let path = clone_cstring_safely(path)?.to_string_lossy().into_owned();
check_mut_ptr(stat_buf)?; check_mut_ptr(stat_buf)?;