Drop support for cloudabi targets

This commit is contained in:
Lzu Tao 2020-10-27 13:10:31 +00:00 committed by Mark Rousskov
parent c643dd2ec8
commit 6bfe27a3e0
165 changed files with 103 additions and 5329 deletions

View File

@ -23,7 +23,7 @@
all(target_arch = "wasm32", not(target_os = "emscripten")), all(target_arch = "wasm32", not(target_os = "emscripten")),
feature(integer_atomics, stdsimd) feature(integer_atomics, stdsimd)
)] )]
#![cfg_attr(any(unix, target_os = "cloudabi", target_os = "redox"), feature(libc))] #![cfg_attr(any(unix, target_os = "redox"), feature(libc))]
// The minimum alignment guaranteed by the architecture. This value is used to // The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. // add fast paths for low alignment values.
#[cfg(all(any(target_arch = "x86", #[cfg(all(any(target_arch = "x86",
@ -69,7 +69,7 @@ const MIN_ALIGN: usize = 16;
/// independently of the standard librarys global allocator. /// independently of the standard librarys global allocator.
#[stable(feature = "alloc_system_type", since = "1.28.0")] #[stable(feature = "alloc_system_type", since = "1.28.0")]
pub struct System; pub struct System;
#[cfg(any(windows, unix, target_os = "cloudabi", target_os = "redox"))] #[cfg(any(windows, unix, target_os = "redox"))]
mod realloc_fallback { mod realloc_fallback {
use core::alloc::{GlobalAlloc, Layout}; use core::alloc::{GlobalAlloc, Layout};
use core::cmp; use core::cmp;
@ -89,7 +89,7 @@ mod realloc_fallback {
} }
} }
} }
#[cfg(any(unix, target_os = "cloudabi", target_os = "redox"))] #[cfg(any(unix, target_os = "redox"))]
mod platform { mod platform {
extern crate libc; extern crate libc;
use core::ptr; use core::ptr;

View File

@ -1,16 +0,0 @@
use crate::spec::Target;
pub fn target() -> Target {
let mut base = super::cloudabi_base::opts();
base.max_atomic_width = Some(128);
base.unsupported_abis = super::arm_base::unsupported_abis();
base.linker = Some("aarch64-unknown-cloudabi-cc".to_string());
Target {
llvm_target: "aarch64-unknown-cloudabi".to_string(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: base,
}
}

View File

@ -1,18 +0,0 @@
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::cloudabi_base::opts();
base.cpu = "cortex-a8".to_string();
base.max_atomic_width = Some(64);
base.features = "+v7,+vfp3,+neon".to_string();
base.unsupported_abis = super::arm_base::unsupported_abis();
base.linker = Some("armv7-unknown-cloudabi-eabihf-cc".to_string());
Target {
llvm_target: "armv7-unknown-cloudabi-eabihf".to_string(),
pointer_width: 32,
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions { mcount: "\u{1}mcount".to_string(), ..base },
}
}

View File

@ -1,36 +0,0 @@
use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions, TlsModel};
pub fn opts() -> TargetOptions {
let mut args = LinkArgs::new();
args.insert(
LinkerFlavor::Gcc,
vec![
"-Wl,-Bstatic".to_string(),
"-Wl,--no-dynamic-linker".to_string(),
"-Wl,--gc-sections".to_string(),
],
);
TargetOptions {
os: "cloudabi".to_string(),
executables: true,
os_family: None,
linker_is_gnu: true,
pre_link_args: args,
position_independent_executables: true,
// As CloudABI only supports static linkage, there is no need
// for dynamic TLS. The C library therefore does not provide
// __tls_get_addr(), which is normally used to perform dynamic
// TLS lookups by programs that make use of dlopen(). Only the
// "local-exec" and "initial-exec" TLS models can be used.
//
// "local-exec" is more efficient than "initial-exec", as the
// latter has one more level of indirection: it accesses the GOT
// (Global Offset Table) to obtain the effective address of a
// thread-local variable. Using a GOT is useful only when doing
// dynamic linking.
tls_model: TlsModel::LocalExec,
relro_level: RelroLevel::Full,
..Default::default()
}
}

View File

@ -1,20 +0,0 @@
use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = super::cloudabi_base::opts();
base.cpu = "pentium4".to_string();
base.max_atomic_width = Some(64);
base.linker = Some("i686-unknown-cloudabi-cc".to_string());
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
base.stack_probes = true;
Target {
llvm_target: "i686-unknown-cloudabi".to_string(),
pointer_width: 32,
data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
f64:32:64-f80:32-n8:16:32-S128"
.to_string(),
arch: "x86".to_string(),
options: base,
}
}

View File

@ -54,7 +54,6 @@ mod apple_base;
mod apple_sdk_base; mod apple_sdk_base;
mod arm_base; mod arm_base;
mod avr_gnu_base; mod avr_gnu_base;
mod cloudabi_base;
mod dragonfly_base; mod dragonfly_base;
mod freebsd_base; mod freebsd_base;
mod fuchsia_base; mod fuchsia_base;
@ -628,11 +627,6 @@ supported_targets! {
("msp430-none-elf", msp430_none_elf), ("msp430-none-elf", msp430_none_elf),
("aarch64-unknown-cloudabi", aarch64_unknown_cloudabi),
("armv7-unknown-cloudabi-eabihf", armv7_unknown_cloudabi_eabihf),
("i686-unknown-cloudabi", i686_unknown_cloudabi),
("x86_64-unknown-cloudabi", x86_64_unknown_cloudabi),
("aarch64-unknown-hermit", aarch64_unknown_hermit), ("aarch64-unknown-hermit", aarch64_unknown_hermit),
("x86_64-unknown-hermit", x86_64_unknown_hermit), ("x86_64-unknown-hermit", x86_64_unknown_hermit),
("x86_64-unknown-hermit-kernel", x86_64_unknown_hermit_kernel), ("x86_64-unknown-hermit-kernel", x86_64_unknown_hermit_kernel),

View File

@ -1,19 +0,0 @@
use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = super::cloudabi_base::opts();
base.cpu = "x86-64".to_string();
base.max_atomic_width = Some(64);
base.linker = Some("x86_64-unknown-cloudabi-cc".to_string());
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
base.stack_probes = true;
Target {
llvm_target: "x86_64-unknown-cloudabi".to_string(),
pointer_width: 64,
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
.to_string(),
arch: "x86_64".to_string(),
options: base,
}
}

View File

@ -32,7 +32,7 @@ pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 {
abort(); abort();
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(any(unix, target_os = "cloudabi"))] { if #[cfg(unix)] {
unsafe fn abort() -> ! { unsafe fn abort() -> ! {
libc::abort(); libc::abort();
} }

View File

@ -49,7 +49,6 @@ cfg_if::cfg_if! {
mod real_imp; mod real_imp;
} else if #[cfg(any( } else if #[cfg(any(
all(target_family = "windows", target_env = "gnu"), all(target_family = "windows", target_env = "gnu"),
target_os = "cloudabi",
target_os = "psp", target_os = "psp",
target_family = "unix", target_family = "unix",
all(target_vendor = "fortanix", target_env = "sgx"), all(target_vendor = "fortanix", target_env = "sgx"),

View File

@ -18,7 +18,6 @@ fn main() {
|| target.contains("uwp") || target.contains("uwp")
|| target.contains("windows") || target.contains("windows")
|| target.contains("fuchsia") || target.contains("fuchsia")
|| target.contains("cloudabi")
|| (target.contains("sgx") && target.contains("fortanix")) || (target.contains("sgx") && target.contains("fortanix"))
|| target.contains("hermit") || target.contains("hermit")
|| target.contains("l4re") || target.contains("l4re")

View File

@ -8,7 +8,7 @@
#![stable(feature = "rust1", since = "1.0.0")] #![stable(feature = "rust1", since = "1.0.0")]
#![deny(unsafe_op_in_unsafe_fn)] #![deny(unsafe_op_in_unsafe_fn)]
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] #[cfg(all(test, not(any(target_os = "emscripten", target_env = "sgx"))))]
mod tests; mod tests;
use crate::ffi::OsString; use crate::ffi::OsString;

View File

@ -1,6 +1,6 @@
#![deny(unsafe_op_in_unsafe_fn)] #![deny(unsafe_op_in_unsafe_fn)]
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))] #[cfg(all(test, not(target_os = "emscripten")))]
mod tests; mod tests;
use crate::io::prelude::*; use crate::io::prelude::*;

View File

@ -1,4 +1,4 @@
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] #[cfg(all(test, not(any(target_os = "emscripten", target_env = "sgx"))))]
mod tests; mod tests;
use crate::fmt; use crate::fmt;

View File

@ -97,7 +97,7 @@
#![stable(feature = "process", since = "1.0.0")] #![stable(feature = "process", since = "1.0.0")]
#![deny(unsafe_op_in_unsafe_fn)] #![deny(unsafe_op_in_unsafe_fn)]
#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] #[cfg(all(test, not(any(target_os = "emscripten", target_env = "sgx"))))]
mod tests; mod tests;
use crate::io::prelude::*; use crate::io::prelude::*;

View File

@ -1,47 +0,0 @@
// Copyright (c) 2018 Nuxi (https://nuxi.nl/) and contributors.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
#[cfg(feature = "bitflags")]
use bitflags::bitflags;
// Minimal implementation of bitflags! in case we can't depend on the bitflags
// crate. Only implements `bits()` and a `from_bits_truncate()` that doesn't
// actually truncate.
#[cfg(not(feature = "bitflags"))]
macro_rules! bitflags {
(
$(#[$attr:meta])*
pub struct $name:ident: $type:ty {
$($(#[$const_attr:meta])* const $const:ident = $val:expr;)*
}
) => {
$(#[$attr])*
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct $name { bits: $type }
impl $name {
$($(#[$const_attr])* pub const $const: $name = $name{ bits: $val };)*
pub fn bits(&self) -> $type { self.bits }
pub fn from_bits_truncate(bits: $type) -> Self { $name{ bits } }
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
#[allow(warnings)]
mod cloudabi;
pub use self::cloudabi::*;

View File

@ -1,7 +0,0 @@
pub use crate::sys::cloudabi::shims::args::*;
#[allow(dead_code)]
pub fn init(_: isize, _: *const *const u8) {}
#[allow(dead_code)]
pub fn cleanup() {}

View File

@ -1,149 +0,0 @@
use crate::mem;
use crate::sync::atomic::{AtomicU32, Ordering};
use crate::sys::cloudabi::abi;
use crate::sys::mutex::{self, Mutex};
use crate::sys::time::checked_dur2intervals;
use crate::time::Duration;
extern "C" {
#[thread_local]
static __pthread_thread_id: abi::tid;
}
pub struct Condvar {
condvar: AtomicU32,
}
pub type MovableCondvar = Condvar;
unsafe impl Send for Condvar {}
unsafe impl Sync for Condvar {}
impl Condvar {
pub const fn new() -> Condvar {
Condvar { condvar: AtomicU32::new(abi::CONDVAR_HAS_NO_WAITERS.0) }
}
pub unsafe fn init(&mut self) {}
pub unsafe fn notify_one(&self) {
if self.condvar.load(Ordering::Relaxed) != abi::CONDVAR_HAS_NO_WAITERS.0 {
let ret = abi::condvar_signal(
&self.condvar as *const AtomicU32 as *mut abi::condvar,
abi::scope::PRIVATE,
1,
);
assert_eq!(ret, abi::errno::SUCCESS, "Failed to signal on condition variable");
}
}
pub unsafe fn notify_all(&self) {
if self.condvar.load(Ordering::Relaxed) != abi::CONDVAR_HAS_NO_WAITERS.0 {
let ret = abi::condvar_signal(
&self.condvar as *const AtomicU32 as *mut abi::condvar,
abi::scope::PRIVATE,
abi::nthreads::MAX,
);
assert_eq!(ret, abi::errno::SUCCESS, "Failed to broadcast on condition variable");
}
}
pub unsafe fn wait(&self, mutex: &Mutex) {
let mutex = mutex::raw(mutex);
assert_eq!(
mutex.load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
"This lock is not write-locked by this thread"
);
// Call into the kernel to wait on the condition variable.
let subscription = abi::subscription {
type_: abi::eventtype::CONDVAR,
union: abi::subscription_union {
condvar: abi::subscription_condvar {
condvar: &self.condvar as *const AtomicU32 as *mut abi::condvar,
condvar_scope: abi::scope::PRIVATE,
lock: mutex as *const AtomicU32 as *mut abi::lock,
lock_scope: abi::scope::PRIVATE,
},
},
..mem::zeroed()
};
let mut event: mem::MaybeUninit<abi::event> = mem::MaybeUninit::uninit();
let mut nevents: mem::MaybeUninit<usize> = mem::MaybeUninit::uninit();
let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr());
assert_eq!(ret, abi::errno::SUCCESS, "Failed to wait on condition variable");
assert_eq!(
event.assume_init().error,
abi::errno::SUCCESS,
"Failed to wait on condition variable"
);
}
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
let mutex = mutex::raw(mutex);
assert_eq!(
mutex.load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
"This lock is not write-locked by this thread"
);
// Call into the kernel to wait on the condition variable.
let timeout =
checked_dur2intervals(&dur).expect("overflow converting duration to nanoseconds");
let subscriptions = [
abi::subscription {
type_: abi::eventtype::CONDVAR,
union: abi::subscription_union {
condvar: abi::subscription_condvar {
condvar: &self.condvar as *const AtomicU32 as *mut abi::condvar,
condvar_scope: abi::scope::PRIVATE,
lock: mutex as *const AtomicU32 as *mut abi::lock,
lock_scope: abi::scope::PRIVATE,
},
},
..mem::zeroed()
},
abi::subscription {
type_: abi::eventtype::CLOCK,
union: abi::subscription_union {
clock: abi::subscription_clock {
clock_id: abi::clockid::MONOTONIC,
timeout,
..mem::zeroed()
},
},
..mem::zeroed()
},
];
let mut events: [mem::MaybeUninit<abi::event>; 2] = [mem::MaybeUninit::uninit(); 2];
let mut nevents: mem::MaybeUninit<usize> = mem::MaybeUninit::uninit();
let ret = abi::poll(
subscriptions.as_ptr(),
mem::MaybeUninit::slice_as_mut_ptr(&mut events),
2,
nevents.as_mut_ptr(),
);
assert_eq!(ret, abi::errno::SUCCESS, "Failed to wait on condition variable");
let nevents = nevents.assume_init();
for i in 0..nevents {
assert_eq!(
events[i].assume_init().error,
abi::errno::SUCCESS,
"Failed to wait on condition variable"
);
if events[i].assume_init().type_ == abi::eventtype::CONDVAR {
return true;
}
}
false
}
pub unsafe fn destroy(&self) {
assert_eq!(
self.condvar.load(Ordering::Relaxed),
abi::CONDVAR_HAS_NO_WAITERS.0,
"Attempted to destroy a condition variable with blocked threads"
);
}
}

View File

@ -1,47 +0,0 @@
use crate::mem;
#[derive(Copy, Clone)]
pub struct IoSlice<'a>(&'a [u8]);
impl<'a> IoSlice<'a> {
#[inline]
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
IoSlice(buf)
}
#[inline]
pub fn advance(&mut self, n: usize) {
self.0 = &self.0[n..]
}
#[inline]
pub fn as_slice(&self) -> &[u8] {
self.0
}
}
pub struct IoSliceMut<'a>(&'a mut [u8]);
impl<'a> IoSliceMut<'a> {
#[inline]
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
IoSliceMut(buf)
}
#[inline]
pub fn advance(&mut self, n: usize) {
let slice = mem::replace(&mut self.0, &mut []);
let (_, remaining) = slice.split_at_mut(n);
self.0 = remaining;
}
#[inline]
pub fn as_slice(&self) -> &[u8] {
self.0
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
self.0
}
}

View File

@ -1,73 +0,0 @@
#![deny(unsafe_op_in_unsafe_fn)]
use crate::io::ErrorKind;
use crate::mem;
#[path = "../unix/alloc.rs"]
pub mod alloc;
pub mod args;
#[path = "../unix/cmath.rs"]
pub mod cmath;
pub mod condvar;
pub mod io;
#[path = "../unix/memchr.rs"]
pub mod memchr;
pub mod mutex;
pub mod os;
pub mod rwlock;
pub mod stack_overflow;
pub mod stdio;
pub mod thread;
#[path = "../unix/thread_local_key.rs"]
pub mod thread_local_key;
pub mod time;
pub use crate::sys_common::os_str_bytes as os_str;
mod abi;
mod shims;
pub use self::shims::*;
#[allow(dead_code)]
pub fn init() {}
pub fn decode_error_kind(errno: i32) -> ErrorKind {
match errno {
x if x == abi::errno::ACCES as i32 => ErrorKind::PermissionDenied,
x if x == abi::errno::ADDRINUSE as i32 => ErrorKind::AddrInUse,
x if x == abi::errno::ADDRNOTAVAIL as i32 => ErrorKind::AddrNotAvailable,
x if x == abi::errno::AGAIN as i32 => ErrorKind::WouldBlock,
x if x == abi::errno::CONNABORTED as i32 => ErrorKind::ConnectionAborted,
x if x == abi::errno::CONNREFUSED as i32 => ErrorKind::ConnectionRefused,
x if x == abi::errno::CONNRESET as i32 => ErrorKind::ConnectionReset,
x if x == abi::errno::EXIST as i32 => ErrorKind::AlreadyExists,
x if x == abi::errno::INTR as i32 => ErrorKind::Interrupted,
x if x == abi::errno::INVAL as i32 => ErrorKind::InvalidInput,
x if x == abi::errno::NOENT as i32 => ErrorKind::NotFound,
x if x == abi::errno::NOTCONN as i32 => ErrorKind::NotConnected,
x if x == abi::errno::PERM as i32 => ErrorKind::PermissionDenied,
x if x == abi::errno::PIPE as i32 => ErrorKind::BrokenPipe,
x if x == abi::errno::TIMEDOUT as i32 => ErrorKind::TimedOut,
_ => ErrorKind::Other,
}
}
pub fn abort_internal() -> ! {
core::intrinsics::abort();
}
pub use libc::strlen;
pub fn hashmap_random_keys() -> (u64, u64) {
unsafe {
let mut v: mem::MaybeUninit<(u64, u64)> = mem::MaybeUninit::uninit();
libc::arc4random_buf(v.as_mut_ptr() as *mut libc::c_void, mem::size_of_val(&v));
v.assume_init()
}
}
#[cfg_attr(feature = "backtrace", link(name = "unwind"))]
#[link(name = "c")]
#[link(name = "compiler_rt")]
extern "C" {}

View File

@ -1,153 +0,0 @@
use crate::cell::Cell;
use crate::mem;
use crate::mem::MaybeUninit;
use crate::sync::atomic::{AtomicU32, Ordering};
use crate::sys::cloudabi::abi;
use crate::sys::rwlock::{self, RWLock};
extern "C" {
#[thread_local]
static __pthread_thread_id: abi::tid;
}
// Implement Mutex using an RWLock. This doesn't introduce any
// performance overhead in this environment, as the operations would be
// implemented identically.
pub struct Mutex(RWLock);
pub type MovableMutex = Mutex;
pub unsafe fn raw(m: &Mutex) -> &AtomicU32 {
rwlock::raw(&m.0)
}
impl Mutex {
pub const fn new() -> Mutex {
Mutex(RWLock::new())
}
pub unsafe fn init(&mut self) {
// This function should normally reinitialize the mutex after
// moving it to a different memory address. This implementation
// does not require adjustments after moving.
}
pub unsafe fn try_lock(&self) -> bool {
self.0.try_write()
}
pub unsafe fn lock(&self) {
self.0.write()
}
pub unsafe fn unlock(&self) {
self.0.write_unlock()
}
pub unsafe fn destroy(&self) {
self.0.destroy()
}
}
pub struct ReentrantMutex {
lock: AtomicU32,
recursion: Cell<u32>,
}
unsafe impl Send for ReentrantMutex {}
unsafe impl Sync for ReentrantMutex {}
impl ReentrantMutex {
pub const unsafe fn uninitialized() -> ReentrantMutex {
ReentrantMutex { lock: AtomicU32::new(abi::LOCK_UNLOCKED.0), recursion: Cell::new(0) }
}
pub unsafe fn init(&self) {}
pub unsafe fn try_lock(&self) -> bool {
// Attempt to acquire the lock.
if let Err(old) = self.lock.compare_exchange(
abi::LOCK_UNLOCKED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
Ordering::Acquire,
Ordering::Relaxed,
) {
// If we fail to acquire the lock, it may be the case
// that we've already acquired it and may need to recurse.
if old & !abi::LOCK_KERNEL_MANAGED.0 == __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0 {
self.recursion.set(self.recursion.get() + 1);
true
} else {
false
}
} else {
// Success.
assert_eq!(self.recursion.get(), 0, "Mutex has invalid recursion count");
true
}
}
pub unsafe fn lock(&self) {
if !self.try_lock() {
// Call into the kernel to acquire a write lock.
let lock = &self.lock as *const AtomicU32;
let subscription = abi::subscription {
type_: abi::eventtype::LOCK_WRLOCK,
union: abi::subscription_union {
lock: abi::subscription_lock {
lock: lock as *mut abi::lock,
lock_scope: abi::scope::PRIVATE,
},
},
..mem::zeroed()
};
let mut event = MaybeUninit::<abi::event>::uninit();
let mut nevents = MaybeUninit::<usize>::uninit();
// SAFE: The caller must to ensure that `event` and `nevents` are initialized.
let ret =
unsafe { abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr()) };
assert_eq!(ret, abi::errno::SUCCESS, "Failed to acquire mutex");
let event = event.assume_init();
assert_eq!(event.error, abi::errno::SUCCESS, "Failed to acquire mutex");
}
}
pub unsafe fn unlock(&self) {
assert_eq!(
self.lock.load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
"This mutex is locked by a different thread"
);
let r = self.recursion.get();
if r > 0 {
self.recursion.set(r - 1);
} else if !self
.lock
.compare_exchange(
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
abi::LOCK_UNLOCKED.0,
Ordering::Release,
Ordering::Relaxed,
)
.is_ok()
{
// Lock is managed by kernelspace. Call into the kernel
// to unblock waiting threads.
let ret = abi::lock_unlock(
&self.lock as *const AtomicU32 as *mut abi::lock,
abi::scope::PRIVATE,
);
assert_eq!(ret, abi::errno::SUCCESS, "Failed to unlock a mutex");
}
}
pub unsafe fn destroy(&self) {
assert_eq!(
self.lock.load(Ordering::Relaxed),
abi::LOCK_UNLOCKED.0,
"Attempted to destroy locked mutex"
);
assert_eq!(self.recursion.get(), 0, "Recursion counter invalid");
}
}

View File

@ -1,26 +0,0 @@
use crate::ffi::CStr;
use crate::str;
use libc::c_int;
pub use crate::sys::cloudabi::shims::os::*;
pub fn errno() -> i32 {
extern "C" {
#[thread_local]
static errno: c_int;
}
unsafe { errno as i32 }
}
/// Gets a detailed string description for the given error number.
pub fn error_string(errno: i32) -> String {
// cloudlibc's strerror() is guaranteed to be thread-safe. There is
// thus no need to use strerror_r().
str::from_utf8(unsafe { CStr::from_ptr(libc::strerror(errno)) }.to_bytes()).unwrap().to_owned()
}
pub fn exit(code: i32) -> ! {
unsafe { libc::exit(code as c_int) }
}

View File

@ -1,215 +0,0 @@
use crate::mem;
use crate::mem::MaybeUninit;
use crate::sync::atomic::{AtomicU32, Ordering};
use crate::sys::cloudabi::abi;
extern "C" {
#[thread_local]
static __pthread_thread_id: abi::tid;
}
#[thread_local]
static mut RDLOCKS_ACQUIRED: u32 = 0;
pub struct RWLock {
lock: AtomicU32,
}
pub unsafe fn raw(r: &RWLock) -> &AtomicU32 {
&r.lock
}
unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {}
impl RWLock {
pub const fn new() -> RWLock {
RWLock { lock: AtomicU32::new(abi::LOCK_UNLOCKED.0) }
}
pub unsafe fn try_read(&self) -> bool {
let mut old = abi::LOCK_UNLOCKED.0;
while let Err(cur) =
self.lock.compare_exchange_weak(old, old + 1, Ordering::Acquire, Ordering::Relaxed)
{
if (cur & abi::LOCK_WRLOCKED.0) != 0 {
// Another thread already has a write lock.
assert_ne!(
old & !abi::LOCK_KERNEL_MANAGED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
"Attempted to acquire a read lock while holding a write lock"
);
return false;
} else if (old & abi::LOCK_KERNEL_MANAGED.0) != 0 && RDLOCKS_ACQUIRED == 0 {
// Lock has threads waiting for the lock. Only acquire
// the lock if we have already acquired read locks. In
// that case, it is justified to acquire this lock to
// prevent a deadlock.
return false;
}
old = cur;
}
RDLOCKS_ACQUIRED += 1;
true
}
pub unsafe fn read(&self) {
if !self.try_read() {
// Call into the kernel to acquire a read lock.
let subscription = abi::subscription {
type_: abi::eventtype::LOCK_RDLOCK,
union: abi::subscription_union {
lock: abi::subscription_lock {
lock: &self.lock as *const AtomicU32 as *mut abi::lock,
lock_scope: abi::scope::PRIVATE,
},
},
..mem::zeroed()
};
let mut event = MaybeUninit::<abi::event>::uninit();
let mut nevents = MaybeUninit::<usize>::uninit();
let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr());
assert_eq!(ret, abi::errno::SUCCESS, "Failed to acquire read lock");
let event = event.assume_init();
assert_eq!(event.error, abi::errno::SUCCESS, "Failed to acquire read lock");
RDLOCKS_ACQUIRED += 1;
}
}
pub unsafe fn read_unlock(&self) {
// Perform a read unlock. We can do this in userspace, except when
// other threads are blocked and we are performing the last unlock.
// In that case, call into the kernel.
//
// Other threads may attempt to increment the read lock count,
// meaning that the call into the kernel could be spurious. To
// prevent this from happening, upgrade to a write lock first. This
// allows us to call into the kernel, having the guarantee that the
// lock value will not change in the meantime.
assert!(RDLOCKS_ACQUIRED > 0, "Bad lock count");
let mut old = 1;
loop {
if old == 1 | abi::LOCK_KERNEL_MANAGED.0 {
// Last read lock while threads are waiting. Attempt to upgrade
// to a write lock before calling into the kernel to unlock.
if let Err(cur) = self.lock.compare_exchange_weak(
old,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0 | abi::LOCK_KERNEL_MANAGED.0,
Ordering::Acquire,
Ordering::Relaxed,
) {
old = cur;
} else {
// Call into the kernel to unlock.
let ret = abi::lock_unlock(
&self.lock as *const AtomicU32 as *mut abi::lock,
abi::scope::PRIVATE,
);
assert_eq!(ret, abi::errno::SUCCESS, "Failed to write unlock a rwlock");
break;
}
} else {
// No threads waiting or not the last read lock. Just decrement
// the read lock count.
assert_ne!(old & !abi::LOCK_KERNEL_MANAGED.0, 0, "This rwlock is not locked");
assert_eq!(
old & abi::LOCK_WRLOCKED.0,
0,
"Attempted to read-unlock a write-locked rwlock"
);
if let Err(cur) = self.lock.compare_exchange_weak(
old,
old - 1,
Ordering::Acquire,
Ordering::Relaxed,
) {
old = cur;
} else {
break;
}
}
}
RDLOCKS_ACQUIRED -= 1;
}
pub unsafe fn try_write(&self) -> bool {
// Attempt to acquire the lock.
if let Err(old) = self.lock.compare_exchange(
abi::LOCK_UNLOCKED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
Ordering::Acquire,
Ordering::Relaxed,
) {
// Failure. Crash upon recursive acquisition.
assert_ne!(
old & !abi::LOCK_KERNEL_MANAGED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
"Attempted to recursive write-lock a rwlock",
);
false
} else {
// Success.
true
}
}
pub unsafe fn write(&self) {
if !self.try_write() {
// Call into the kernel to acquire a write lock.
let subscription = abi::subscription {
type_: abi::eventtype::LOCK_WRLOCK,
union: abi::subscription_union {
lock: abi::subscription_lock {
lock: &self.lock as *const AtomicU32 as *mut abi::lock,
lock_scope: abi::scope::PRIVATE,
},
},
..mem::zeroed()
};
let mut event = MaybeUninit::<abi::event>::uninit();
let mut nevents = MaybeUninit::<usize>::uninit();
let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr());
assert_eq!(ret, abi::errno::SUCCESS, "Failed to acquire write lock");
let event = event.assume_init();
assert_eq!(event.error, abi::errno::SUCCESS, "Failed to acquire write lock");
}
}
pub unsafe fn write_unlock(&self) {
assert_eq!(
self.lock.load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
"This rwlock is not write-locked by this thread"
);
if !self
.lock
.compare_exchange(
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
abi::LOCK_UNLOCKED.0,
Ordering::Release,
Ordering::Relaxed,
)
.is_ok()
{
// Lock is managed by kernelspace. Call into the kernel
// to unblock waiting threads.
let ret = abi::lock_unlock(
&self.lock as *const AtomicU32 as *mut abi::lock,
abi::scope::PRIVATE,
);
assert_eq!(ret, abi::errno::SUCCESS, "Failed to write unlock a rwlock");
}
}
pub unsafe fn destroy(&self) {
assert_eq!(
self.lock.load(Ordering::Relaxed),
abi::LOCK_UNLOCKED.0,
"Attempted to destroy locked rwlock"
);
}
}

View File

@ -1,35 +0,0 @@
use crate::ffi::OsString;
pub struct Args(());
impl Args {
pub fn inner_debug(&self) -> &[OsString] {
&[]
}
}
impl Iterator for Args {
type Item = OsString;
fn next(&mut self) -> Option<OsString> {
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(0))
}
}
impl ExactSizeIterator for Args {
fn len(&self) -> usize {
0
}
}
impl DoubleEndedIterator for Args {
fn next_back(&mut self) -> Option<OsString> {
None
}
}
pub fn args() -> Args {
Args(())
}

View File

@ -1,9 +0,0 @@
pub mod os {
pub const FAMILY: &str = "cloudabi";
pub const OS: &str = "cloudabi";
pub const DLL_PREFIX: &str = "lib";
pub const DLL_SUFFIX: &str = ".so";
pub const DLL_EXTENSION: &str = "so";
pub const EXE_SUFFIX: &str = "";
pub const EXE_EXTENSION: &str = "";
}

View File

@ -1,308 +0,0 @@
use crate::ffi::OsString;
use crate::fmt;
use crate::hash::{Hash, Hasher};
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
use crate::path::{Path, PathBuf};
use crate::sys::time::SystemTime;
use crate::sys::{unsupported, Void};
pub struct File(Void);
pub struct FileAttr(Void);
pub struct ReadDir(Void);
pub struct DirEntry(Void);
#[derive(Clone, Debug)]
pub struct OpenOptions {}
pub struct FilePermissions(Void);
pub struct FileType(Void);
#[derive(Debug)]
pub struct DirBuilder {}
impl FileAttr {
pub fn size(&self) -> u64 {
match self.0 {}
}
pub fn perm(&self) -> FilePermissions {
match self.0 {}
}
pub fn file_type(&self) -> FileType {
match self.0 {}
}
pub fn modified(&self) -> io::Result<SystemTime> {
match self.0 {}
}
pub fn accessed(&self) -> io::Result<SystemTime> {
match self.0 {}
}
pub fn created(&self) -> io::Result<SystemTime> {
match self.0 {}
}
}
impl Clone for FileAttr {
fn clone(&self) -> FileAttr {
match self.0 {}
}
}
impl FilePermissions {
pub fn readonly(&self) -> bool {
match self.0 {}
}
pub fn set_readonly(&mut self, _readonly: bool) {
match self.0 {}
}
}
impl Clone for FilePermissions {
fn clone(&self) -> FilePermissions {
match self.0 {}
}
}
impl PartialEq for FilePermissions {
fn eq(&self, _other: &FilePermissions) -> bool {
match self.0 {}
}
}
impl Eq for FilePermissions {}
impl fmt::Debug for FilePermissions {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
}
}
impl FileType {
pub fn is_dir(&self) -> bool {
match self.0 {}
}
pub fn is_file(&self) -> bool {
match self.0 {}
}
pub fn is_symlink(&self) -> bool {
match self.0 {}
}
}
impl Clone for FileType {
fn clone(&self) -> FileType {
match self.0 {}
}
}
impl Copy for FileType {}
impl PartialEq for FileType {
fn eq(&self, _other: &FileType) -> bool {
match self.0 {}
}
}
impl Eq for FileType {}
impl Hash for FileType {
fn hash<H: Hasher>(&self, _h: &mut H) {
match self.0 {}
}
}
impl fmt::Debug for FileType {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
}
}
impl fmt::Debug for ReadDir {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
}
}
impl Iterator for ReadDir {
type Item = io::Result<DirEntry>;
fn next(&mut self) -> Option<io::Result<DirEntry>> {
match self.0 {}
}
}
impl DirEntry {
pub fn path(&self) -> PathBuf {
match self.0 {}
}
pub fn file_name(&self) -> OsString {
match self.0 {}
}
pub fn metadata(&self) -> io::Result<FileAttr> {
match self.0 {}
}
pub fn file_type(&self) -> io::Result<FileType> {
match self.0 {}
}
}
impl OpenOptions {
pub fn new() -> OpenOptions {
OpenOptions {}
}
pub fn read(&mut self, _read: bool) {}
pub fn write(&mut self, _write: bool) {}
pub fn append(&mut self, _append: bool) {}
pub fn truncate(&mut self, _truncate: bool) {}
pub fn create(&mut self, _create: bool) {}
pub fn create_new(&mut self, _create_new: bool) {}
}
impl File {
pub fn open(_path: &Path, _opts: &OpenOptions) -> io::Result<File> {
unsupported()
}
pub fn file_attr(&self) -> io::Result<FileAttr> {
match self.0 {}
}
pub fn fsync(&self) -> io::Result<()> {
match self.0 {}
}
pub fn datasync(&self) -> io::Result<()> {
match self.0 {}
}
pub fn truncate(&self, _size: u64) -> io::Result<()> {
match self.0 {}
}
pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
match self.0 {}
}
pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
match self.0 {}
}
pub fn is_read_vectored(&self) -> bool {
match self.0 {}
}
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
match self.0 {}
}
pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result<usize> {
match self.0 {}
}
pub fn is_write_vectored(&self) -> bool {
match self.0 {}
}
pub fn flush(&self) -> io::Result<()> {
match self.0 {}
}
pub fn seek(&self, _pos: SeekFrom) -> io::Result<u64> {
match self.0 {}
}
pub fn duplicate(&self) -> io::Result<File> {
match self.0 {}
}
pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> {
match self.0 {}
}
pub fn diverge(&self) -> ! {
match self.0 {}
}
}
impl DirBuilder {
pub fn new() -> DirBuilder {
DirBuilder {}
}
pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
unsupported()
}
}
impl fmt::Debug for File {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
}
}
pub fn readdir(_p: &Path) -> io::Result<ReadDir> {
unsupported()
}
pub fn unlink(_p: &Path) -> io::Result<()> {
unsupported()
}
pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
unsupported()
}
pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> {
match perm.0 {}
}
pub fn rmdir(_p: &Path) -> io::Result<()> {
unsupported()
}
pub fn remove_dir_all(_path: &Path) -> io::Result<()> {
unsupported()
}
pub fn readlink(_p: &Path) -> io::Result<PathBuf> {
unsupported()
}
pub fn symlink(_original: &Path, _link: &Path) -> io::Result<()> {
unsupported()
}
pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
unsupported()
}
pub fn stat(_p: &Path) -> io::Result<FileAttr> {
unsupported()
}
pub fn lstat(_p: &Path) -> io::Result<FileAttr> {
unsupported()
}
pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
unsupported()
}
pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> {
unsupported()
}

View File

@ -1,19 +0,0 @@
use crate::io;
pub mod args;
pub mod env;
pub mod fs;
pub mod net;
pub mod os;
#[path = "../../unix/path.rs"]
pub mod path;
pub mod pipe;
pub mod process;
// This enum is used as the storage for a bunch of types which can't actually exist.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub enum Void {}
pub fn unsupported<T>() -> io::Result<T> {
Err(io::Error::new(io::ErrorKind::Other, "This function is not available on CloudABI."))
}

View File

@ -1,326 +0,0 @@
use crate::convert::TryFrom;
use crate::fmt;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
use crate::sys::{unsupported, Void};
use crate::time::Duration;
#[allow(unused_extern_crates)]
pub extern crate libc as netc;
pub struct TcpStream(Void);
impl TcpStream {
pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
unsupported()
}
pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
unsupported()
}
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
match self.0 {}
}
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
match self.0 {}
}
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
match self.0 {}
}
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
match self.0 {}
}
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
match self.0 {}
}
pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
match self.0 {}
}
pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
match self.0 {}
}
pub fn is_read_vectored(&self) -> bool {
match self.0 {}
}
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
match self.0 {}
}
pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> {
match self.0 {}
}
pub fn is_write_vectored(&self) -> bool {
match self.0 {}
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
}
pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
match self.0 {}
}
pub fn duplicate(&self) -> io::Result<TcpStream> {
match self.0 {}
}
pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
match self.0 {}
}
pub fn nodelay(&self) -> io::Result<bool> {
match self.0 {}
}
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
match self.0 {}
}
pub fn ttl(&self) -> io::Result<u32> {
match self.0 {}
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
match self.0 {}
}
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
match self.0 {}
}
}
impl fmt::Debug for TcpStream {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
}
}
pub struct TcpListener(Void);
impl TcpListener {
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
unsupported()
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
}
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
match self.0 {}
}
pub fn duplicate(&self) -> io::Result<TcpListener> {
match self.0 {}
}
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
match self.0 {}
}
pub fn ttl(&self) -> io::Result<u32> {
match self.0 {}
}
pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
match self.0 {}
}
pub fn only_v6(&self) -> io::Result<bool> {
match self.0 {}
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
match self.0 {}
}
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
match self.0 {}
}
}
impl fmt::Debug for TcpListener {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
}
}
pub struct UdpSocket(Void);
impl UdpSocket {
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
unsupported()
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
}
pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
match self.0 {}
}
pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
match self.0 {}
}
pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
match self.0 {}
}
pub fn duplicate(&self) -> io::Result<UdpSocket> {
match self.0 {}
}
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
match self.0 {}
}
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
match self.0 {}
}
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
match self.0 {}
}
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
match self.0 {}
}
pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
match self.0 {}
}
pub fn broadcast(&self) -> io::Result<bool> {
match self.0 {}
}
pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
match self.0 {}
}
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
match self.0 {}
}
pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
match self.0 {}
}
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
match self.0 {}
}
pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
match self.0 {}
}
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
match self.0 {}
}
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
match self.0 {}
}
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
match self.0 {}
}
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
match self.0 {}
}
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
match self.0 {}
}
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
match self.0 {}
}
pub fn ttl(&self) -> io::Result<u32> {
match self.0 {}
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
match self.0 {}
}
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
match self.0 {}
}
pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
match self.0 {}
}
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
match self.0 {}
}
pub fn send(&self, _: &[u8]) -> io::Result<usize> {
match self.0 {}
}
pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
match self.0 {}
}
}
impl fmt::Debug for UdpSocket {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
}
}
pub struct LookupHost(Void);
impl LookupHost {
pub fn port(&self) -> u16 {
match self.0 {}
}
}
impl Iterator for LookupHost {
type Item = SocketAddr;
fn next(&mut self) -> Option<SocketAddr> {
match self.0 {}
}
}
impl TryFrom<&str> for LookupHost {
type Error = io::Error;
fn try_from(_v: &str) -> io::Result<LookupHost> {
unsupported()
}
}
impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
type Error = io::Error;
fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
unsupported()
}
}

View File

@ -1,86 +0,0 @@
use crate::error::Error as StdError;
use crate::ffi::{OsStr, OsString};
use crate::fmt;
use crate::io;
use crate::iter;
use crate::path::{self, PathBuf};
use crate::sys::{unsupported, Void};
pub fn getcwd() -> io::Result<PathBuf> {
unsupported()
}
pub fn chdir(_: &path::Path) -> io::Result<()> {
unsupported()
}
pub type Env = iter::Empty<(OsString, OsString)>;
pub fn env() -> Env {
iter::empty()
}
pub fn getenv(_: &OsStr) -> io::Result<Option<OsString>> {
Ok(None)
}
pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
unsupported()
}
pub fn unsetenv(_: &OsStr) -> io::Result<()> {
unsupported()
}
pub struct SplitPaths<'a>(&'a Void);
pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> {
panic!("unsupported")
}
impl<'a> Iterator for SplitPaths<'a> {
type Item = PathBuf;
fn next(&mut self) -> Option<PathBuf> {
match *self.0 {}
}
}
#[derive(Debug)]
pub struct JoinPathsError;
pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
where
I: Iterator<Item = T>,
T: AsRef<OsStr>,
{
Err(JoinPathsError)
}
impl fmt::Display for JoinPathsError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
"not supported on CloudABI yet".fmt(f)
}
}
impl StdError for JoinPathsError {
#[allow(deprecated)]
fn description(&self) -> &str {
"not supported on CloudABI yet"
}
}
pub fn home_dir() -> Option<PathBuf> {
None
}
pub fn temp_dir() -> PathBuf {
PathBuf::from("/tmp")
}
pub fn current_exe() -> io::Result<PathBuf> {
unsupported()
}
pub fn getpid() -> u32 {
1
}

View File

@ -1,38 +0,0 @@
use crate::io::{self, IoSlice, IoSliceMut};
use crate::sys::Void;
pub struct AnonPipe(Void);
impl AnonPipe {
pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
match self.0 {}
}
pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
match self.0 {}
}
pub fn is_read_vectored(&self) -> bool {
match self.0 {}
}
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
match self.0 {}
}
pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result<usize> {
match self.0 {}
}
pub fn is_write_vectored(&self) -> bool {
match self.0 {}
}
pub fn diverge(&self) -> ! {
match self.0 {}
}
}
pub fn read2(p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> {
match p1.0 {}
}

View File

@ -1,149 +0,0 @@
use crate::ffi::OsStr;
use crate::fmt;
use crate::io;
use crate::sys::fs::File;
use crate::sys::pipe::AnonPipe;
use crate::sys::{unsupported, Void};
use crate::sys_common::process::CommandEnv;
pub use crate::ffi::OsString as EnvKey;
////////////////////////////////////////////////////////////////////////////////
// Command
////////////////////////////////////////////////////////////////////////////////
pub struct Command {
env: CommandEnv,
}
// passed back to std::process with the pipes connected to the child, if any
// were requested
pub struct StdioPipes {
pub stdin: Option<AnonPipe>,
pub stdout: Option<AnonPipe>,
pub stderr: Option<AnonPipe>,
}
pub enum Stdio {
Inherit,
Null,
MakePipe,
}
impl Command {
pub fn new(_program: &OsStr) -> Command {
Command { env: Default::default() }
}
pub fn arg(&mut self, _arg: &OsStr) {}
pub fn env_mut(&mut self) -> &mut CommandEnv {
&mut self.env
}
pub fn cwd(&mut self, _dir: &OsStr) {}
pub fn stdin(&mut self, _stdin: Stdio) {}
pub fn stdout(&mut self, _stdout: Stdio) {}
pub fn stderr(&mut self, _stderr: Stdio) {}
pub fn spawn(
&mut self,
_default: Stdio,
_needs_stdin: bool,
) -> io::Result<(Process, StdioPipes)> {
unsupported()
}
}
impl From<AnonPipe> for Stdio {
fn from(pipe: AnonPipe) -> Stdio {
pipe.diverge()
}
}
impl From<File> for Stdio {
fn from(file: File) -> Stdio {
file.diverge()
}
}
impl fmt::Debug for Command {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
}
}
pub struct ExitStatus(Void);
impl ExitStatus {
pub fn success(&self) -> bool {
match self.0 {}
}
pub fn code(&self) -> Option<i32> {
match self.0 {}
}
}
impl Clone for ExitStatus {
fn clone(&self) -> ExitStatus {
match self.0 {}
}
}
impl Copy for ExitStatus {}
impl PartialEq for ExitStatus {
fn eq(&self, _other: &ExitStatus) -> bool {
match self.0 {}
}
}
impl Eq for ExitStatus {}
impl fmt::Debug for ExitStatus {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
}
}
impl fmt::Display for ExitStatus {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {}
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct ExitCode(bool);
impl ExitCode {
pub const SUCCESS: ExitCode = ExitCode(false);
pub const FAILURE: ExitCode = ExitCode(true);
pub fn as_i32(&self) -> i32 {
self.0 as i32
}
}
pub struct Process(Void);
impl Process {
pub fn id(&self) -> u32 {
match self.0 {}
}
pub fn kill(&mut self) -> io::Result<()> {
match self.0 {}
}
pub fn wait(&mut self) -> io::Result<ExitStatus> {
match self.0 {}
}
pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
match self.0 {}
}
}

View File

@ -1,5 +0,0 @@
#![cfg_attr(test, allow(dead_code))]
pub unsafe fn init() {}
pub unsafe fn cleanup() {}

View File

@ -1,66 +0,0 @@
use crate::io;
use crate::sys::cloudabi::abi;
pub struct Stdin(());
pub struct Stdout(());
pub struct Stderr(());
impl Stdin {
pub const fn new() -> Stdin {
Stdin(())
}
}
impl io::Read for Stdin {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Ok(0)
}
}
impl Stdout {
pub const fn new() -> Stdout {
Stdout(())
}
}
impl io::Write for Stdout {
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
Err(io::Error::new(
io::ErrorKind::BrokenPipe,
"Stdout is not connected to any output in this environment",
))
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl Stderr {
pub const fn new() -> Stderr {
Stderr(())
}
}
impl io::Write for Stderr {
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
Err(io::Error::new(
io::ErrorKind::BrokenPipe,
"Stderr is not connected to any output in this environment",
))
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
pub fn is_ebadf(err: &io::Error) -> bool {
err.raw_os_error() == Some(abi::errno::BADF as i32)
}
pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
pub fn panic_output() -> Option<impl io::Write> {
Some(Stderr::new())
}

View File

@ -1,118 +0,0 @@
use crate::cmp;
use crate::ffi::CStr;
use crate::io;
use crate::mem;
use crate::ptr;
use crate::sys::cloudabi::abi;
use crate::sys::time::checked_dur2intervals;
use crate::time::Duration;
pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
pub struct Thread {
id: libc::pthread_t,
}
// CloudABI has pthread_t as a pointer in which case we still want
// a thread to be Send/Sync
unsafe impl Send for Thread {}
unsafe impl Sync for Thread {}
impl Thread {
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
let p = Box::into_raw(box p);
let mut native: libc::pthread_t = mem::zeroed();
let mut attr: libc::pthread_attr_t = mem::zeroed();
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
let stack_size = cmp::max(stack, min_stack_size(&attr));
assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
// Note: if the thread creation fails and this assert fails, then p will
// be leaked. However, an alternative design could cause double-free
// which is clearly worse.
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
return if ret != 0 {
// The thread failed to start and as a result p was not consumed. Therefore, it is
// safe to reconstruct the box so that it gets deallocated.
drop(Box::from_raw(p));
Err(io::Error::from_raw_os_error(ret))
} else {
Ok(Thread { id: native })
};
extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
unsafe {
// Let's run some code.
Box::from_raw(main as *mut Box<dyn FnOnce()>)();
}
ptr::null_mut()
}
}
pub fn yield_now() {
let ret = unsafe { abi::thread_yield() };
debug_assert_eq!(ret, abi::errno::SUCCESS);
}
pub fn set_name(_name: &CStr) {
// CloudABI has no way to set a thread name.
}
pub fn sleep(dur: Duration) {
let timeout =
checked_dur2intervals(&dur).expect("overflow converting duration to nanoseconds");
unsafe {
let subscription = abi::subscription {
type_: abi::eventtype::CLOCK,
union: abi::subscription_union {
clock: abi::subscription_clock {
clock_id: abi::clockid::MONOTONIC,
timeout,
..mem::zeroed()
},
},
..mem::zeroed()
};
let mut event = mem::MaybeUninit::<abi::event>::uninit();
let mut nevents = mem::MaybeUninit::<usize>::uninit();
let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr());
assert_eq!(ret, abi::errno::SUCCESS);
let event = event.assume_init();
assert_eq!(event.error, abi::errno::SUCCESS);
}
}
pub fn join(self) {
unsafe {
let ret = libc::pthread_join(self.id, ptr::null_mut());
mem::forget(self);
assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
}
}
}
impl Drop for Thread {
fn drop(&mut self) {
let ret = unsafe { libc::pthread_detach(self.id) };
debug_assert_eq!(ret, 0);
}
}
#[cfg_attr(test, allow(dead_code))]
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
libc::PTHREAD_STACK_MIN
}

View File

@ -1,82 +0,0 @@
use crate::mem;
use crate::sys::cloudabi::abi;
use crate::time::Duration;
const NSEC_PER_SEC: abi::timestamp = 1_000_000_000;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Instant {
t: abi::timestamp,
}
pub fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> {
dur.as_secs().checked_mul(NSEC_PER_SEC)?.checked_add(dur.subsec_nanos() as abi::timestamp)
}
impl Instant {
pub fn now() -> Instant {
unsafe {
let mut t: mem::MaybeUninit<abi::timestamp> = mem::MaybeUninit::uninit();
let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, t.as_mut_ptr());
assert_eq!(ret, abi::errno::SUCCESS);
Instant { t: t.assume_init() }
}
}
pub fn actually_monotonic() -> bool {
true
}
pub const fn zero() -> Instant {
Instant { t: 0 }
}
pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
let diff = self.t.checked_sub(other.t)?;
Some(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32))
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant { t: self.t.checked_add(checked_dur2intervals(other)?)? })
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant { t: self.t.checked_sub(checked_dur2intervals(other)?)? })
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct SystemTime {
t: abi::timestamp,
}
impl SystemTime {
pub fn now() -> SystemTime {
unsafe {
let mut t: mem::MaybeUninit<abi::timestamp> = mem::MaybeUninit::uninit();
let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, t.as_mut_ptr());
assert_eq!(ret, abi::errno::SUCCESS);
SystemTime { t: t.assume_init() }
}
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
if self.t >= other.t {
let diff = self.t - other.t;
Ok(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32))
} else {
let diff = other.t - self.t;
Err(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32))
}
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime { t: self.t.checked_add(checked_dur2intervals(other)?)? })
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime { t: self.t.checked_sub(checked_dur2intervals(other)?)? })
}
}
pub const UNIX_EPOCH: SystemTime = SystemTime { t: 0 };

View File

@ -32,9 +32,6 @@ cfg_if::cfg_if! {
} else if #[cfg(windows)] { } else if #[cfg(windows)] {
mod windows; mod windows;
pub use self::windows::*; pub use self::windows::*;
} else if #[cfg(target_os = "cloudabi")] {
mod cloudabi;
pub use self::cloudabi::*;
} else if #[cfg(target_os = "hermit")] { } else if #[cfg(target_os = "hermit")] {
mod hermit; mod hermit;
pub use self::hermit::*; pub use self::hermit::*;
@ -63,11 +60,10 @@ cfg_if::cfg_if! {
// On unix we'll document what's already available // On unix we'll document what's already available
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub use self::ext as unix_ext; pub use self::ext as unix_ext;
} else if #[cfg(any(target_os = "cloudabi", } else if #[cfg(any(target_os = "hermit",
target_os = "hermit",
target_arch = "wasm32", target_arch = "wasm32",
all(target_vendor = "fortanix", target_env = "sgx")))] { all(target_vendor = "fortanix", target_env = "sgx")))] {
// On CloudABI and wasm right now the module below doesn't compile // On wasm right now the module below doesn't compile
// (missing things in `libc` which is empty) so just omit everything // (missing things in `libc` which is empty) so just omit everything
// with an empty module // with an empty module
#[unstable(issue = "none", feature = "std_internals")] #[unstable(issue = "none", feature = "std_internals")]
@ -88,11 +84,10 @@ cfg_if::cfg_if! {
#[allow(missing_docs)] #[allow(missing_docs)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub use self::ext as windows_ext; pub use self::ext as windows_ext;
} else if #[cfg(any(target_os = "cloudabi", } else if #[cfg(any(target_os = "hermit",
target_os = "hermit",
target_arch = "wasm32", target_arch = "wasm32",
all(target_vendor = "fortanix", target_env = "sgx")))] { all(target_vendor = "fortanix", target_env = "sgx")))] {
// On CloudABI and wasm right now the shim below doesn't compile, so // On wasm right now the shim below doesn't compile, so
// just omit it // just omit it
#[unstable(issue = "none", feature = "std_internals")] #[unstable(issue = "none", feature = "std_internals")]
#[allow(missing_docs)] #[allow(missing_docs)]

View File

@ -71,8 +71,7 @@ pub mod util;
pub mod wtf8; pub mod wtf8;
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(any(target_os = "cloudabi", if #[cfg(any(target_os = "l4re",
target_os = "l4re",
target_os = "hermit", target_os = "hermit",
feature = "restricted-std", feature = "restricted-std",
all(target_arch = "wasm32", not(target_os = "emscripten")), all(target_arch = "wasm32", not(target_os = "emscripten")),

View File

@ -70,7 +70,6 @@ cfg_if::cfg_if! {
} }
} else if #[cfg(any( } else if #[cfg(any(
target_os = "android", target_os = "android",
target_os = "cloudabi",
target_os = "emscripten", target_os = "emscripten",
target_os = "fuchsia", target_os = "fuchsia",
target_os = "ios", target_os = "ios",

View File

@ -83,7 +83,6 @@ pub use core::time::Duration;
/// ///
/// | Platform | System call | /// | Platform | System call |
/// |:---------:|:--------------------------------------------------------------------:| /// |:---------:|:--------------------------------------------------------------------:|
/// | CloudABI | [clock_time_get (Monotonic Clock)] |
/// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] | /// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] |
/// | UNIX | [clock_gettime (Monotonic Clock)] | /// | UNIX | [clock_gettime (Monotonic Clock)] |
/// | Darwin | [mach_absolute_time] | /// | Darwin | [mach_absolute_time] |
@ -97,7 +96,6 @@ pub use core::time::Duration;
/// [__wasi_clock_time_get (Monotonic Clock)]: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md#clock_time_get /// [__wasi_clock_time_get (Monotonic Clock)]: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md#clock_time_get
/// [clock_gettime (Monotonic Clock)]: https://linux.die.net/man/3/clock_gettime /// [clock_gettime (Monotonic Clock)]: https://linux.die.net/man/3/clock_gettime
/// [mach_absolute_time]: https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html /// [mach_absolute_time]: https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html
/// [clock_time_get (Monotonic Clock)]: https://nuxi.nl/cloudabi/#clock_time_get
/// ///
/// **Disclaimer:** These system calls might change over time. /// **Disclaimer:** These system calls might change over time.
/// ///
@ -161,7 +159,6 @@ pub struct Instant(time::Instant);
/// ///
/// | Platform | System call | /// | Platform | System call |
/// |:---------:|:--------------------------------------------------------------------:| /// |:---------:|:--------------------------------------------------------------------:|
/// | CloudABI | [clock_time_get (Realtime Clock)] |
/// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] | /// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] |
/// | UNIX | [clock_gettime (Realtime Clock)] | /// | UNIX | [clock_gettime (Realtime Clock)] |
/// | Darwin | [gettimeofday] | /// | Darwin | [gettimeofday] |
@ -169,7 +166,6 @@ pub struct Instant(time::Instant);
/// | WASI | [__wasi_clock_time_get (Realtime Clock)] | /// | WASI | [__wasi_clock_time_get (Realtime Clock)] |
/// | Windows | [GetSystemTimePreciseAsFileTime] / [GetSystemTimeAsFileTime] | /// | Windows | [GetSystemTimePreciseAsFileTime] / [GetSystemTimeAsFileTime] |
/// ///
/// [clock_time_get (Realtime Clock)]: https://nuxi.nl/cloudabi/#clock_time_get
/// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time /// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time
/// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode /// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode
/// [gettimeofday]: http://man7.org/linux/man-pages/man2/gettimeofday.2.html /// [gettimeofday]: http://man7.org/linux/man-pages/man2/gettimeofday.2.html

View File

@ -20,7 +20,7 @@
#![crate_name = "test"] #![crate_name = "test"]
#![unstable(feature = "test", issue = "50297")] #![unstable(feature = "test", issue = "50297")]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
#![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))] #![cfg_attr(unix, feature(libc))]
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(nll)] #![feature(nll)]
#![feature(bool_to_option)] #![feature(bool_to_option)]

View File

@ -44,8 +44,6 @@ fn main() {
println!("cargo:rustc-link-lib=gcc_s"); println!("cargo:rustc-link-lib=gcc_s");
} else if target.contains("redox") { } else if target.contains("redox") {
// redox is handled in lib.rs // redox is handled in lib.rs
} else if target.contains("cloudabi") {
println!("cargo:rustc-link-lib=unwind");
} }
} }

View File

@ -20,7 +20,6 @@ cfg_if::cfg_if! {
unix, unix,
windows, windows,
target_os = "psp", target_os = "psp",
target_os = "cloudabi",
all(target_vendor = "fortanix", target_env = "sgx"), all(target_vendor = "fortanix", target_env = "sgx"),
))] { ))] {
mod libunwind; mod libunwind;

View File

@ -32,7 +32,4 @@ ignore = [
"src/tools/rust-analyzer", "src/tools/rust-analyzer",
"src/tools/rustfmt", "src/tools/rustfmt",
"src/tools/rust-installer", "src/tools/rust-installer",
# We do not format this file as it is externally sourced and auto-generated.
"library/std/src/sys/cloudabi/abi/cloudabi.rs",
] ]

View File

@ -1,40 +0,0 @@
#!/bin/bash
set -eux
# Install prerequisites.
apt-get update
apt-get install -y --no-install-recommends \
apt-transport-https \
ca-certificates \
clang-5.0 \
cmake \
curl \
file \
g++ \
gdb \
git \
lld-5.0 \
make \
ninja-build \
python \
sudo \
xz-utils
# Set up a Clang-based cross compiler toolchain.
# Based on the steps described at https://nuxi.nl/cloudabi/debian/
target=$1
for tool in ar nm objdump ranlib size; do
ln -s ../lib/llvm-5.0/bin/llvm-${tool} /usr/bin/${target}-${tool}
done
ln -s ../lib/llvm-5.0/bin/clang /usr/bin/${target}-cc
ln -s ../lib/llvm-5.0/bin/clang /usr/bin/${target}-c++
ln -s ../lib/llvm-5.0/bin/lld /usr/bin/${target}-ld
ln -s ../../${target} /usr/lib/llvm-5.0/${target}
# Install the C++ runtime libraries from CloudABI Ports.
apt-key adv --batch --yes --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0DA51B8531344B15
add-apt-repository -y 'deb https://nuxi.nl/distfiles/cloudabi-ports/debian/ cloudabi cloudabi'
apt-get update
apt-get install -y "${target//_/-}-cxx-runtime"

View File

@ -153,7 +153,6 @@ not available.
target | std | host | notes target | std | host | notes
-------|-----|------|------- -------|-----|------|-------
`aarch64-apple-tvos` | * | | ARM64 tvOS `aarch64-apple-tvos` | * | | ARM64 tvOS
`aarch64-unknown-cloudabi` | ✓ | | ARM64 CloudABI
`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
`aarch64-unknown-hermit` | ? | | `aarch64-unknown-hermit` | ? | |
`aarch64-unknown-netbsd` | ? | | `aarch64-unknown-netbsd` | ? | |
@ -165,7 +164,6 @@ target | std | host | notes
`armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
`armv6-unknown-netbsd-eabihf` | ? | | `armv6-unknown-netbsd-eabihf` | ? | |
`armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8 `armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8
`armv7-unknown-cloudabi-eabihf` | ✓ | | ARMv7 CloudABI, hardfloat
`armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
`armv7-unknown-netbsd-eabihf` | ? | | `armv7-unknown-netbsd-eabihf` | ? | |
`armv7-wrs-vxworks-eabihf` | ? | | `armv7-wrs-vxworks-eabihf` | ? | |
@ -176,7 +174,6 @@ target | std | host | notes
`i386-apple-ios` | ✓ | | 32-bit x86 iOS `i386-apple-ios` | ✓ | | 32-bit x86 iOS
`i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.7+, Lion+) `i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.7+, Lion+)
`i686-pc-windows-msvc` | ✓ | | 32-bit Windows XP support `i686-pc-windows-msvc` | ✓ | | 32-bit Windows XP support
`i686-unknown-cloudabi` | ✓ | | 32-bit CloudABI
`i686-unknown-uefi` | ? | | 32-bit UEFI `i686-unknown-uefi` | ? | | 32-bit UEFI
`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku
`i686-unknown-netbsd` | ✓ | | NetBSD/i386 with SSE2 `i686-unknown-netbsd` | ✓ | | NetBSD/i386 with SSE2
@ -215,7 +212,6 @@ target | std | host | notes
`x86_64-linux-kernel` | * | | Linux kernel modules `x86_64-linux-kernel` | * | | Linux kernel modules
`x86_64-pc-solaris` | ? | | `x86_64-pc-solaris` | ? | |
`x86_64-pc-windows-msvc` | ✓ | | 64-bit Windows XP support `x86_64-pc-windows-msvc` | ✓ | | 64-bit Windows XP support
`x86_64-unknown-cloudabi` | ✓ | | 64-bit CloudABI
`x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD
`x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
`x86_64-unknown-hermit` | ? | | `x86_64-unknown-hermit` | ? | |

View File

@ -1,6 +1,5 @@
// This test is for *-windows-msvc only. // This test is for *-windows-msvc only.
// ignore-android // ignore-android
// ignore-cloudabi
// ignore-dragonfly // ignore-dragonfly
// ignore-emscripten // ignore-emscripten
// ignore-freebsd // ignore-freebsd

View File

@ -1,6 +1,5 @@
// This test is for *-windows-msvc only. // This test is for *-windows-msvc only.
// ignore-android // ignore-android
// ignore-cloudabi
// ignore-dragonfly // ignore-dragonfly
// ignore-emscripten // ignore-emscripten
// ignore-freebsd // ignore-freebsd

View File

@ -1,4 +1,3 @@
// ignore-cloudabi
// ignore-emscripten // ignore-emscripten
// ignore-sgx no processes // ignore-sgx no processes
// ignore-macos this needs valgrind 3.11 or higher; see // ignore-macos this needs valgrind 3.11 or higher; see

View File

@ -1,7 +1,6 @@
// run-pass // run-pass
#![allow(unused_imports)] #![allow(unused_imports)]
// ignore-cloudabi can't run commands
// ignore-emscripten can't run commands // ignore-emscripten can't run commands
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -8,7 +8,6 @@
// ignore-sparc // ignore-sparc
// ignore-sparc64 // ignore-sparc64
// ignore-wasm // ignore-wasm
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes
// ignore-musl FIXME #31506 // ignore-musl FIXME #31506

View File

@ -8,7 +8,6 @@
// ignore-sparc // ignore-sparc
// ignore-sparc64 // ignore-sparc64
// ignore-wasm // ignore-wasm
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,6 +1,5 @@
// run-pass // run-pass
// ignore-android no libc // ignore-android no libc
// ignore-cloudabi no libc
// ignore-emscripten no libc // ignore-emscripten no libc
// ignore-sgx no libc // ignore-sgx no libc
// ignore-wasm32 no libc // ignore-wasm32 no libc

View File

@ -1,6 +1,5 @@
// run-pass // run-pass
// ignore-android no libc // ignore-android no libc
// ignore-cloudabi no libc
// ignore-emscripten no libc // ignore-emscripten no libc
// ignore-sgx no libc // ignore-sgx no libc
// ignore-wasm32 no libc // ignore-wasm32 no libc

View File

@ -2,7 +2,6 @@
#![allow(unused_must_use)] #![allow(unused_must_use)]
#![allow(deprecated)] #![allow(deprecated)]
// ignore-cloudabi no process support
// ignore-emscripten no threads support // ignore-emscripten no threads support
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -9,7 +9,6 @@
// compile-flags:-g -Cllvm-args=-enable-tail-merge=0 -Cllvm-args=-opt-bisect-limit=0 // compile-flags:-g -Cllvm-args=-enable-tail-merge=0 -Cllvm-args=-opt-bisect-limit=0
// compile-flags:-Cforce-frame-pointers=yes // compile-flags:-Cforce-frame-pointers=yes
// ignore-pretty issue #37195 // ignore-pretty issue #37195
// ignore-cloudabi spawning processes is not supported
// ignore-emscripten spawning processes is not supported // ignore-emscripten spawning processes is not supported
// ignore-sgx no processes // ignore-sgx no processes
// normalize-stderr-test ".*\n" -> "" // normalize-stderr-test ".*\n" -> ""

View File

@ -1,6 +1,5 @@
// run-pass // run-pass
// ignore-android FIXME #17520 // ignore-android FIXME #17520
// ignore-cloudabi spawning processes is not supported
// ignore-emscripten spawning processes is not supported // ignore-emscripten spawning processes is not supported
// ignore-openbsd no support for libbacktrace without filename // ignore-openbsd no support for libbacktrace without filename
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,6 +1,5 @@
// run-pass // run-pass
// pretty-expanded FIXME #23616 // pretty-expanded FIXME #23616
// ignore-cloudabi no target_family
// ignore-wasm32-bare no target_family // ignore-wasm32-bare no target_family
// ignore-sgx // ignore-sgx

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no target_family
// ignore-wasm32-bare no target_family // ignore-wasm32-bare no target_family
// ignore-sgx // ignore-sgx

View File

@ -2,7 +2,6 @@
// Test that cleanups for the RHS of shortcircuiting operators work. // Test that cleanups for the RHS of shortcircuiting operators work.
// pretty-expanded FIXME #23616 // pretty-expanded FIXME #23616
// ignore-cloudabi no std::env support
use std::env; use std::env;

View File

@ -1,7 +1,6 @@
// run-pass // run-pass
// ignore-windows - this is a unix-specific test // ignore-windows - this is a unix-specific test
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes
use std::os::unix::process::CommandExt; use std::os::unix::process::CommandExt;

View File

@ -1,7 +1,6 @@
// run-pass // run-pass
// ignore-windows - this is a unix-specific test // ignore-windows - this is a unix-specific test
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes
use std::env; use std::env;

View File

@ -3,7 +3,6 @@
#![allow(stable_features)] #![allow(stable_features)]
// ignore-windows - this is a unix-specific test // ignore-windows - this is a unix-specific test
// ignore-pretty issue #37199 // ignore-pretty issue #37199
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -2,7 +2,6 @@
#![allow(stable_features)] #![allow(stable_features)]
// ignore-windows - this is a unix-specific test // ignore-windows - this is a unix-specific test
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes
#![feature(process_exec, rustc_private)] #![feature(process_exec, rustc_private)]

View File

@ -1,6 +1,5 @@
// run-pass // run-pass
// ignore-android // ignore-android
// ignore-cloudabi
// ignore-emscripten // ignore-emscripten
// ignore-sgx // ignore-sgx

View File

@ -5,7 +5,6 @@
#![allow(deprecated)] #![allow(deprecated)]
#![allow(unused_imports)] #![allow(unused_imports)]
// compile-flags:--test // compile-flags:--test
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes
// ignore-vxworks no 'cat' and 'sleep' // ignore-vxworks no 'cat' and 'sleep'

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -3,7 +3,6 @@
// ignore-android // ignore-android
// ignore-windows // ignore-windows
// ignore-cloudabi no execve
// ignore-emscripten no execve // ignore-emscripten no execve
// ignore-sgx no execve // ignore-sgx no execve
// ignore-vxworks no execve // ignore-vxworks no execve

View File

@ -2,7 +2,6 @@
#![allow(unused_variables)] #![allow(unused_variables)]
#![allow(deprecated)] #![allow(deprecated)]
// ignore-cloudabi no environment variables present
// ignore-emscripten env vars don't work? // ignore-emscripten env vars don't work?
// ignore-sgx env vars cannot be modified // ignore-sgx env vars cannot be modified

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no env vars
// ignore-wasm32-bare no env vars // ignore-wasm32-bare no env vars
use std::env::*; use std::env::*;

View File

@ -1,5 +1,3 @@
// ignore-cloudabi no std::path
use std::path::Path; use std::path::Path;
trait Foo { trait Foo {

View File

@ -1,5 +1,5 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/E0277.rs:13:6 --> $DIR/E0277.rs:11:6
| |
LL | fn f(p: Path) { } LL | fn f(p: Path) { }
| ^ doesn't have a size known at compile-time | ^ doesn't have a size known at compile-time
@ -13,7 +13,7 @@ LL | fn f(&p: Path) { }
| ^ | ^
error[E0277]: the trait bound `i32: Foo` is not satisfied error[E0277]: the trait bound `i32: Foo` is not satisfied
--> $DIR/E0277.rs:17:15 --> $DIR/E0277.rs:15:15
| |
LL | fn some_func<T: Foo>(foo: T) { LL | fn some_func<T: Foo>(foo: T) {
| --- required by this bound in `some_func` | --- required by this bound in `some_func`

View File

@ -1,6 +1,5 @@
// run-pass // run-pass
// exec-env:TEST_EXEC_ENV=22 // exec-env:TEST_EXEC_ENV=22
// ignore-cloudabi no env vars
// ignore-emscripten FIXME: issue #31622 // ignore-emscripten FIXME: issue #31622
// ignore-sgx unsupported // ignore-sgx unsupported

View File

@ -1,7 +1,6 @@
// run-pass // run-pass
// ignore-windows // ignore-windows
// ignore-android // ignore-android
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-haiku // ignore-haiku
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -11,7 +11,6 @@ mod rusti {
} }
#[cfg(any(target_os = "android", #[cfg(any(target_os = "android",
target_os = "cloudabi",
target_os = "dragonfly", target_os = "dragonfly",
target_os = "emscripten", target_os = "emscripten",
target_os = "freebsd", target_os = "freebsd",

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -2,7 +2,6 @@
// aux-build:issue-12133-rlib.rs // aux-build:issue-12133-rlib.rs
// aux-build:issue-12133-dylib.rs // aux-build:issue-12133-dylib.rs
// aux-build:issue-12133-dylib2.rs // aux-build:issue-12133-dylib2.rs
// ignore-cloudabi no dylib support
// ignore-emscripten no dylib support // ignore-emscripten no dylib support
// ignore-musl // ignore-musl
// ignore-sgx no dylib support // ignore-sgx no dylib support

View File

@ -1,6 +1,5 @@
// run-pass // run-pass
#![allow(unused_mut)] #![allow(unused_mut)]
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,6 +1,5 @@
// run-pass // run-pass
#![allow(unused_mut)] #![allow(unused_mut)]
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,7 +1,6 @@
// check-pass // check-pass
#![allow(dead_code)] #![allow(dead_code)]
// pretty-expanded FIXME #23616 // pretty-expanded FIXME #23616
// ignore-cloudabi no std::fs
use std::fs::File; use std::fs::File;
use std::io::{self, BufReader, Read}; use std::io::{self, BufReader, Read};

View File

@ -1,7 +1,6 @@
// run-pass // run-pass
#![allow(stable_features)] #![allow(stable_features)]
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -7,7 +7,6 @@
// had to do with codegen ignoring binders. // had to do with codegen ignoring binders.
// pretty-expanded FIXME #23616 // pretty-expanded FIXME #23616
// ignore-cloudabi no std::fs
#![feature(os)] #![feature(os)]

View File

@ -1,5 +1,4 @@
// build-pass // build-pass
// ignore-cloudabi no std::fs
// Regression test for #20797. // Regression test for #20797.

View File

@ -24,7 +24,7 @@ mod m {
use libc::{c_double, c_int}; use libc::{c_double, c_int};
extern { extern {
#[cfg(any(all(unix, not(target_os = "vxworks")), target_os = "cloudabi"))] #[cfg(all(unix, not(target_os = "vxworks")))]
#[link_name="lgamma_r"] #[link_name="lgamma_r"]
pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double; pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double;
#[cfg(windows)] #[cfg(windows)]

View File

@ -1,7 +1,6 @@
// run-pass // run-pass
#![allow(dead_code)] #![allow(dead_code)]
// pretty-expanded FIXME #23616 // pretty-expanded FIXME #23616
// ignore-cloudabi no std::fs
use std::{fs, net}; use std::{fs, net};

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no std::path
use std::collections::HashMap; use std::collections::HashMap;
use std::path::Path; use std::path::Path;

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no std::path
use std::collections::HashMap; use std::collections::HashMap;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no processes
// ignore-emscripten no threads // ignore-emscripten no threads
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no std::env
// ignore-wasm32 issue 42629 // ignore-wasm32 issue 42629
#[inline(never)] #[inline(never)]

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes // ignore-emscripten no processes
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,5 +1,4 @@
// compile-flags: -Z unpretty=mir // compile-flags: -Z unpretty=mir
// ignore-cloudabi no std::path
use std::path::MAIN_SEPARATOR; use std::path::MAIN_SEPARATOR;

View File

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-37665.rs:10:17 --> $DIR/issue-37665.rs:9:17
| |
LL | let x: () = 0; LL | let x: () = 0;
| -- ^ expected `()`, found integer | -- ^ expected `()`, found integer

View File

@ -4,7 +4,6 @@
// these platforms also. // these platforms also.
// ignore-windows // ignore-windows
// ignore-cloudabi
// ignore-emscripten // ignore-emscripten
// ignore-sgx no processes // ignore-sgx no processes

View File

@ -1,5 +1,5 @@
error[E0599]: no method named `exec` found for mutable reference `&mut Command` in the current scope error[E0599]: no method named `exec` found for mutable reference `&mut Command` in the current scope
--> $DIR/issue-39175.rs:15:39 --> $DIR/issue-39175.rs:14:39
| |
LL | Command::new("echo").arg("hello").exec(); LL | Command::new("echo").arg("hello").exec();
| ^^^^ method not found in `&mut Command` | ^^^^ method not found in `&mut Command`

View File

@ -1,5 +1,4 @@
// run-pass // run-pass
// ignore-cloudabi no std::env
fn parse_args() -> String { fn parse_args() -> String {
let args: Vec<_> = ::std::env::args().collect(); let args: Vec<_> = ::std::env::args().collect();

View File

@ -1,6 +1,5 @@
// run-pass // run-pass
// pretty-expanded FIXME #23616 // pretty-expanded FIXME #23616
// ignore-cloudabi no std::env
use std::env; use std::env;

Some files were not shown because too many files have changed in this diff Show More