From 510cb2f72001306432885cfa0462d568774cf6c2 Mon Sep 17 00:00:00 2001 From: Ed Schouten <ed@nuxi.nl> Date: Wed, 27 Dec 2017 14:42:19 +0100 Subject: [PATCH] Add support for CloudABI. CloudABI is a sandboxed UNIX-like runtime environment, based on the principle of capability-based security. As CloudABI is intended to be cross-platform, the system call layer is specified here: https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt From these definitions, we automatically generate C and Rust bindings. The latter is published on crates.io: https://crates.io/crates/cloudabi My goal is to implement libstd for CloudABI in such a way that it uses the C library as little as possible; only in places where it would ease interfacing with C code (e.g., thread creation). In places where constants in the C library are directly based on the CloudABI specification (e.g., errnos), use the constants provided by the cloudabi crate. --- Cargo.lock | 18 +++++ Cargo.toml | 3 + src/cloudabi/aarch64.rs | 4 ++ src/cloudabi/mod.rs | 141 ++++++++++++++++++++++++++++++++++++++++ src/cloudabi/x86.rs | 4 ++ src/cloudabi/x86_64.rs | 4 ++ src/lib.rs | 3 + 7 files changed, 177 insertions(+) create mode 100644 src/cloudabi/aarch64.rs create mode 100644 src/cloudabi/mod.rs create mode 100644 src/cloudabi/x86.rs create mode 100644 src/cloudabi/x86_64.rs diff --git a/Cargo.lock b/Cargo.lock index 804871d6..395a6d75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,11 +8,24 @@ name = "bitflags" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bitflags" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cc" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cloudabi" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ctest" version = "0.1.6" @@ -76,6 +89,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" version = "0.2.34" +dependencies = [ + "cloudabi 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "libc-test" @@ -256,7 +272,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" +"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" +"checksum cloudabi 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91833d57fabae4915bc772175e83f4830805b9e3b26c1c1fc85e4fd2339963cb" "checksum ctest 0.1.6 (git+https://github.com/alexcrichton/ctest)" = "<none>" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum extprim 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1de79797db68eb235c616cc3ad1a2793fa94a2245594cb6f81d602e62ed951c5" diff --git a/Cargo.toml b/Cargo.toml index c8850420..167187ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,9 @@ other common platform libraries. travis-ci = { repository = "rust-lang/libc" } appveyor = { repository = "rust-lang/libc", project_name = "rust-lang-libs/libc" } +[target.'cfg(target_os = "cloudabi")'.dependencies] +cloudabi = "0.0.1" + [features] default = ["use_std"] use_std = [] diff --git a/src/cloudabi/aarch64.rs b/src/cloudabi/aarch64.rs new file mode 100644 index 00000000..e9e2473d --- /dev/null +++ b/src/cloudabi/aarch64.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = u32; diff --git a/src/cloudabi/mod.rs b/src/cloudabi/mod.rs new file mode 100644 index 00000000..d5b63d49 --- /dev/null +++ b/src/cloudabi/mod.rs @@ -0,0 +1,141 @@ +extern crate cloudabi; + +pub type in_addr_t = u32; +pub type in_port_t = u16; +pub type pthread_key_t = usize; +pub type pthread_t = usize; +pub type sa_family_t = u8; +pub type socklen_t = usize; + +s! { + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + pub ai_addrlen: ::socklen_t, + pub ai_addr: *mut ::sockaddr, + pub ai_canonname: *mut ::c_char, + pub ai_next: *mut addrinfo, + } + + pub struct in_addr { + pub s_addr: in_addr_t, + } + + pub struct in6_addr { + pub s6_addr: [u8; 16], + } + + pub struct pthread_attr_t { + __detachstate: ::c_int, + __stacksize: usize, + } + + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 0], + } + + pub struct sockaddr_in { + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + } + + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + pub struct sockaddr_storage { + pub ss_family: ::sa_family_t, + __ss_data: [u8; 32], + } +} + +extern "C" { + pub fn freeaddrinfo(res: *mut addrinfo); + pub fn gai_strerror(errcode: ::c_int) -> *const ::c_char; + pub fn getaddrinfo( + node: *const c_char, + service: *const c_char, + hints: *const addrinfo, + res: *mut *mut addrinfo, + ) -> ::c_int; + pub fn getsockopt( + sockfd: ::c_int, + level: ::c_int, + optname: ::c_int, + optval: *mut ::c_void, + optlen: *mut ::socklen_t, + ) -> ::c_int; + pub fn posix_memalign(memptr: *mut *mut ::c_void, align: ::size_t, size: ::size_t) -> ::c_int; + pub fn pthread_attr_destroy(attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_init(attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_setstacksize(attr: *mut ::pthread_attr_t, stack_size: ::size_t) -> ::c_int; + pub fn pthread_create( + native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_detach(thread: ::pthread_t) -> ::c_int; + pub fn pthread_getspecific(key: pthread_key_t) -> *mut ::c_void; + pub fn pthread_join(native: ::pthread_t, value: *mut *mut ::c_void) -> ::c_int; + pub fn pthread_key_create( + key: *mut pthread_key_t, + dtor: Option<unsafe extern "C" fn(*mut ::c_void)>, + ) -> ::c_int; + pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int; + pub fn pthread_setspecific(key: pthread_key_t, value: *const ::c_void) -> ::c_int; + pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + pub fn sysconf(name: ::c_int) -> ::c_long; +} + +pub const _SC_PAGESIZE: ::c_int = 54; + +pub const AF_INET: ::c_int = 1; +pub const AF_INET6: ::c_int = 2; + +pub const EACCES: ::c_int = cloudabi::errno::ACCES as ::c_int; +pub const EADDRINUSE: ::c_int = cloudabi::errno::ADDRINUSE as ::c_int; +pub const EADDRNOTAVAIL: ::c_int = cloudabi::errno::ADDRNOTAVAIL as ::c_int; +pub const EAGAIN: ::c_int = cloudabi::errno::AGAIN as ::c_int; +pub const ECONNABORTED: ::c_int = cloudabi::errno::CONNABORTED as ::c_int; +pub const ECONNREFUSED: ::c_int = cloudabi::errno::CONNREFUSED as ::c_int; +pub const ECONNRESET: ::c_int = cloudabi::errno::CONNRESET as ::c_int; +pub const EEXIST: ::c_int = cloudabi::errno::EXIST as ::c_int; +pub const EINTR: ::c_int = cloudabi::errno::INTR as ::c_int; +pub const EINVAL: ::c_int = cloudabi::errno::INVAL as ::c_int; +pub const ENOENT: ::c_int = cloudabi::errno::NOENT as ::c_int; +pub const ENOTCONN: ::c_int = cloudabi::errno::NOTCONN as ::c_int; +pub const EPERM: ::c_int = cloudabi::errno::PERM as ::c_int; +pub const EPIPE: ::c_int = cloudabi::errno::PIPE as ::c_int; +pub const ETIMEDOUT: ::c_int = cloudabi::errno::TIMEDOUT as ::c_int; +pub const EWOULDBLOCK: ::c_int = cloudabi::errno::AGAIN as ::c_int; + +pub const EAI_SYSTEM: ::c_int = 9; + +pub const PTHREAD_STACK_MIN: ::size_t = 1024; + +pub const SOCK_DGRAM: ::c_int = cloudabi::filetype::SOCKET_DGRAM as ::c_int; +pub const SOCK_STREAM: ::c_int = cloudabi::filetype::SOCKET_STREAM as ::c_int; + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(any(target_arch = "x86"))] { + mod x86; + pub use self::x86::*; + } else if #[cfg(any(target_arch = "x86_64"))] { + mod x86_64; + pub use self::x86_64::*; + } else { + // Unknown target_arch + } +} diff --git a/src/cloudabi/x86.rs b/src/cloudabi/x86.rs new file mode 100644 index 00000000..2f9f39c9 --- /dev/null +++ b/src/cloudabi/x86.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type wchar_t = i32; diff --git a/src/cloudabi/x86_64.rs b/src/cloudabi/x86_64.rs new file mode 100644 index 00000000..bb17624b --- /dev/null +++ b/src/cloudabi/x86_64.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = i32; diff --git a/src/lib.rs b/src/lib.rs index 74634a1b..1c374bf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -286,6 +286,9 @@ cfg_if! { } else if #[cfg(target_os = "redox")] { mod redox; pub use redox::*; + } else if #[cfg(target_os = "cloudabi")] { + mod cloudabi; + pub use cloudabi::*; } else if #[cfg(target_os = "fuchsia")] { mod fuchsia; pub use fuchsia::*; -- GitLab