add sys_pread, sys_pwrite
This commit is contained in:
parent
c1c61c4e21
commit
fc145097b2
@ -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)?;
|
||||
|
Loading…
Reference in New Issue
Block a user