about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-04-30 03:28:35 +0200
committerGitHub <noreply@github.com>2019-04-30 03:28:35 +0200
commitc54b77ca2da2584608a74eacdc78739e5e168456 (patch)
tree48659169d808b9e5b7f8d95829466c790f46de68 /src/libstd/sys
parent00859e3e653973120006aaf3227823062dde1ba7 (diff)
parent09f4008da5ecee74fe06d8fd78ac39064e300512 (diff)
downloadrust-c54b77ca2da2584608a74eacdc78739e5e168456.tar.gz
rust-c54b77ca2da2584608a74eacdc78739e5e168456.zip
Rollup merge of #59869 - jethrogb:jb/sgx-iovec, r=sfackler
SGX target: implemented vectored I/O

r? @sfackler

Includes #59857
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/sgx/abi/usercalls/alloc.rs12
-rw-r--r--src/libstd/sys/sgx/abi/usercalls/mod.rs45
-rw-r--r--src/libstd/sys/sgx/fd.rs14
-rw-r--r--src/libstd/sys/sgx/net.rs4
4 files changed, 60 insertions, 15 deletions
diff --git a/src/libstd/sys/sgx/abi/usercalls/alloc.rs b/src/libstd/sys/sgx/abi/usercalls/alloc.rs
index 22ae2a8e07d..38e05f6fd27 100644
--- a/src/libstd/sys/sgx/abi/usercalls/alloc.rs
+++ b/src/libstd/sys/sgx/abi/usercalls/alloc.rs
@@ -523,7 +523,11 @@ impl<T, I: SliceIndex<[T]>> Index<I> for UserRef<[T]> where [T]: UserSafe, I::Ou
     #[inline]
     fn index(&self, index: I) -> &UserRef<I::Output> {
         unsafe {
-            UserRef::from_ptr(index.index(&*self.as_raw_ptr()))
+            if let Some(slice) = index.get(&*self.as_raw_ptr()) {
+                UserRef::from_ptr(slice)
+            } else {
+                rtabort!("index out of range for user slice");
+            }
         }
     }
 }
@@ -533,7 +537,11 @@ impl<T, I: SliceIndex<[T]>> IndexMut<I> for UserRef<[T]> where [T]: UserSafe, I:
     #[inline]
     fn index_mut(&mut self, index: I) -> &mut UserRef<I::Output> {
         unsafe {
-            UserRef::from_mut_ptr(index.index_mut(&mut*self.as_raw_mut_ptr()))
+            if let Some(slice) = index.get_mut(&mut*self.as_raw_mut_ptr()) {
+                UserRef::from_mut_ptr(slice)
+            } else {
+                rtabort!("index out of range for user slice");
+            }
         }
     }
 }
diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs
index 0abfc26bced..fca62e028de 100644
--- a/src/libstd/sys/sgx/abi/usercalls/mod.rs
+++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs
@@ -1,4 +1,5 @@
-use crate::io::{Error as IoError, Result as IoResult};
+use crate::cmp;
+use crate::io::{Error as IoError, Result as IoResult, IoSlice, IoSliceMut};
 use crate::time::Duration;
 
 pub(crate) mod alloc;
@@ -8,13 +9,27 @@ pub(crate) mod raw;
 use self::raw::*;
 
 /// Usercall `read`. See the ABI documentation for more information.
+///
+/// This will do a single `read` usercall and scatter the read data among
+/// `bufs`. To read to a single buffer, just pass a slice of length one.
 #[unstable(feature = "sgx_platform", issue = "56975")]
-pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult<usize> {
+pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> IoResult<usize> {
     unsafe {
-        let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.len());
-        let len = raw::read(fd, userbuf.as_mut_ptr(), userbuf.len()).from_sgx_result()?;
-        userbuf[..len].copy_to_enclave(&mut buf[..len]);
-        Ok(len)
+        let total_len = bufs.iter().fold(0usize, |sum, buf| sum.saturating_add(buf.len()));
+        let mut userbuf = alloc::User::<[u8]>::uninitialized(total_len);
+        let ret_len = raw::read(fd, userbuf.as_mut_ptr(), userbuf.len()).from_sgx_result()?;
+        let userbuf = &userbuf[..ret_len];
+        let mut index = 0;
+        for buf in bufs {
+            let end = cmp::min(index + buf.len(), userbuf.len());
+            if let Some(buflen) = end.checked_sub(index) {
+                userbuf[index..end].copy_to_enclave(&mut buf[..buflen]);
+                index += buf.len();
+            } else {
+                break
+            }
+        }
+        Ok(userbuf.len())
     }
 }
 
@@ -30,10 +45,24 @@ pub fn read_alloc(fd: Fd) -> IoResult<Vec<u8>> {
 }
 
 /// Usercall `write`. See the ABI documentation for more information.
+///
+/// This will do a single `write` usercall and gather the written data from
+/// `bufs`. To write from a single buffer, just pass a slice of length one.
 #[unstable(feature = "sgx_platform", issue = "56975")]
-pub fn write(fd: Fd, buf: &[u8]) -> IoResult<usize> {
+pub fn write(fd: Fd, bufs: &[IoSlice<'_>]) -> IoResult<usize> {
     unsafe {
-        let userbuf = alloc::User::new_from_enclave(buf);
+        let total_len = bufs.iter().fold(0usize, |sum, buf| sum.saturating_add(buf.len()));
+        let mut userbuf = alloc::User::<[u8]>::uninitialized(total_len);
+        let mut index = 0;
+        for buf in bufs {
+            let end = cmp::min(index + buf.len(), userbuf.len());
+            if let Some(buflen) = end.checked_sub(index) {
+                userbuf[index..end].copy_from_enclave(&buf[..buflen]);
+                index += buf.len();
+            } else {
+                break
+            }
+        }
         raw::write(fd, userbuf.as_ptr(), userbuf.len()).from_sgx_result()
     }
 }
diff --git a/src/libstd/sys/sgx/fd.rs b/src/libstd/sys/sgx/fd.rs
index a9924f55f12..a1c4af81966 100644
--- a/src/libstd/sys/sgx/fd.rs
+++ b/src/libstd/sys/sgx/fd.rs
@@ -1,6 +1,6 @@
 use fortanix_sgx_abi::Fd;
 
-use crate::io;
+use crate::io::{self, IoSlice, IoSliceMut};
 use crate::mem;
 use crate::sys::{AsInner, FromInner, IntoInner};
 use super::abi::usercalls;
@@ -25,11 +25,19 @@ impl FileDesc {
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        usercalls::read(self.fd, buf)
+        usercalls::read(self.fd, &mut [IoSliceMut::new(buf)])
+    }
+
+    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        usercalls::read(self.fd, bufs)
     }
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
-        usercalls::write(self.fd, buf)
+        usercalls::write(self.fd, &[IoSlice::new(buf)])
+    }
+
+    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        usercalls::write(self.fd, bufs)
     }
 
     pub fn flush(&self) -> io::Result<()> {
diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs
index 76b0b81186a..f9eca9f4cb3 100644
--- a/src/libstd/sys/sgx/net.rs
+++ b/src/libstd/sys/sgx/net.rs
@@ -137,7 +137,7 @@ impl TcpStream {
     }
 
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        io::default_read_vectored(|b| self.read(b), bufs)
+        self.inner.inner.read_vectored(bufs)
     }
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
@@ -145,7 +145,7 @@ impl TcpStream {
     }
 
     pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        io::default_write_vectored(|b| self.write(b), bufs)
+        self.inner.inner.write_vectored(bufs)
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {