Skip to content

Commit 3f6fbf0

Browse files
author
Jethro Beekman
committed
SGX target: implement streams
1 parent 368fafb commit 3f6fbf0

File tree

4 files changed

+135
-29
lines changed

4 files changed

+135
-29
lines changed

src/libstd/sys/sgx/abi/usercalls/mod.rs

+40-1
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,49 @@ pub use fortanix_sgx_abi::*;
1212

1313
use io::{Error as IoError, Result as IoResult};
1414

15-
mod alloc;
15+
pub mod alloc;
1616
#[macro_use]
1717
mod raw;
1818

19+
pub(crate) fn copy_user_buffer(buf: &alloc::UserRef<ByteBuffer>) -> Vec<u8> {
20+
unsafe {
21+
let buf = buf.to_enclave();
22+
alloc::User::from_raw_parts(buf.data as _, buf.len).to_enclave()
23+
}
24+
}
25+
26+
pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult<usize> {
27+
unsafe {
28+
let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.len());
29+
let len = raw::read(fd, userbuf.as_mut_ptr(), userbuf.len()).from_sgx_result()?;
30+
userbuf[..len].copy_to_enclave(&mut buf[..len]);
31+
Ok(len)
32+
}
33+
}
34+
35+
pub fn read_alloc(fd: Fd) -> IoResult<Vec<u8>> {
36+
unsafe {
37+
let mut userbuf = alloc::User::<ByteBuffer>::uninitialized();
38+
raw::read_alloc(fd, userbuf.as_raw_mut_ptr()).from_sgx_result()?;
39+
Ok(copy_user_buffer(&userbuf))
40+
}
41+
}
42+
43+
pub fn write(fd: Fd, buf: &[u8]) -> IoResult<usize> {
44+
unsafe {
45+
let userbuf = alloc::User::new_from_enclave(buf);
46+
raw::write(fd, userbuf.as_ptr(), userbuf.len()).from_sgx_result()
47+
}
48+
}
49+
50+
pub fn flush(fd: Fd) -> IoResult<()> {
51+
unsafe { raw::flush(fd).from_sgx_result() }
52+
}
53+
54+
pub fn close(fd: Fd) {
55+
unsafe { raw::close(fd) }
56+
}
57+
1958
pub fn launch_thread() -> IoResult<()> {
2059
unsafe { raw::launch_thread().from_sgx_result() }
2160
}

src/libstd/sys/sgx/fd.rs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use fortanix_sgx_abi::Fd;
12+
13+
use io;
14+
use mem;
15+
use sys_common::AsInner;
16+
use super::abi::usercalls;
17+
18+
#[derive(Debug)]
19+
pub struct FileDesc {
20+
fd: Fd,
21+
}
22+
23+
impl FileDesc {
24+
pub fn new(fd: Fd) -> FileDesc {
25+
FileDesc { fd: fd }
26+
}
27+
28+
pub fn raw(&self) -> Fd { self.fd }
29+
30+
/// Extracts the actual filedescriptor without closing it.
31+
pub fn into_raw(self) -> Fd {
32+
let fd = self.fd;
33+
mem::forget(self);
34+
fd
35+
}
36+
37+
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
38+
usercalls::read(self.fd, buf)
39+
}
40+
41+
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
42+
usercalls::write(self.fd, buf)
43+
}
44+
45+
pub fn flush(&self) -> io::Result<()> {
46+
usercalls::flush(self.fd)
47+
}
48+
}
49+
50+
impl AsInner<Fd> for FileDesc {
51+
fn as_inner(&self) -> &Fd { &self.fd }
52+
}
53+
54+
impl Drop for FileDesc {
55+
fn drop(&mut self) {
56+
usercalls::close(self.fd)
57+
}
58+
}

src/libstd/sys/sgx/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub mod backtrace;
2727
pub mod cmath;
2828
pub mod condvar;
2929
pub mod env;
30+
pub mod fd;
3031
pub mod fs;
3132
pub mod memchr;
3233
pub mod mutex;

src/libstd/sys/sgx/stdio.rs

+36-28
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -8,67 +8,75 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use fortanix_sgx_abi as abi;
12+
1113
use io;
12-
use sys::unsupported;
14+
use sys::fd::FileDesc;
1315
use panicking::PanicOutput;
1416

15-
pub struct Stdin;
16-
pub struct Stdout;
17-
pub struct Stderr;
17+
pub struct Stdin(());
18+
pub struct Stdout(());
19+
pub struct Stderr(());
20+
21+
fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R {
22+
let fd = FileDesc::new(fd);
23+
let ret = f(&fd);
24+
fd.into_raw();
25+
ret
26+
}
1827

1928
impl Stdin {
20-
pub fn new() -> io::Result<Stdin> {
21-
Ok(Stdin)
22-
}
29+
pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }
2330

24-
pub fn read(&self, _data: &mut [u8]) -> io::Result<usize> {
25-
unsupported()
31+
pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
32+
with_std_fd(abi::FD_STDIN, |fd| fd.read(data))
2633
}
2734
}
2835

2936
impl Stdout {
30-
pub fn new() -> io::Result<Stdout> {
31-
Ok(Stdout)
32-
}
37+
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
3338

34-
pub fn write(&self, _data: &[u8]) -> io::Result<usize> {
35-
unsupported()
39+
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
40+
with_std_fd(abi::FD_STDOUT, |fd| fd.write(data))
3641
}
3742

3843
pub fn flush(&self) -> io::Result<()> {
39-
Ok(())
44+
with_std_fd(abi::FD_STDOUT, |fd| fd.flush())
4045
}
4146
}
4247

4348
impl Stderr {
44-
pub fn new() -> io::Result<Stderr> {
45-
Ok(Stderr)
46-
}
49+
pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }
4750

48-
pub fn write(&self, _data: &[u8]) -> io::Result<usize> {
49-
unsupported()
51+
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
52+
with_std_fd(abi::FD_STDERR, |fd| fd.write(data))
5053
}
5154

5255
pub fn flush(&self) -> io::Result<()> {
53-
Ok(())
56+
with_std_fd(abi::FD_STDERR, |fd| fd.flush())
5457
}
5558
}
5659

60+
// FIXME: right now this raw stderr handle is used in a few places because
61+
// std::io::stderr_raw isn't exposed, but once that's exposed this impl
62+
// should go away
5763
impl io::Write for Stderr {
5864
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
59-
(&*self).write(data)
65+
Stderr::write(self, data)
6066
}
67+
6168
fn flush(&mut self) -> io::Result<()> {
62-
(&*self).flush()
69+
Stderr::flush(self)
6370
}
6471
}
6572

66-
pub const STDIN_BUF_SIZE: usize = 0;
67-
68-
pub fn is_ebadf(_err: &io::Error) -> bool {
69-
true
73+
pub fn is_ebadf(err: &io::Error) -> bool {
74+
// FIXME: Rust normally maps Unix EBADF to `Other`
75+
err.raw_os_error() == Some(abi::Error::BrokenPipe as _)
7076
}
7177

78+
pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;
79+
7280
pub fn panic_output() -> Option<PanicOutput<super::abi::panic::SgxPanicOutput>> {
7381
extern {
7482
static DEBUG: u8;

0 commit comments

Comments
 (0)