diff options
| author | Richard Diamond <wichard@vitalitystudios.com> | 2015-10-24 20:51:34 -0500 |
|---|---|---|
| committer | Richard Diamond <wichard@vitalitystudios.com> | 2015-10-28 17:23:28 -0500 |
| commit | a7d93c939a9cedbc239b3ce647fb8a22125a4d22 (patch) | |
| tree | c21ab99f1eb5dc33d46121bb5912dc691e73530d /src/libstd/sys | |
| parent | 8d86d1a4e17239361ecebced0d5dd246efa95512 (diff) | |
| download | rust-a7d93c939a9cedbc239b3ce647fb8a22125a4d22.tar.gz rust-a7d93c939a9cedbc239b3ce647fb8a22125a4d22.zip | |
Port the standard crates to PNaCl/NaCl.
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/common/backtrace.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/unix/c.rs | 48 | ||||
| -rw-r--r-- | src/libstd/sys/unix/fd.rs | 9 | ||||
| -rw-r--r-- | src/libstd/sys/unix/mod.rs | 5 | ||||
| -rw-r--r-- | src/libstd/sys/unix/os.rs | 51 | ||||
| -rw-r--r-- | src/libstd/sys/unix/process.rs | 43 | ||||
| -rw-r--r-- | src/libstd/sys/unix/sync.rs | 59 | ||||
| -rw-r--r-- | src/libstd/sys/unix/thread.rs | 5 | ||||
| -rw-r--r-- | src/libstd/sys/unix/thread_local.rs | 6 | ||||
| -rw-r--r-- | src/libstd/sys/unix/time.rs | 6 |
10 files changed, 175 insertions, 59 deletions
diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs index e7bda9a7ba2..3c84783d215 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 051b3d8897d..fc6af6447d2 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 4ac498f77ce..e9f442a22cc 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<c_int> for FileDesc { diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 3a88f36399e..26b6b17cbe4 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 59b385b9481..c328c84f62a 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<PathBuf> { }).map(PathBuf::from); #[cfg(any(target_os = "android", - target_os = "ios"))] + target_os = "ios", + target_os = "nacl"))] unsafe fn fallback() -> Option<OsString> { None } #[cfg(not(any(target_os = "android", - target_os = "ios")))] + target_os = "ios", + target_os = "nacl")))] unsafe fn fallback() -> Option<OsString> { 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 7f50e75f6fc..75ae9310b21 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<OsString, OsString>>) 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 954bfbb6b18..6f6acc2560e 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 50e01ecf9fa..88ff4272935 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 e697417675d..e9bf214e816 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 73b66877588..35d55902f9c 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; |
