# https://github.com/rust-lang-nursery/stdsimd/blob/master/crates/std_detect/Cargo.toml
std_detect_file_io = []
std_detect_dlsym_getauxval = []
+
+[package.metadata.fortanix-sgx]
+# Maximum possible number of threads when testing
+threads = 125
use crate::path::Path;
#[test]
- #[cfg_attr(target_os = "emscripten", ignore)]
+ #[cfg_attr(any(target_os = "emscripten", target_env = "sgx"), ignore)]
fn test_self_exe_path() {
let path = current_exe();
assert!(path.is_ok());
fn test() {
assert!((!Path::new("test-path").is_absolute()));
+ #[cfg(not(target_env = "sgx"))]
current_dir().unwrap();
}
}
}
-#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
mod tests {
use crate::io::prelude::*;
assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53)));
let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
+ #[cfg(not(target_env = "sgx"))]
assert!(tsa(("localhost", 23924)).unwrap().contains(&a));
+ #[cfg(target_env = "sgx")]
+ let _ = a;
}
#[test]
assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53"));
let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
+ #[cfg(not(target_env = "sgx"))]
assert!(tsa("localhost:23924").unwrap().contains(&a));
+ #[cfg(target_env = "sgx")]
+ let _ = a;
}
#[test]
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
mod tests {
+ use crate::fmt;
use crate::io::{ErrorKind, IoVec, IoVecMut};
use crate::io::prelude::*;
use crate::net::*;
use crate::net::test::{next_test_ip4, next_test_ip6};
use crate::sync::mpsc::channel;
- use crate::sys_common::AsInner;
use crate::time::{Instant, Duration};
use crate::thread;
connect(i + 1, addr);
t!(stream.write(&[i as u8]));
});
- t.join().ok().unwrap();
+ t.join().ok().expect("thread panicked");
}
}
connect(i + 1, addr);
t!(stream.write(&[99]));
});
- t.join().ok().unwrap();
+ t.join().ok().expect("thread panicked");
}
}
}
#[test]
+ // FIXME: https://github.com/fortanix/rust-sgx/issues/110
+ #[cfg_attr(target_env = "sgx", ignore)]
fn shutdown_smoke() {
each_ip(&mut |addr| {
let a = t!(TcpListener::bind(&addr));
}
#[test]
+ // FIXME: https://github.com/fortanix/rust-sgx/issues/110
+ #[cfg_attr(target_env = "sgx", ignore)]
fn close_readwrite_smoke() {
each_ip(&mut |addr| {
let a = t!(TcpListener::bind(&addr));
#[test]
fn debug() {
- let name = if cfg!(windows) {"socket"} else {"fd"};
+ #[cfg(not(target_env = "sgx"))]
+ fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a {
+ addr
+ }
+ #[cfg(target_env = "sgx")]
+ fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a {
+ addr.to_string()
+ }
+
+ #[cfg(unix)]
+ use crate::os::unix::io::AsRawFd;
+ #[cfg(target_env = "sgx")]
+ use crate::os::fortanix_sgx::io::AsRawFd;
+ #[cfg(not(windows))]
+ fn render_inner(addr: &dyn AsRawFd) -> impl fmt::Debug {
+ addr.as_raw_fd()
+ }
+ #[cfg(windows)]
+ fn render_inner(addr: &dyn crate::os::windows::io::AsRawSocket) -> impl fmt::Debug {
+ addr.as_raw_socket()
+ }
+
+ let inner_name = if cfg!(windows) {"socket"} else {"fd"};
let socket_addr = next_test_ip4();
let listener = t!(TcpListener::bind(&socket_addr));
- let listener_inner = listener.0.socket().as_inner();
let compare = format!("TcpListener {{ addr: {:?}, {}: {:?} }}",
- socket_addr, name, listener_inner);
+ render_socket_addr(&socket_addr),
+ inner_name,
+ render_inner(&listener));
assert_eq!(format!("{:?}", listener), compare);
- let stream = t!(TcpStream::connect(&("localhost",
- socket_addr.port())));
- let stream_inner = stream.0.socket().as_inner();
- let compare = format!("TcpStream {{ addr: {:?}, \
- peer: {:?}, {}: {:?} }}",
- stream.local_addr().unwrap(),
- stream.peer_addr().unwrap(),
- name,
- stream_inner);
+ let stream = t!(TcpStream::connect(&("localhost", socket_addr.port())));
+ let compare = format!("TcpStream {{ addr: {:?}, peer: {:?}, {}: {:?} }}",
+ render_socket_addr(&stream.local_addr().unwrap()),
+ render_socket_addr(&stream.peer_addr().unwrap()),
+ inner_name,
+ render_inner(&stream));
assert_eq!(format!("{:?}", stream), compare);
}
// FIXME: re-enabled bitrig/openbsd tests once their socket timeout code
// no longer has rounding errors.
#[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
#[test]
fn timeouts() {
let addr = next_test_ip4();
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn test_read_timeout() {
let addr = next_test_ip4();
let listener = t!(TcpListener::bind(&addr));
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn test_read_with_timeout() {
let addr = next_test_ip4();
let listener = t!(TcpListener::bind(&addr));
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)]
fn nodelay() {
let addr = next_test_ip4();
let _listener = t!(TcpListener::bind(&addr));
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)]
fn ttl() {
let ttl = 100;
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)]
fn set_nonblocking() {
let addr = next_test_ip4();
let listener = t!(TcpListener::bind(&addr));
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn peek() {
each_ip(&mut |addr| {
let (txdone, rxdone) = channel();
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn connect_timeout_valid() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap();
// all want to use ports. This function figures out which workspace
// it is running in and assigns a port range based on it.
fn base_port() -> u16 {
- let cwd = env::current_dir().unwrap();
+ let cwd = if cfg!(target_env = "sgx") {
+ String::from("sgx")
+ } else {
+ env::current_dir().unwrap().into_os_string().into_string().unwrap()
+ };
let dirs = ["32-opt", "32-nopt",
"musl-64-opt", "cross-opt",
"64-opt", "64-nopt", "64-opt-vg", "64-debug-opt",
- "all-opt", "snap3", "dist"];
+ "all-opt", "snap3", "dist", "sgx"];
dirs.iter().enumerate().find(|&(_, dir)| {
- cwd.to_str().unwrap().contains(dir)
+ cwd.contains(dir)
}).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600
}
}
}
-#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
mod tests {
use crate::io::ErrorKind;
use crate::net::*;
});
);
- if cfg!(unix) {
+ if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) {
tp!("", "foo", "foo");
tp!("foo", "bar", "foo/bar");
tp!("foo/", "bar", "foo/bar");
tfn!("foo", "bar", "bar");
tfn!("foo", "", "");
tfn!("", "foo", "foo");
- if cfg!(unix) {
+ if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) {
tfn!(".", "foo", "./foo");
tfn!("foo/", "bar", "bar");
tfn!("foo/.", "bar", "bar");
}
}
-#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))]
+#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
mod tests {
use crate::io::prelude::*;
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn wait_timeout_wait() {
let m = Arc::new(Mutex::new(()));
let c = Arc::new(Condvar::new());
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn wait_timeout_until_wait() {
let m = Arc::new(Mutex::new(()));
let c = Arc::new(Condvar::new());
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn wait_timeout_until_wake() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair_copy = pair.clone();
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn wait_timeout_wake() {
let m = Arc::new(Mutex::new(()));
let c = Arc::new(Condvar::new());
for _ in 0..10000 {
assert_eq!(rx.recv().unwrap(), 1);
}
- t.join().ok().unwrap();
+ t.join().ok().expect("thread panicked");
}
#[test]
});
}
drop(tx);
- t.join().ok().unwrap();
+ t.join().ok().expect("thread panicked");
}
#[test]
tx2.send(1).unwrap();
}
});
- t1.join().ok().unwrap();
- t2.join().ok().unwrap();
+ t1.join().ok().expect("thread panicked");
+ t2.join().ok().expect("thread panicked");
}
#[test]
for _ in 0..40 {
tx.send(1).unwrap();
}
- t.join().ok().unwrap();
+ t.join().ok().expect("thread panicked");
}
#[test]
tx1.send(1).unwrap();
assert_eq!(rx2.recv().unwrap(), 2);
});
- t1.join().ok().unwrap();
- t2.join().ok().unwrap();
+ t1.join().ok().expect("thread panicked");
+ t2.join().ok().expect("thread panicked");
}
#[test]
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn oneshot_single_thread_recv_timeout() {
let (tx, rx) = channel();
tx.send(()).unwrap();
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn stress_recv_timeout_two_threads() {
let (tx, rx) = channel();
let stress = stress_factor() + 100;
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn recv_timeout_upgrade() {
let (tx, rx) = channel::<()>();
let timeout = Duration::from_millis(1);
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn stress_recv_timeout_shared() {
let (tx, rx) = channel();
let stress = stress_factor() + 100;
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn very_long_recv_timeout_wont_panic() {
let (tx, rx) = channel::<()>();
let join_handle = thread::spawn(move || {
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn shared_recv_timeout() {
let (tx, rx) = channel();
let total = 5;
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn recv_timeout() {
let (tx, rx) = sync_channel::<i32>(1);
assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn stress_recv_timeout_two_threads() {
let (tx, rx) = sync_channel::<i32>(0);
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn stress_recv_timeout_shared() {
const AMT: u32 = 1000;
const NTHREADS: u32 = 8;
+#![cfg_attr(test, allow(unused))] // RT initialization logic is not compiled for test
+
use core::sync::atomic::{AtomicUsize, Ordering};
use crate::io::Write;
#[macro_use]
pub mod usercalls;
+#[cfg(not(test))]
global_asm!(include_str!("entry.S"));
+#[cfg(not(test))]
#[no_mangle]
unsafe extern "C" fn tcs_init(secondary: bool) {
// Be very careful when changing this code: it runs before the binary has been
// FIXME: this item should only exist if this is linked into an executable
// (main function exists). If this is a library, the crate author should be
// able to specify this
+#[cfg(not(test))]
#[no_mangle]
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) {
// FIXME: how to support TLS in library mode?
}
}
-#[no_mangle]
+#[cfg_attr(not(test), no_mangle)]
pub extern "C" fn panic_msg(msg: &str) -> ! {
let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes()));
usercalls::exit(true)
const TLS_KEYS: usize = 128; // Same as POSIX minimum
const TLS_KEYS_BITSET_SIZE: usize = (TLS_KEYS + (USIZE_BITS - 1)) / USIZE_BITS;
+#[cfg_attr(test, linkage = "available_externally")]
+#[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_KEY_IN_USEE"]
static TLS_KEY_IN_USE: SyncBitset = SYNC_BITSET_INIT;
macro_rules! dup {
((* $($exp:tt)*) $($val:tt)*) => (dup!( ($($exp)*) $($val)* $($val)* ));
(() $($val:tt)*) => ([$($val),*])
}
-static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = [
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
- AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
-];
+#[cfg_attr(test, linkage = "available_externally")]
+#[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_DESTRUCTORE"]
+static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = dup!((* * * * * * *) (AtomicUsize::new(0)));
extern "C" {
fn get_tls_ptr() -> *const u8;
// from outside as obtained by `super::alloc`.
fn new_uninit_bytes(size: usize) -> Self {
unsafe {
- let ptr = super::alloc(size, T::align_of()).expect("User memory allocation failed");
- User(NonNull::new_userref(T::from_raw_sized(ptr as _, size)))
+ // Mustn't call alloc with size 0.
+ let ptr = if size > 0 {
+ super::alloc(size, T::align_of()).expect("User memory allocation failed") as _
+ } else {
+ T::align_of() as _ // dangling pointer ok for size 0
+ };
+ User(NonNull::new_userref(T::from_raw_sized(ptr, size)))
}
}
// Using a SpinMutex because we never want to exit the enclave waiting for the
// allocator.
+#[cfg_attr(test, linkage = "available_externally")]
+#[export_name = "_ZN16__rust_internals3std3sys3sgx5alloc8DLMALLOCE"]
static DLMALLOC: SpinMutex<dlmalloc::Dlmalloc> = SpinMutex::new(dlmalloc::DLMALLOC_INIT);
#[stable(feature = "alloc_system_type", since = "1.28.0")]
use crate::sys_common::FromInner;
use crate::slice;
+#[cfg_attr(test, linkage = "available_externally")]
+#[export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE"]
static ARGS: AtomicUsize = AtomicUsize::new(0);
type ArgsStore = Vec<OsString>;
+#[cfg_attr(test, allow(dead_code))]
pub unsafe fn init(argc: isize, argv: *const *const u8) {
if argc != 0 {
let args = alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _);
mutex.lock()
}
- pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
+ pub unsafe fn wait_timeout(&self, mutex: &Mutex, _dur: Duration) -> bool {
+ mutex.unlock(); // don't hold the lock while panicking
panic!("timeout not supported in SGX");
}
}
}
-#[derive(Debug, Clone)]
+#[derive(Clone)]
pub struct TcpStream {
inner: Socket,
peer_addr: Option<String>,
}
+impl fmt::Debug for TcpStream {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let mut res = f.debug_struct("TcpStream");
+
+ if let Some(ref addr) = self.inner.local_addr {
+ res.field("addr", addr);
+ }
+
+ if let Some(ref peer) = self.peer_addr {
+ res.field("peer", peer);
+ }
+
+ res.field("fd", &self.inner.inner.as_inner())
+ .finish()
+ }
+}
+
fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
match result {
Ok(saddr) => Ok(saddr.to_string()),
Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) })
}
- pub fn connect_timeout(addr: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
+ pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream> {
+ if dur == Duration::default() {
+ return Err(io::Error::new(io::ErrorKind::InvalidInput,
+ "cannot set a 0 duration timeout"));
+ }
Self::connect(Ok(addr)) // FIXME: ignoring timeout
}
- pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
- sgx_ineffective(())
+ pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
+ match dur {
+ Some(dur) if dur == Duration::default() => {
+ return Err(io::Error::new(io::ErrorKind::InvalidInput,
+ "cannot set a 0 duration timeout"));
+ }
+ _ => sgx_ineffective(())
+ }
}
- pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
- sgx_ineffective(())
+ pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
+ match dur {
+ Some(dur) if dur == Duration::default() => {
+ return Err(io::Error::new(io::ErrorKind::InvalidInput,
+ "cannot set a 0 duration timeout"));
+ }
+ _ => sgx_ineffective(())
+ }
}
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
}
}
-#[derive(Debug, Clone)]
+#[derive(Clone)]
pub struct TcpListener {
inner: Socket,
}
+impl fmt::Debug for TcpListener {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let mut res = f.debug_struct("TcpListener");
+
+ if let Some(ref addr) = self.inner.local_addr {
+ res.field("addr", addr);
+ }
+
+ res.field("fd", &self.inner.inner.as_inner())
+ .finish()
+ }
+}
+
impl TcpListener {
pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
let addr = io_err_to_addr(addr)?;
unsupported()
}
+#[cfg_attr(test, linkage = "available_externally")]
+#[export_name = "_ZN16__rust_internals3std3sys3sgx2os3ENVE"]
static ENV: AtomicUsize = AtomicUsize::new(0);
+#[cfg_attr(test, linkage = "available_externally")]
+#[export_name = "_ZN16__rust_internals3std3sys3sgx2os8ENV_INITE"]
static ENV_INIT: Once = Once::new();
type EnvStore = Mutex<HashMap<OsString, OsString>>;
+#[cfg(not(test))]
use crate::alloc::{self, Layout};
use crate::num::NonZeroUsize;
+#[cfg(not(test))]
use crate::slice;
+#[cfg(not(test))]
use crate::str;
use super::waitqueue::{
// only used by __rust_rwlock_unlock below
#[inline]
+ #[cfg_attr(test, allow(dead_code))]
unsafe fn unlock(&self) {
let rguard = self.readers.lock();
let wguard = self.writer.lock();
pub unsafe fn destroy(&self) {}
}
+#[cfg(not(test))]
const EINVAL: i32 = 22;
// used by libunwind port
+#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
if p.is_null() {
return 0;
}
+#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
if p.is_null() {
(*p).write();
return 0;
}
+#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
if p.is_null() {
// the following functions are also used by the libunwind port. They're
// included here to make sure parallel codegen and LTO don't mess things up.
+#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
if s < 0 {
}
}
+#[cfg(not(test))]
#[no_mangle]
// NB. used by both libunwind and libpanic_abort
pub unsafe extern "C" fn __rust_abort() {
crate::sys::abort_internal();
}
+#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 {
alloc::alloc(Layout::from_size_align_unchecked(size, align))
}
+#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) {
alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align))
#[cfg(test)]
mod tests {
-
use super::*;
use core::array::FixedSizeArray;
- use crate::mem::MaybeUninit;
- use crate::{mem, ptr};
+ use crate::mem::{self, MaybeUninit};
- // The below test verifies that the bytes of initialized RWLock are the ones
- // we use in libunwind.
- // If they change we need to update src/UnwindRustSgx.h in libunwind.
+ // Verify that the bytes of initialized RWLock are the same as in
+ // libunwind. If they change, `src/UnwindRustSgx.h` in libunwind needs to
+ // be changed too.
#[test]
fn test_c_rwlock_initializer() {
const RWLOCK_INIT: &[u8] = &[
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
];
- let mut init = MaybeUninit::<RWLock>::zeroed();
- init.set(RWLock::new());
- assert_eq!(
- mem::transmute::<_, [u8; 128]>(init.into_inner()).as_slice(),
- RWLOCK_INIT
- );
+ #[inline(never)]
+ fn zero_stack() {
+ test::black_box(MaybeUninit::<[RWLock; 16]>::zeroed());
+ }
+
+ #[inline(never)]
+ unsafe fn rwlock_new(init: &mut MaybeUninit<RWLock>) {
+ init.set(RWLock::new());
+ }
+
+ unsafe {
+ // try hard to make sure that the padding/unused bytes in RWLock
+ // get initialized as 0. If the assertion below fails, that might
+ // just be an issue with the test code and not with the value of
+ // RWLOCK_INIT.
+ zero_stack();
+ let mut init = MaybeUninit::<RWLock>::zeroed();
+ rwlock_new(&mut init);
+ assert_eq!(
+ mem::transmute::<_, [u8; 128]>(init.into_initialized()).as_slice(),
+ RWLOCK_INIT
+ )
+ };
}
}
}
}
+#[cfg_attr(test, allow(dead_code))]
pub unsafe fn init() {
}
+#![cfg_attr(test, allow(dead_code))] // why is this necessary?
use crate::boxed::FnBox;
use crate::ffi::CStr;
use crate::io;
}
}
+ #[cfg_attr(test, linkage = "available_externally")]
+ #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread15TASK_QUEUE_INITE"]
static TASK_QUEUE_INIT: Once = Once::new();
+ #[cfg_attr(test, linkage = "available_externally")]
+ #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread10TASK_QUEUEE"]
static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
use super::*;
use crate::sync::Arc;
use crate::thread;
+ use crate::time::{SystemTime, Duration};
#[test]
fn sleep() {
let t1 = thread::spawn(move || {
*mutex2.lock() = 1;
});
- thread::sleep_ms(50);
+
+ // "sleep" for 50ms
+ // FIXME: https://github.com/fortanix/rust-sgx/issues/31
+ let start = SystemTime::now();
+ let max = Duration::from_millis(50);
+ while start.elapsed().unwrap() < max {}
+
assert_eq!(*guard, 0);
drop(guard);
t1.join().unwrap();
let locked = wq.lock();
let t1 = thread::spawn(move || {
- assert!(WaitQueue::notify_one(wq2.lock()).is_none())
+ // if we obtain the lock, the main thread should be waiting
+ assert!(WaitQueue::notify_one(wq2.lock()).is_ok());
});
WaitQueue::wait(locked);
thread::spawn(|| {
assert!(FOO.try_with(|_| ()).is_ok());
- }).join().ok().unwrap();
+ }).join().ok().expect("thread panicked");
}
#[test]
thread::spawn(move|| {
drop(S1);
- }).join().ok().unwrap();
+ }).join().ok().expect("thread panicked");
}
#[test]
thread::spawn(move|| unsafe {
K1.with(|s| *s.get() = Some(S1));
- }).join().ok().unwrap();
+ }).join().ok().expect("thread panicked");
}
// Note that this test will deadlock if TLS destructors aren't run (this
fn test_unnamed_thread() {
thread::spawn(move|| {
assert!(thread::current().name().is_none());
- }).join().ok().unwrap();
+ }).join().ok().expect("thread panicked");
}
#[test]
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn test_park_timeout_unpark_not_called() {
for _ in 0..10 {
thread::park_timeout(Duration::from_millis(10));
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn test_park_timeout_unpark_called_other_thread() {
for _ in 0..10 {
let th = thread::current();
}
#[test]
+ #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
fn sleep_ms_smoke() {
thread::sleep(Duration::from_millis(2));
}
"src/libstd/f64.rs",
// Integration test for platform-specific run-time feature detection:
"src/libstd/tests/run-time-detect.rs" ,
+ "src/libstd/net/test.rs",
"src/libstd/sys_common/mod.rs",
"src/libstd/sys_common/net.rs",
"src/libterm", // Not sure how to make this crate portable, but test crate needs it.