1 use io::{Error as IoError, Result as IoResult};
10 /// Usercall `read`. See the ABI documentation for more information.
11 #[unstable(feature = "sgx_platform", issue = "56975")]
12 pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult<usize> {
14 let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.len());
15 let len = raw::read(fd, userbuf.as_mut_ptr(), userbuf.len()).from_sgx_result()?;
16 userbuf[..len].copy_to_enclave(&mut buf[..len]);
21 /// Usercall `read_alloc`. See the ABI documentation for more information.
22 #[unstable(feature = "sgx_platform", issue = "56975")]
23 pub fn read_alloc(fd: Fd) -> IoResult<Vec<u8>> {
25 let mut userbuf = alloc::User::<ByteBuffer>::uninitialized();
26 raw::read_alloc(fd, userbuf.as_raw_mut_ptr()).from_sgx_result()?;
27 Ok(userbuf.copy_user_buffer())
31 /// Usercall `write`. See the ABI documentation for more information.
32 #[unstable(feature = "sgx_platform", issue = "56975")]
33 pub fn write(fd: Fd, buf: &[u8]) -> IoResult<usize> {
35 let userbuf = alloc::User::new_from_enclave(buf);
36 raw::write(fd, userbuf.as_ptr(), userbuf.len()).from_sgx_result()
40 /// Usercall `flush`. See the ABI documentation for more information.
41 #[unstable(feature = "sgx_platform", issue = "56975")]
42 pub fn flush(fd: Fd) -> IoResult<()> {
43 unsafe { raw::flush(fd).from_sgx_result() }
46 /// Usercall `close`. See the ABI documentation for more information.
47 #[unstable(feature = "sgx_platform", issue = "56975")]
48 pub fn close(fd: Fd) {
49 unsafe { raw::close(fd) }
52 fn string_from_bytebuffer(buf: &alloc::UserRef<ByteBuffer>, usercall: &str, arg: &str) -> String {
53 String::from_utf8(buf.copy_user_buffer())
54 .unwrap_or_else(|_| panic!("Usercall {}: expected {} to be valid UTF-8", usercall, arg))
57 /// Usercall `bind_stream`. See the ABI documentation for more information.
58 #[unstable(feature = "sgx_platform", issue = "56975")]
59 pub fn bind_stream(addr: &str) -> IoResult<(Fd, String)> {
61 let addr_user = alloc::User::new_from_enclave(addr.as_bytes());
62 let mut local = alloc::User::<ByteBuffer>::uninitialized();
63 let fd = raw::bind_stream(
66 local.as_raw_mut_ptr()
68 let local = string_from_bytebuffer(&local, "bind_stream", "local_addr");
73 /// Usercall `accept_stream`. See the ABI documentation for more information.
74 #[unstable(feature = "sgx_platform", issue = "56975")]
75 pub fn accept_stream(fd: Fd) -> IoResult<(Fd, String, String)> {
77 let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized();
78 let mut buf_it = alloc::UserRef::iter_mut(&mut *bufs); // FIXME: can this be done
79 // without forcing coercion?
80 let (local, peer) = (buf_it.next().unwrap(), buf_it.next().unwrap());
81 let fd = raw::accept_stream(
83 local.as_raw_mut_ptr(),
86 let local = string_from_bytebuffer(&local, "accept_stream", "local_addr");
87 let peer = string_from_bytebuffer(&peer, "accept_stream", "peer_addr");
92 /// Usercall `connect_stream`. See the ABI documentation for more information.
93 #[unstable(feature = "sgx_platform", issue = "56975")]
94 pub fn connect_stream(addr: &str) -> IoResult<(Fd, String, String)> {
96 let addr_user = alloc::User::new_from_enclave(addr.as_bytes());
97 let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized();
98 let mut buf_it = alloc::UserRef::iter_mut(&mut *bufs); // FIXME: can this be done
99 // without forcing coercion?
100 let (local, peer) = (buf_it.next().unwrap(), buf_it.next().unwrap());
101 let fd = raw::connect_stream(
104 local.as_raw_mut_ptr(),
105 peer.as_raw_mut_ptr()
106 ).from_sgx_result()?;
107 let local = string_from_bytebuffer(&local, "connect_stream", "local_addr");
108 let peer = string_from_bytebuffer(&peer, "connect_stream", "peer_addr");
109 Ok((fd, local, peer))
113 /// Usercall `launch_thread`. See the ABI documentation for more information.
114 #[unstable(feature = "sgx_platform", issue = "56975")]
115 pub unsafe fn launch_thread() -> IoResult<()> {
116 raw::launch_thread().from_sgx_result()
119 /// Usercall `exit`. See the ABI documentation for more information.
120 #[unstable(feature = "sgx_platform", issue = "56975")]
121 pub fn exit(panic: bool) -> ! {
122 unsafe { raw::exit(panic) }
125 /// Usercall `wait`. See the ABI documentation for more information.
126 #[unstable(feature = "sgx_platform", issue = "56975")]
127 pub fn wait(event_mask: u64, timeout: u64) -> IoResult<u64> {
128 unsafe { raw::wait(event_mask, timeout).from_sgx_result() }
131 /// Usercall `send`. See the ABI documentation for more information.
132 #[unstable(feature = "sgx_platform", issue = "56975")]
133 pub fn send(event_set: u64, tcs: Option<Tcs>) -> IoResult<()> {
134 unsafe { raw::send(event_set, tcs).from_sgx_result() }
137 /// Usercall `insecure_time`. See the ABI documentation for more information.
138 #[unstable(feature = "sgx_platform", issue = "56975")]
139 pub fn insecure_time() -> Duration {
140 let t = unsafe { raw::insecure_time() };
141 Duration::new(t / 1_000_000_000, (t % 1_000_000_000) as _)
144 /// Usercall `alloc`. See the ABI documentation for more information.
145 #[unstable(feature = "sgx_platform", issue = "56975")]
146 pub fn alloc(size: usize, alignment: usize) -> IoResult<*mut u8> {
147 unsafe { raw::alloc(size, alignment).from_sgx_result() }
150 #[unstable(feature = "sgx_platform", issue = "56975")]
152 pub use self::raw::free;
154 fn check_os_error(err: Result) -> i32 {
155 // FIXME: not sure how to make sure all variants of Error are covered
156 if err == Error::NotFound as _ ||
157 err == Error::PermissionDenied as _ ||
158 err == Error::ConnectionRefused as _ ||
159 err == Error::ConnectionReset as _ ||
160 err == Error::ConnectionAborted as _ ||
161 err == Error::NotConnected as _ ||
162 err == Error::AddrInUse as _ ||
163 err == Error::AddrNotAvailable as _ ||
164 err == Error::BrokenPipe as _ ||
165 err == Error::AlreadyExists as _ ||
166 err == Error::WouldBlock as _ ||
167 err == Error::InvalidInput as _ ||
168 err == Error::InvalidData as _ ||
169 err == Error::TimedOut as _ ||
170 err == Error::WriteZero as _ ||
171 err == Error::Interrupted as _ ||
172 err == Error::Other as _ ||
173 err == Error::UnexpectedEof as _ ||
174 ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&err)
178 panic!("Usercall: returned invalid error value {}", err)
182 trait FromSgxResult {
185 fn from_sgx_result(self) -> IoResult<Self::Return>;
188 impl<T> FromSgxResult for (Result, T) {
191 fn from_sgx_result(self) -> IoResult<Self::Return> {
192 if self.0 == RESULT_SUCCESS {
195 Err(IoError::from_raw_os_error(check_os_error(self.0)))
200 impl FromSgxResult for Result {
203 fn from_sgx_result(self) -> IoResult<Self::Return> {
204 if self == RESULT_SUCCESS {
207 Err(IoError::from_raw_os_error(check_os_error(self)))