From: Jethro Beekman Date: Mon, 17 Sep 2018 23:22:59 +0000 (-0700) Subject: SGX target: implement streams X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=1a894f135e972c30e79b4d7f836d69dbe49e7ead;p=rust.git SGX target: implement streams --- diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs index cf422e3e6aa..b8d739f4d2f 100644 --- a/src/libstd/sys/sgx/abi/usercalls/mod.rs +++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs @@ -12,10 +12,49 @@ use io::{Error as IoError, Result as IoResult}; -mod alloc; +pub mod alloc; #[macro_use] mod raw; +pub(crate) fn copy_user_buffer(buf: &alloc::UserRef) -> Vec { + unsafe { + let buf = buf.to_enclave(); + alloc::User::from_raw_parts(buf.data as _, buf.len).to_enclave() + } +} + +pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult { + 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) + } +} + +pub fn read_alloc(fd: Fd) -> IoResult> { + unsafe { + let mut userbuf = alloc::User::::uninitialized(); + raw::read_alloc(fd, userbuf.as_raw_mut_ptr()).from_sgx_result()?; + Ok(copy_user_buffer(&userbuf)) + } +} + +pub fn write(fd: Fd, buf: &[u8]) -> IoResult { + unsafe { + let userbuf = alloc::User::new_from_enclave(buf); + raw::write(fd, userbuf.as_ptr(), userbuf.len()).from_sgx_result() + } +} + +pub fn flush(fd: Fd) -> IoResult<()> { + unsafe { raw::flush(fd).from_sgx_result() } +} + +pub fn close(fd: Fd) { + unsafe { raw::close(fd) } +} + pub fn launch_thread() -> IoResult<()> { unsafe { raw::launch_thread().from_sgx_result() } } diff --git a/src/libstd/sys/sgx/fd.rs b/src/libstd/sys/sgx/fd.rs new file mode 100644 index 00000000000..31c4199c6cd --- /dev/null +++ b/src/libstd/sys/sgx/fd.rs @@ -0,0 +1,58 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use fortanix_sgx_abi::Fd; + +use io; +use mem; +use sys_common::AsInner; +use super::abi::usercalls; + +#[derive(Debug)] +pub struct FileDesc { + fd: Fd, +} + +impl FileDesc { + pub fn new(fd: Fd) -> FileDesc { + FileDesc { fd: fd } + } + + pub fn raw(&self) -> Fd { self.fd } + + /// Extracts the actual filedescriptor without closing it. + pub fn into_raw(self) -> Fd { + let fd = self.fd; + mem::forget(self); + fd + } + + pub fn read(&self, buf: &mut [u8]) -> io::Result { + usercalls::read(self.fd, buf) + } + + pub fn write(&self, buf: &[u8]) -> io::Result { + usercalls::write(self.fd, buf) + } + + pub fn flush(&self) -> io::Result<()> { + usercalls::flush(self.fd) + } +} + +impl AsInner for FileDesc { + fn as_inner(&self) -> &Fd { &self.fd } +} + +impl Drop for FileDesc { + fn drop(&mut self) { + usercalls::close(self.fd) + } +} diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs index 68f7479d7cd..dd6862e908e 100644 --- a/src/libstd/sys/sgx/mod.rs +++ b/src/libstd/sys/sgx/mod.rs @@ -27,6 +27,7 @@ pub mod cmath; pub mod condvar; pub mod env; +pub mod fd; pub mod fs; pub mod memchr; pub mod mutex; diff --git a/src/libstd/sys/sgx/stdio.rs b/src/libstd/sys/sgx/stdio.rs index 540599a3596..13c91195569 100644 --- a/src/libstd/sys/sgx/stdio.rs +++ b/src/libstd/sys/sgx/stdio.rs @@ -1,4 +1,4 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,64 +8,72 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use fortanix_sgx_abi as abi; + use io; -use sys::unsupported; +use sys::fd::FileDesc; + +pub struct Stdin(()); +pub struct Stdout(()); +pub struct Stderr(()); -pub struct Stdin; -pub struct Stdout; -pub struct Stderr; +fn with_std_fd R, R>(fd: abi::Fd, f: F) -> R { + let fd = FileDesc::new(fd); + let ret = f(&fd); + fd.into_raw(); + ret +} impl Stdin { - pub fn new() -> io::Result { - Ok(Stdin) - } + pub fn new() -> io::Result { Ok(Stdin(())) } - pub fn read(&self, _data: &mut [u8]) -> io::Result { - unsupported() + pub fn read(&self, data: &mut [u8]) -> io::Result { + with_std_fd(abi::FD_STDIN, |fd| fd.read(data)) } } impl Stdout { - pub fn new() -> io::Result { - Ok(Stdout) - } + pub fn new() -> io::Result { Ok(Stdout(())) } - pub fn write(&self, _data: &[u8]) -> io::Result { - unsupported() + pub fn write(&self, data: &[u8]) -> io::Result { + with_std_fd(abi::FD_STDOUT, |fd| fd.write(data)) } pub fn flush(&self) -> io::Result<()> { - Ok(()) + with_std_fd(abi::FD_STDOUT, |fd| fd.flush()) } } impl Stderr { - pub fn new() -> io::Result { - Ok(Stderr) - } + pub fn new() -> io::Result { Ok(Stderr(())) } - pub fn write(&self, _data: &[u8]) -> io::Result { - unsupported() + pub fn write(&self, data: &[u8]) -> io::Result { + with_std_fd(abi::FD_STDERR, |fd| fd.write(data)) } pub fn flush(&self) -> io::Result<()> { - Ok(()) + with_std_fd(abi::FD_STDERR, |fd| fd.flush()) } } +// FIXME: right now this raw stderr handle is used in a few places because +// std::io::stderr_raw isn't exposed, but once that's exposed this impl +// should go away impl io::Write for Stderr { fn write(&mut self, data: &[u8]) -> io::Result { - (&*self).write(data) + Stderr::write(self, data) } + fn flush(&mut self) -> io::Result<()> { - (&*self).flush() + Stderr::flush(self) } } -pub const STDIN_BUF_SIZE: usize = 0; +pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE; -pub fn is_ebadf(_err: &io::Error) -> bool { - true +pub fn is_ebadf(err: &io::Error) -> bool { + // FIXME: Rust normally maps Unix EBADF to `Other` + err.raw_os_error() == Some(abi::Error::BrokenPipe as _) } pub fn panic_output() -> Option {