From a7d93c939a9cedbc239b3ce647fb8a22125a4d22 Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Sat, 24 Oct 2015 20:51:34 -0500 Subject: [PATCH] Port the standard crates to PNaCl/NaCl. --- src/libstd/dynamic_lib.rs | 29 ++- src/libstd/env.rs | 26 +++ src/libstd/os/nacl/raw.rs | 269 ++++------------------------ src/libstd/rtdeps.rs | 8 + src/libstd/sys/common/backtrace.rs | 2 + src/libstd/sys/unix/c.rs | 48 ++++- src/libstd/sys/unix/fd.rs | 9 + src/libstd/sys/unix/mod.rs | 5 +- src/libstd/sys/unix/os.rs | 51 ++---- src/libstd/sys/unix/process.rs | 43 +++-- src/libstd/sys/unix/sync.rs | 59 ++++++ src/libstd/sys/unix/thread.rs | 5 + src/libstd/sys/unix/thread_local.rs | 6 +- src/libstd/sys/unix/time.rs | 6 +- src/libsyntax/abi.rs | 2 + src/libtest/lib.rs | 4 + 16 files changed, 273 insertions(+), 299 deletions(-) diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index 5629cba1e0b3c..8e942a116b16e 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -118,7 +118,7 @@ impl DynamicLibrary { } } -#[cfg(all(test, not(target_os = "ios")))] +#[cfg(all(test, not(target_os = "ios"), not(target_os = "nacl")))] mod tests { use super::*; use prelude::v1::*; @@ -372,3 +372,30 @@ mod dl { fn SetErrorMode(uMode: libc::c_uint) -> libc::c_uint; } } + +#[cfg(target_os = "nacl")] +pub mod dl { + use ffi::OsStr; + use ptr; + use result::Result; + use result::Result::Err; + use libc; + use string::String; + use ops::FnOnce; + use option::Option; + + pub fn open(_filename: Option<&OsStr>) -> Result<*mut u8, String> { + Err(format!("NaCl + Newlib doesn't impl loading shared objects")) + } + + pub fn check_for_errors_in(_f: F) -> Result + where F: FnOnce() -> T, + { + Err(format!("NaCl doesn't support shared objects")) + } + + pub unsafe fn symbol(_handle: *mut u8, _symbol: *const libc::c_char) -> *mut u8 { + ptr::null_mut() + } + pub unsafe fn close(_handle: *mut u8) { } +} diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 518c67bbe7f58..495f37e123848 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -795,6 +795,27 @@ mod os { pub const EXE_EXTENSION: &'static str = "exe"; } +#[cfg(all(target_os = "nacl", not(target_arch = "le32")))] +mod os { + pub const FAMILY: &'static str = "unix"; + pub const OS: &'static str = "nacl"; + pub const DLL_PREFIX: &'static str = "lib"; + pub const DLL_SUFFIX: &'static str = ".so"; + pub const DLL_EXTENSION: &'static str = "so"; + pub const EXE_SUFFIX: &'static str = ".nexe"; + pub const EXE_EXTENSION: &'static str = "nexe"; +} +#[cfg(all(target_os = "nacl", target_arch = "le32"))] +mod os { + pub const FAMILY: &'static str = "unix"; + pub const OS: &'static str = "pnacl"; + pub const DLL_PREFIX: &'static str = "lib"; + pub const DLL_SUFFIX: &'static str = ".pso"; + pub const DLL_EXTENSION: &'static str = "pso"; + pub const EXE_SUFFIX: &'static str = ".pexe"; + pub const EXE_EXTENSION: &'static str = "pexe"; +} + #[cfg(target_arch = "x86")] mod arch { pub const ARCH: &'static str = "x86"; @@ -830,6 +851,11 @@ mod arch { pub const ARCH: &'static str = "powerpc"; } +#[cfg(target_arch = "le32")] +mod arch { + pub const ARCH: &'static str = "le32"; +} + #[cfg(test)] mod tests { use prelude::v1::*; diff --git a/src/libstd/os/nacl/raw.rs b/src/libstd/os/nacl/raw.rs index 82898437687b9..36f8a5fb5c923 100644 --- a/src/libstd/os/nacl/raw.rs +++ b/src/libstd/os/nacl/raw.rs @@ -12,245 +12,36 @@ #![stable(feature = "raw_ext", since = "1.1.0")] +#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i32; #[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type pid_t = i32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type uid_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type gid_t = u32; #[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; - -pub use self::arch::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t}; - -#[cfg(any(target_arch = "x86", - target_arch = "le32", - target_arch = "powerpc", - target_arch = "arm"))] -mod arch { - use super::{dev_t, mode_t}; - use os::raw::{c_long, c_short}; - use os::unix::raw::{gid_t, uid_t}; - - #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32; - - #[repr(C)] - #[derive(Clone)] - #[stable(feature = "raw_ext", since = "1.1.0")] - pub struct stat { - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_dev: dev_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub __pad1: c_short, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ino: ino_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mode: mode_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_nlink: nlink_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_uid: uid_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_gid: gid_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_rdev: dev_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub __pad2: c_short, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_size: off_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blksize: blksize_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blocks: blkcnt_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub __unused4: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub __unused5: c_long, - } -} - -#[cfg(any(target_arch = "mips", - target_arch = "mipsel"))] -mod arch { - use super::{dev_t, mode_t}; - use os::raw::c_long; - use os::unix::raw::{gid_t, uid_t}; - - #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32; - - #[repr(C)] - #[derive(Clone)] - #[stable(feature = "raw_ext", since = "1.1.0")] - pub struct stat { - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_dev: c_ulong, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_pad1: [c_long; 3], - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ino: ino_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mode: mode_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_nlink: nlink_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_uid: uid_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_gid: gid_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_rdev: c_ulong, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_pad2: [c_long; 2], - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_size: off_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_pad3: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blksize: blksize_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blocks: blkcnt_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_pad5: [c_long; 14], - } -} - -#[cfg(target_arch = "aarch64")] -mod arch { - use super::{dev_t, mode_t}; - use os::raw::{c_long, c_int}; - use os::unix::raw::{gid_t, uid_t}; - - #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u32; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i64; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; - - #[repr(C)] - #[derive(Clone)] - #[stable(feature = "raw_ext", since = "1.1.0")] - pub struct stat { - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_dev: dev_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ino: ino_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mode: mode_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_nlink: nlink_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_uid: uid_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_gid: gid_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_rdev: dev_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub __pad1: dev_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_size: off_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blksize: blksize_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub __pad2: c_int, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blocks: blkcnt_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub __unused: [c_int; 2], - } -} - -#[cfg(target_arch = "x86_64")] -mod arch { - use super::{dev_t, mode_t}; - use os::raw::{c_long, c_int}; - use os::unix::raw::{gid_t, uid_t}; - - #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i64; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i64; - #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; - - #[repr(C)] - #[derive(Clone)] - #[stable(feature = "raw_ext", since = "1.1.0")] - pub struct stat { - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_dev: dev_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ino: ino_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_nlink: nlink_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mode: mode_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_uid: uid_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_gid: gid_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub __pad0: c_int, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_rdev: dev_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_size: off_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blksize: blksize_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blocks: blkcnt_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime_nsec: c_long, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub __unused: [c_long; 3], - } +#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i32; + +#[repr(C)] +#[derive(Copy, Clone)] +#[stable(feature = "raw_ext", since = "1.1.0")] +pub struct stat { + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_dev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ino: ino_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mode: mode_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_nlink: nlink_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_uid: uid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_gid: gid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_rdev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_size: off_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_blksize: blksize_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_blocks: blkcnt_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_atime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_atime_nsec: i64, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mtime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_mtime_nsec: i64, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ctime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] pub st_ctime_nsec: i64, } diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs index a3b2ab7705eaf..8383b3ec18972 100644 --- a/src/libstd/rtdeps.rs +++ b/src/libstd/rtdeps.rs @@ -44,6 +44,14 @@ extern {} #[link(name = "pthread")] extern {} +// For PNaCl targets, nacl_io is a Pepper wrapper for some IO functions +// missing (ie always error) in Newlib. +#[cfg(all(target_os = "nacl", not(test)))] +#[link(name = "nacl_io", kind = "static")] +#[link(name = "c++", kind = "static")] // for `nacl_io` and EH. +#[link(name = "pthread", kind = "static")] +extern {} + #[cfg(target_os = "macos")] #[link(name = "System")] extern {} diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs index e7bda9a7ba2db..3c84783d215ec 100644 --- a/src/libstd/sys/common/backtrace.rs +++ b/src/libstd/sys/common/backtrace.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![cfg_attr(target_os = "nacl", allow(dead_code))] + use env; use io::prelude::*; use io; diff --git a/src/libstd/sys/unix/c.rs b/src/libstd/sys/unix/c.rs index 051b3d8897d90..fc6af6447d2fd 100644 --- a/src/libstd/sys/unix/c.rs +++ b/src/libstd/sys/unix/c.rs @@ -24,9 +24,7 @@ #![allow(dead_code)] #![allow(non_camel_case_types)] -pub use self::signal_os::{sigaction, siginfo, sigset_t, sigaltstack}; -pub use self::signal_os::{SA_ONSTACK, SA_SIGINFO, SIGBUS, SIGSTKSZ, SIG_SETMASK}; - +pub use self::signal_os::*; use libc; #[cfg(any(target_os = "macos", @@ -52,6 +50,13 @@ pub const FIOCLEX: libc::c_ulong = 0x5451; target_arch = "powerpc")))] pub const FIOCLEX: libc::c_ulong = 0x6601; +#[cfg(target_env = "newlib")] +pub const FD_CLOEXEC: libc::c_int = 1; +#[cfg(target_env = "newlib")] +pub const F_GETFD: libc::c_int = 1; +#[cfg(target_env = "newlib")] +pub const F_SETFD: libc::c_int = 2; + pub const WNOHANG: libc::c_int = 1; #[cfg(target_os = "linux")] @@ -79,6 +84,18 @@ pub struct passwd { pub pw_dir: *mut libc::c_char, pub pw_shell: *mut libc::c_char, } +#[repr(C)] +#[cfg(target_env = "newlib")] +pub struct passwd { + pub pw_name: *mut libc::c_char, + pub pw_passwd: *mut libc::c_char, + pub pw_uid: libc::uid_t, + pub pw_gid: libc::gid_t, + pub pw_comment: *mut libc::c_char, + pub pw_gecos: *mut libc::c_char, + pub pw_dir: *mut libc::c_char, + pub pw_shell: *mut libc::c_char, +} #[repr(C)] #[cfg(any(target_os = "macos", @@ -124,7 +141,10 @@ extern { optname: libc::c_int, optval: *mut libc::c_void, optlen: *mut libc::socklen_t) -> libc::c_int; + #[cfg(not(target_env = "newlib"))] pub fn ioctl(fd: libc::c_int, req: libc::c_ulong, ...) -> libc::c_int; + #[cfg(target_env = "newlib")] + pub fn fnctl(fd: libc::c_int, req: libc::c_int, ...) -> libc::c_int; pub fn waitpid(pid: libc::pid_t, status: *mut libc::c_int, @@ -138,6 +158,7 @@ extern { oldact: *mut sigaction) -> libc::c_int; #[cfg_attr(target_os = "netbsd", link_name = "__sigaltstack14")] + #[cfg(not(target_env = "newlib"))] pub fn sigaltstack(ss: *const sigaltstack, oss: *mut sigaltstack) -> libc::c_int; @@ -160,6 +181,8 @@ extern { pub fn utimes(filename: *const libc::c_char, times: *const libc::timeval) -> libc::c_int; pub fn gai_strerror(errcode: libc::c_int) -> *const libc::c_char; + /// Newlib has this, but only for Cygwin. + #[cfg(not(target_os = "nacl"))] pub fn setgroups(ngroups: libc::c_int, ptr: *const libc::c_void) -> libc::c_int; pub fn realpath(pathname: *const libc::c_char, resolved: *mut libc::c_char) @@ -325,6 +348,25 @@ mod signal_os { } } +/// Note: Although the signal functions are defined on NaCl, they always fail. +/// Also, this could be cfg-ed on newlib instead of nacl, but these structures +/// can differ depending on the platform, so I've played it safe here. +#[cfg(target_os = "nacl")] +mod signal_os { + use libc; + + pub static SA_NOCLDSTOP: libc::c_ulong = 1; + pub static SA_SIGINFO: libc::c_ulong = 2; + + pub type sigset_t = libc::c_ulong; + #[repr(C)] + pub struct sigaction { + pub sa_flags: libc::c_int, + pub sa_mask: sigset_t, + pub handler: extern fn(libc::c_int), + } +} + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd", diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 4ac498f77ce48..e9f442a22ccee 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -51,12 +51,21 @@ impl FileDesc { Ok(ret as usize) } + #[cfg(not(target_env = "newlib"))] pub fn set_cloexec(&self) { unsafe { let ret = c::ioctl(self.fd, c::FIOCLEX); debug_assert_eq!(ret, 0); } } + #[cfg(target_env = "newlib")] + pub fn set_cloexec(&self) { + unsafe { + let previous = c::fnctl(self.fd, c::F_GETFD); + let ret = c::fnctl(self.fd, c::F_SETFD, previous | c::FD_CLOEXEC); + debug_assert_eq!(ret, 0); + } + } } impl AsInner for FileDesc { diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 3a88f36399eb2..26b6b17cbe41a 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -12,7 +12,6 @@ #![allow(non_camel_case_types)] use io::{self, ErrorKind}; -use libc::funcs::posix01::signal::signal; use libc; use num::One; use ops::Neg; @@ -48,7 +47,9 @@ pub mod thread_local; pub mod time; pub mod stdio; +#[cfg(not(target_os = "nacl"))] pub fn init() { + use libc::funcs::posix01::signal::signal; // By default, some platforms will send a *signal* when an EPIPE error // would otherwise be delivered. This runtime doesn't install a SIGPIPE // handler, causing it to kill the program, which isn't exactly what we @@ -60,6 +61,8 @@ pub fn init() { assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != !0); } } +#[cfg(target_os = "nacl")] +pub fn init() { } pub fn decode_error_kind(errno: i32) -> ErrorKind { match errno as libc::c_int { diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 59b385b94810b..c328c84f62ae5 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -34,30 +34,15 @@ const TMPBUF_SZ: usize = 128; /// Returns the platform-specific value of errno pub fn errno() -> i32 { - #[cfg(any(target_os = "macos", - target_os = "ios", - target_os = "freebsd"))] - unsafe fn errno_location() -> *const c_int { - extern { fn __error() -> *const c_int; } - __error() - } - - #[cfg(target_os = "dragonfly")] - unsafe fn errno_location() -> *const c_int { - extern { fn __dfly_error() -> *const c_int; } - __dfly_error() - } - - #[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))] - unsafe fn errno_location() -> *const c_int { - extern { fn __errno() -> *const c_int; } - __errno() - } - - #[cfg(any(target_os = "linux", target_os = "android"))] - unsafe fn errno_location() -> *const c_int { - extern { fn __errno_location() -> *const c_int; } - __errno_location() + extern { + #[cfg_attr(any(target_os = "linux", target_os = "android"), link_name = "__errno_location")] + #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd", + target_env = "newlib"), + link_name = "__errno")] + #[cfg_attr(target_os = "dragonfly", link_name = "__dfly_error")] + #[cfg_attr(any(target_os = "macos", target_os = "ios", target_os = "freebsd"), + link_name = "__error")] + fn errno_location() -> *const c_int; } unsafe { @@ -67,14 +52,9 @@ pub fn errno() -> i32 { /// Gets a detailed string description for the given error number. pub fn error_string(errno: i32) -> String { - #[cfg(target_os = "linux")] - extern { - #[link_name = "__xpg_strerror_r"] - fn strerror_r(errnum: c_int, buf: *mut c_char, - buflen: libc::size_t) -> c_int; - } - #[cfg(not(target_os = "linux"))] extern { + #[cfg_attr(any(target_os = "linux", target_env = "newlib"), + link_name = "__xpg_strerror_r")] fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int; } @@ -361,7 +341,8 @@ pub fn args() -> Args { target_os = "dragonfly", target_os = "bitrig", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "nacl"))] pub fn args() -> Args { use sys_common; let bytes = sys_common::args::clone().unwrap_or(Vec::new()); @@ -473,10 +454,12 @@ pub fn home_dir() -> Option { }).map(PathBuf::from); #[cfg(any(target_os = "android", - target_os = "ios"))] + target_os = "ios", + target_os = "nacl"))] unsafe fn fallback() -> Option { None } #[cfg(not(any(target_os = "android", - target_os = "ios")))] + target_os = "ios", + target_os = "nacl")))] unsafe fn fallback() -> Option { let amt = match libc::sysconf(c::_SC_GETPW_R_SIZE_MAX) { n if n < 0 => 512 as usize, diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 7f50e75f6fc64..75ae9310b21ba 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -17,7 +17,6 @@ use ffi::{OsString, OsStr, CString, CStr}; use fmt; use io::{self, Error, ErrorKind}; use libc::{self, pid_t, c_void, c_int, gid_t, uid_t}; -use mem; use ptr; use sys::fd::FileDesc; use sys::fs::{File, OpenOptions}; @@ -315,21 +314,31 @@ impl Process { *sys::os::environ() = envp as *const _; } - // Reset signal handling so the child process starts in a - // standardized state. libstd ignores SIGPIPE, and signal-handling - // libraries often set a mask. Child processes inherit ignored - // signals and the signal mask from their parent, but most - // UNIX programs do not reset these things on their own, so we - // need to clean things up now to avoid confusing the program - // we're about to run. - let mut set: c::sigset_t = mem::uninitialized(); - if c::sigemptyset(&mut set) != 0 || - c::pthread_sigmask(c::SIG_SETMASK, &set, ptr::null_mut()) != 0 || - libc::funcs::posix01::signal::signal( - libc::SIGPIPE, mem::transmute(c::SIG_DFL) - ) == mem::transmute(c::SIG_ERR) { - fail(&mut output); + #[cfg(not(target_os = "nacl"))] + unsafe fn reset_signal_handling(output: &mut AnonPipe) { + use mem; + // Reset signal handling so the child process starts in a + // standardized state. libstd ignores SIGPIPE, and signal-handling + // libraries often set a mask. Child processes inherit ignored + // signals and the signal mask from their parent, but most + // UNIX programs do not reset these things on their own, so we + // need to clean things up now to avoid confusing the program + // we're about to run. + let mut set: c::sigset_t = mem::uninitialized(); + if c::sigemptyset(&mut set) != 0 || + c::pthread_sigmask(c::SIG_SETMASK, &set, ptr::null_mut()) != 0 || + libc::funcs::posix01::signal::signal( + libc::SIGPIPE, mem::transmute(c::SIG_DFL) + ) == mem::transmute(c::SIG_ERR) + { + fail(output); + } + } + #[cfg(target_os = "nacl")] + unsafe fn reset_signal_handling(_output: &mut AnonPipe) { + // NaCl has no signal support. } + reset_signal_handling(&mut output); let _ = libc::execvp(*argv, argv); fail(&mut output) @@ -411,7 +420,8 @@ fn make_envp(env: Option<&HashMap>) fn translate_status(status: c_int) -> ExitStatus { #![allow(non_snake_case)] - #[cfg(any(target_os = "linux", target_os = "android"))] + #[cfg(any(target_os = "linux", target_os = "android", + target_os = "nacl"))] mod imp { pub fn WIFEXITED(status: i32) -> bool { (status & 0xff) == 0 } pub fn WEXITSTATUS(status: i32) -> i32 { (status >> 8) & 0xff } @@ -478,6 +488,7 @@ mod tests { // test from being flaky we ignore it on OSX. #[test] #[cfg_attr(target_os = "macos", ignore)] + #[cfg_attr(target_os = "nacl", ignore)] // no signals on NaCl. fn test_process_mask() { unsafe { // Test to make sure that a signal mask does not get inherited. diff --git a/src/libstd/sys/unix/sync.rs b/src/libstd/sys/unix/sync.rs index 954bfbb6b18b7..6f6acc2560e0c 100644 --- a/src/libstd/sys/unix/sync.rs +++ b/src/libstd/sys/unix/sync.rs @@ -34,6 +34,7 @@ extern { // cvars pub fn pthread_cond_wait(cond: *mut pthread_cond_t, lock: *mut pthread_mutex_t) -> libc::c_int; + #[cfg_attr(target_os = "nacl", link_name = "pthread_cond_timedwait_abs")] pub fn pthread_cond_timedwait(cond: *mut pthread_cond_t, lock: *mut pthread_mutex_t, abstime: *const libc::timespec) -> libc::c_int; @@ -313,3 +314,61 @@ mod os { pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 2; } +#[cfg(target_os = "nacl")] +mod os { + use libc; + + pub type __nc_basic_thread_data = libc::c_void; + + #[repr(C)] + pub struct pthread_mutex_t { + mutex_state: libc::c_int, + mutex_type: libc::c_int, + owner_thread_id: *mut __nc_basic_thread_data, + recursion_counter: libc::uint32_t, + _unused: libc::c_int, + } + #[repr(C)] + pub struct pthread_mutexattr_t { + kind: libc::c_int, + } + #[repr(C)] + pub struct pthread_cond_t { + sequence_number: libc::c_int, + _unused: libc::c_int, + } + #[repr(C)] + pub struct pthread_rwlock_t { + mutex: pthread_mutex_t, + reader_count: libc::c_int, + writers_waiting: libc::c_int, + writer_thread_id: *mut __nc_basic_thread_data, + read_possible: pthread_cond_t, + write_possible: pthread_cond_t, + } + + const NC_INVALID_HANDLE: libc::c_int = -1; + const NACL_PTHREAD_ILLEGAL_THREAD_ID: *mut __nc_basic_thread_data + = 0 as *mut __nc_basic_thread_data; + + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + mutex_state: 0, + mutex_type: 0, + owner_thread_id: NACL_PTHREAD_ILLEGAL_THREAD_ID, + recursion_counter: 0, + _unused: NC_INVALID_HANDLE, + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + sequence_number: 0, + _unused: NC_INVALID_HANDLE, + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + mutex: PTHREAD_MUTEX_INITIALIZER, + reader_count: 0, + writers_waiting: 0, + writer_thread_id: NACL_PTHREAD_ILLEGAL_THREAD_ID, + read_possible: PTHREAD_COND_INITIALIZER, + write_possible: PTHREAD_COND_INITIALIZER, + }; + pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 1; +} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 50e01ecf9fa98..88ff427293580 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -14,6 +14,7 @@ use prelude::v1::*; use alloc::boxed::FnBox; use cmp; +#[cfg(not(target_env = "newlib"))] use ffi::CString; use io; use libc::consts::os::posix01::PTHREAD_STACK_MIN; @@ -139,6 +140,10 @@ impl Thread { carg.as_ptr() as *mut libc::c_void); } } + #[cfg(target_env = "newlib")] + pub unsafe fn set_name(_name: &str) { + // Newlib has no way to set a thread name. + } pub fn sleep(dur: Duration) { let mut ts = libc::timespec { diff --git a/src/libstd/sys/unix/thread_local.rs b/src/libstd/sys/unix/thread_local.rs index e697417675d77..e9bf214e8161c 100644 --- a/src/libstd/sys/unix/thread_local.rs +++ b/src/libstd/sys/unix/thread_local.rs @@ -46,7 +46,8 @@ type pthread_key_t = ::libc::c_ulong; target_os = "dragonfly", target_os = "bitrig", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "nacl"))] type pthread_key_t = ::libc::c_int; #[cfg(not(any(target_os = "macos", @@ -55,7 +56,8 @@ type pthread_key_t = ::libc::c_int; target_os = "dragonfly", target_os = "bitrig", target_os = "netbsd", - target_os = "openbsd")))] + target_os = "openbsd", + target_os = "nacl")))] type pthread_key_t = ::libc::c_uint; extern { diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs index 73b6687758814..35d55902f9c8b 100644 --- a/src/libstd/sys/unix/time.rs +++ b/src/libstd/sys/unix/time.rs @@ -77,16 +77,16 @@ mod inner { // Apparently android provides this in some other library? // Bitrig's RT extensions are in the C library, not a separate librt - // OpenBSD provide it via libc + // OpenBSD and NaCl provide it via libc #[cfg(not(any(target_os = "android", target_os = "bitrig", target_os = "netbsd", target_os = "openbsd", - target_env = "musl")))] + target_env = "musl", + target_os = "nacl")))] #[link(name = "rt")] extern {} - extern { #[cfg_attr(target_os = "netbsd", link_name = "__clock_gettime50")] fn clock_gettime(clk_id: libc::c_int, tp: *mut libc::timespec) -> libc::c_int; diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index c0fe541ead510..ca44dec627e37 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -27,6 +27,7 @@ pub enum Os { OsBitrig, OsNetbsd, OsOpenbsd, + OsNaCl, } #[derive(PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)] @@ -143,6 +144,7 @@ impl fmt::Display for Os { OsBitrig => "bitrig".fmt(f), OsNetbsd => "netbsd".fmt(f), OsOpenbsd => "openbsd".fmt(f), + OsNaCl => "nacl".fmt(f), } } } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index cfe75779536a2..12541dc010bcf 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -1084,12 +1084,16 @@ impl MetricMap { /// elimination. /// /// This function is a no-op, and does not even read from `dummy`. +#[cfg(not(all(target_os = "nacl", target_arch = "le32")))] pub fn black_box(dummy: T) -> T { // we need to "use" the argument in some way LLVM can't // introspect. unsafe {asm!("" : : "r"(&dummy))} dummy } +#[cfg(all(target_os = "nacl", target_arch = "le32"))] +#[inline(never)] +pub fn black_box(dummy: T) -> T { dummy } impl Bencher {