Skip to content

Commit 1a894f1

Browse files
author
Jethro Beekman
committed
SGX target: implement streams
1 parent 8d6edc9 commit 1a894f1

File tree

4 files changed

+134
-28
lines changed

4 files changed

+134
-28
lines changed

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

Lines changed: 40 additions & 1 deletion
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

Lines changed: 58 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 35 additions & 27 deletions
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,64 +8,72 @@
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;
15+
16+
pub struct Stdin(());
17+
pub struct Stdout(());
18+
pub struct Stderr(());
1319

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

1827
impl Stdin {
19-
pub fn new() -> io::Result<Stdin> {
20-
Ok(Stdin)
21-
}
28+
pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }
2229

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

2835
impl Stdout {
29-
pub fn new() -> io::Result<Stdout> {
30-
Ok(Stdout)
31-
}
36+
pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
3237

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

3742
pub fn flush(&self) -> io::Result<()> {
38-
Ok(())
43+
with_std_fd(abi::FD_STDOUT, |fd| fd.flush())
3944
}
4045
}
4146

4247
impl Stderr {
43-
pub fn new() -> io::Result<Stderr> {
44-
Ok(Stderr)
45-
}
48+
pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }
4649

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

5154
pub fn flush(&self) -> io::Result<()> {
52-
Ok(())
55+
with_std_fd(abi::FD_STDERR, |fd| fd.flush())
5356
}
5457
}
5558

59+
// FIXME: right now this raw stderr handle is used in a few places because
60+
// std::io::stderr_raw isn't exposed, but once that's exposed this impl
61+
// should go away
5662
impl io::Write for Stderr {
5763
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
58-
(&*self).write(data)
64+
Stderr::write(self, data)
5965
}
66+
6067
fn flush(&mut self) -> io::Result<()> {
61-
(&*self).flush()
68+
Stderr::flush(self)
6269
}
6370
}
6471

65-
pub const STDIN_BUF_SIZE: usize = 0;
72+
pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;
6673

67-
pub fn is_ebadf(_err: &io::Error) -> bool {
68-
true
74+
pub fn is_ebadf(err: &io::Error) -> bool {
75+
// FIXME: Rust normally maps Unix EBADF to `Other`
76+
err.raw_os_error() == Some(abi::Error::BrokenPipe as _)
6977
}
7078

7179
pub fn panic_output() -> Option<impl io::Write> {

0 commit comments

Comments
 (0)