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