aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/sys/unix
diff options
context:
space:
mode:
authorVivian Lim <[email protected]>2021-02-06 22:11:59 -0800
committerVivian Lim <[email protected]>2021-02-06 22:11:59 -0800
commit64423f0e34cc4a7d78c15b345b3b8f58243d8286 (patch)
treecc20e2e7f0fc35abf470e20e61d3d48f0d954f3b /ctr-std/src/sys/unix
parentSupport libctru 2.0 (diff)
downloadctru-rs-64423f0e34cc4a7d78c15b345b3b8f58243d8286.tar.xz
ctru-rs-64423f0e34cc4a7d78c15b345b3b8f58243d8286.zip
Delete ctr-std to use my fork of the rust repo instead
Diffstat (limited to 'ctr-std/src/sys/unix')
-rw-r--r--ctr-std/src/sys/unix/android.rs170
-rw-r--r--ctr-std/src/sys/unix/args.rs219
-rw-r--r--ctr-std/src/sys/unix/backtrace/mod.rs119
-rw-r--r--ctr-std/src/sys/unix/backtrace/printing/dladdr.rs45
-rw-r--r--ctr-std/src/sys/unix/backtrace/printing/mod.rs43
-rw-r--r--ctr-std/src/sys/unix/backtrace/tracing/backtrace_fn.rs49
-rw-r--r--ctr-std/src/sys/unix/backtrace/tracing/gcc_s.rs109
-rw-r--r--ctr-std/src/sys/unix/backtrace/tracing/mod.rs18
-rw-r--r--ctr-std/src/sys/unix/cmath.rs43
-rw-r--r--ctr-std/src/sys/unix/condvar.rs192
-rw-r--r--ctr-std/src/sys/unix/env.rs185
-rw-r--r--ctr-std/src/sys/unix/ext/ffi.rs119
-rw-r--r--ctr-std/src/sys/unix/ext/fs.rs863
-rw-r--r--ctr-std/src/sys/unix/ext/io.rs108
-rw-r--r--ctr-std/src/sys/unix/ext/mod.rs67
-rw-r--r--ctr-std/src/sys/unix/ext/net.rs1824
-rw-r--r--ctr-std/src/sys/unix/ext/process.rs203
-rw-r--r--ctr-std/src/sys/unix/ext/raw.rs33
-rw-r--r--ctr-std/src/sys/unix/ext/thread.rs51
-rw-r--r--ctr-std/src/sys/unix/fast_thread_local.rs72
-rw-r--r--ctr-std/src/sys/unix/fd.rs288
-rw-r--r--ctr-std/src/sys/unix/fs.rs945
-rw-r--r--ctr-std/src/sys/unix/l4re.rs441
-rw-r--r--ctr-std/src/sys/unix/memchr.rs57
-rw-r--r--ctr-std/src/sys/unix/mod.rs167
-rw-r--r--ctr-std/src/sys/unix/mutex.rs139
-rw-r--r--ctr-std/src/sys/unix/net.rs424
-rw-r--r--ctr-std/src/sys/unix/os.rs571
-rw-r--r--ctr-std/src/sys/unix/os_str.rs189
-rw-r--r--ctr-std/src/sys/unix/path.rs29
-rw-r--r--ctr-std/src/sys/unix/pipe.rs131
-rw-r--r--ctr-std/src/sys/unix/process/mod.rs22
-rw-r--r--ctr-std/src/sys/unix/process/process_common.rs510
-rw-r--r--ctr-std/src/sys/unix/process/process_fuchsia.rs181
-rw-r--r--ctr-std/src/sys/unix/process/process_unix.rs405
-rw-r--r--ctr-std/src/sys/unix/process/zircon.rs279
-rw-r--r--ctr-std/src/sys/unix/rand.rs192
-rw-r--r--ctr-std/src/sys/unix/rwlock.rs142
-rw-r--r--ctr-std/src/sys/unix/stack_overflow.rs220
-rw-r--r--ctr-std/src/sys/unix/stdio.rs81
-rw-r--r--ctr-std/src/sys/unix/thread.rs458
-rw-r--r--ctr-std/src/sys/unix/thread_local.rs45
-rw-r--r--ctr-std/src/sys/unix/time.rs365
-rw-r--r--ctr-std/src/sys/unix/weak.rs79
44 files changed, 0 insertions, 10892 deletions
diff --git a/ctr-std/src/sys/unix/android.rs b/ctr-std/src/sys/unix/android.rs
deleted file mode 100644
index 1043672..0000000
--- a/ctr-std/src/sys/unix/android.rs
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Android ABI-compatibility module
-//!
-//! The ABI of Android has changed quite a bit over time, and libstd attempts to
-//! be both forwards and backwards compatible as much as possible. We want to
-//! always work with the most recent version of Android, but we also want to
-//! work with older versions of Android for whenever projects need to.
-//!
-//! Our current minimum supported Android version is `android-9`, e.g. Android
-//! with API level 9. We then in theory want to work on that and all future
-//! versions of Android!
-//!
-//! Some of the detection here is done at runtime via `dlopen` and
-//! introspection. Other times no detection is performed at all and we just
-//! provide a fallback implementation as some versions of Android we support
-//! don't have the function.
-//!
-//! You'll find more details below about why each compatibility shim is needed.
-
-#![cfg(target_os = "android")]
-
-use libc::{c_int, c_void, sighandler_t, size_t, ssize_t};
-use libc::{ftruncate, pread, pwrite};
-
-use io;
-use super::{cvt, cvt_r};
-
-// The `log2` and `log2f` functions apparently appeared in android-18, or at
-// least you can see they're not present in the android-17 header [1] and they
-// are present in android-18 [2].
-//
-// [1]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms
-// /android-17/arch-arm/usr/include/math.h
-// [2]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms
-// /android-18/arch-arm/usr/include/math.h
-//
-// Note that these shims are likely less precise than directly calling `log2`,
-// but hopefully that should be enough for now...
-//
-// Note that mathematically, for any arbitrary `y`:
-//
-// log_2(x) = log_y(x) / log_y(2)
-// = log_y(x) / (1 / log_2(y))
-// = log_y(x) * log_2(y)
-//
-// Hence because `ln` (log_e) is available on all Android we just choose `y = e`
-// and get:
-//
-// log_2(x) = ln(x) * log_2(e)
-
-#[cfg(not(test))]
-pub fn log2f32(f: f32) -> f32 {
- f.ln() * ::f32::consts::LOG2_E
-}
-
-#[cfg(not(test))]
-pub fn log2f64(f: f64) -> f64 {
- f.ln() * ::f64::consts::LOG2_E
-}
-
-// Back in the day [1] the `signal` function was just an inline wrapper
-// around `bsd_signal`, but starting in API level android-20 the `signal`
-// symbols was introduced [2]. Finally, in android-21 the API `bsd_signal` was
-// removed [3].
-//
-// Basically this means that if we want to be binary compatible with multiple
-// Android releases (oldest being 9 and newest being 21) then we need to check
-// for both symbols and not actually link against either.
-//
-// [1]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms
-// /android-18/arch-arm/usr/include/signal.h
-// [2]: https://chromium.googlesource.com/android_tools/+/fbd420/ndk_experimental
-// /platforms/android-20/arch-arm
-// /usr/include/signal.h
-// [3]: https://chromium.googlesource.com/android_tools/+/20ee6d/ndk/platforms
-// /android-21/arch-arm/usr/include/signal.h
-pub unsafe fn signal(signum: c_int, handler: sighandler_t) -> sighandler_t {
- weak!(fn signal(c_int, sighandler_t) -> sighandler_t);
- weak!(fn bsd_signal(c_int, sighandler_t) -> sighandler_t);
-
- let f = signal.get().or_else(|| bsd_signal.get());
- let f = f.expect("neither `signal` nor `bsd_signal` symbols found");
- f(signum, handler)
-}
-
-// The `ftruncate64` symbol apparently appeared in android-12, so we do some
-// dynamic detection to see if we can figure out whether `ftruncate64` exists.
-//
-// If it doesn't we just fall back to `ftruncate`, generating an error for
-// too-large values.
-#[cfg(target_pointer_width = "32")]
-pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
- weak!(fn ftruncate64(c_int, i64) -> c_int);
-
- unsafe {
- match ftruncate64.get() {
- Some(f) => cvt_r(|| f(fd, size as i64)).map(|_| ()),
- None => {
- if size > i32::max_value() as u64 {
- Err(io::Error::new(io::ErrorKind::InvalidInput,
- "cannot truncate >2GB"))
- } else {
- cvt_r(|| ftruncate(fd, size as i32)).map(|_| ())
- }
- }
- }
- }
-}
-
-#[cfg(target_pointer_width = "64")]
-pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
- unsafe {
- cvt_r(|| ftruncate(fd, size as i64)).map(|_| ())
- }
-}
-
-#[cfg(target_pointer_width = "32")]
-pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
- -> io::Result<ssize_t>
-{
- use convert::TryInto;
- weak!(fn pread64(c_int, *mut c_void, size_t, i64) -> ssize_t);
- pread64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
- if let Ok(o) = offset.try_into() {
- cvt(pread(fd, buf, count, o))
- } else {
- Err(io::Error::new(io::ErrorKind::InvalidInput,
- "cannot pread >2GB"))
- }
- })
-}
-
-#[cfg(target_pointer_width = "32")]
-pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
- -> io::Result<ssize_t>
-{
- use convert::TryInto;
- weak!(fn pwrite64(c_int, *const c_void, size_t, i64) -> ssize_t);
- pwrite64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
- if let Ok(o) = offset.try_into() {
- cvt(pwrite(fd, buf, count, o))
- } else {
- Err(io::Error::new(io::ErrorKind::InvalidInput,
- "cannot pwrite >2GB"))
- }
- })
-}
-
-#[cfg(target_pointer_width = "64")]
-pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
- -> io::Result<ssize_t>
-{
- cvt(pread(fd, buf, count, offset))
-}
-
-#[cfg(target_pointer_width = "64")]
-pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
- -> io::Result<ssize_t>
-{
- cvt(pwrite(fd, buf, count, offset))
-}
diff --git a/ctr-std/src/sys/unix/args.rs b/ctr-std/src/sys/unix/args.rs
deleted file mode 100644
index c3c033d..0000000
--- a/ctr-std/src/sys/unix/args.rs
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Global initialization and retrieval of command line arguments.
-//!
-//! On some platforms these are stored during runtime startup,
-//! and on some they are retrieved from the system on demand.
-
-#![allow(dead_code)] // runtime init functions not used during testing
-
-use ffi::OsString;
-use marker::PhantomData;
-use vec;
-
-/// One-time global initialization.
-pub unsafe fn init(argc: isize, argv: *const *const u8) { imp::init(argc, argv) }
-
-/// One-time global cleanup.
-pub unsafe fn cleanup() { imp::cleanup() }
-
-/// Returns the command line arguments
-pub fn args() -> Args {
- imp::args()
-}
-
-pub struct Args {
- iter: vec::IntoIter<OsString>,
- _dont_send_or_sync_me: PhantomData<*mut ()>,
-}
-
-impl Args {
- pub fn inner_debug(&self) -> &[OsString] {
- self.iter.as_slice()
- }
-}
-
-impl Iterator for Args {
- type Item = OsString;
- fn next(&mut self) -> Option<OsString> { self.iter.next() }
- fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
-}
-
-impl ExactSizeIterator for Args {
- fn len(&self) -> usize { self.iter.len() }
-}
-
-impl DoubleEndedIterator for Args {
- fn next_back(&mut self) -> Option<OsString> { self.iter.next_back() }
-}
-
-#[cfg(any(target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "bitrig",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris",
- target_os = "emscripten",
- target_os = "haiku",
- target_os = "l4re",
- target_os = "fuchsia",
- target_os = "hermit"))]
-mod imp {
- use os::unix::prelude::*;
- use ptr;
- use ffi::{CStr, OsString};
- use marker::PhantomData;
- use libc;
- use super::Args;
-
- use sys_common::mutex::Mutex;
-
- static mut ARGC: isize = 0;
- static mut ARGV: *const *const u8 = ptr::null();
- // We never call `ENV_LOCK.init()`, so it is UB to attempt to
- // acquire this mutex reentrantly!
- static LOCK: Mutex = Mutex::new();
-
- pub unsafe fn init(argc: isize, argv: *const *const u8) {
- let _guard = LOCK.lock();
- ARGC = argc;
- ARGV = argv;
- }
-
- pub unsafe fn cleanup() {
- let _guard = LOCK.lock();
- ARGC = 0;
- ARGV = ptr::null();
- }
-
- pub fn args() -> Args {
- Args {
- iter: clone().into_iter(),
- _dont_send_or_sync_me: PhantomData
- }
- }
-
- fn clone() -> Vec<OsString> {
- unsafe {
- let _guard = LOCK.lock();
- (0..ARGC).map(|i| {
- let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
- OsStringExt::from_vec(cstr.to_bytes().to_vec())
- }).collect()
- }
- }
-}
-
-#[cfg(any(target_os = "macos",
- target_os = "ios"))]
-mod imp {
- use ffi::CStr;
- use marker::PhantomData;
- use libc;
- use super::Args;
-
- pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
- }
-
- pub fn cleanup() {
- }
-
- #[cfg(target_os = "macos")]
- pub fn args() -> Args {
- use os::unix::prelude::*;
- extern {
- // These functions are in crt_externs.h.
- fn _NSGetArgc() -> *mut libc::c_int;
- fn _NSGetArgv() -> *mut *mut *mut libc::c_char;
- }
-
- let vec = unsafe {
- let (argc, argv) = (*_NSGetArgc() as isize,
- *_NSGetArgv() as *const *const libc::c_char);
- (0.. argc as isize).map(|i| {
- let bytes = CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec();
- OsStringExt::from_vec(bytes)
- }).collect::<Vec<_>>()
- };
- Args {
- iter: vec.into_iter(),
- _dont_send_or_sync_me: PhantomData,
- }
- }
-
- // As _NSGetArgc and _NSGetArgv aren't mentioned in iOS docs
- // and use underscores in their names - they're most probably
- // are considered private and therefore should be avoided
- // Here is another way to get arguments using Objective C
- // runtime
- //
- // In general it looks like:
- // res = Vec::new()
- // let args = [[NSProcessInfo processInfo] arguments]
- // for i in (0..[args count])
- // res.push([args objectAtIndex:i])
- // res
- #[cfg(target_os = "ios")]
- pub fn args() -> Args {
- use ffi::OsString;
- use mem;
- use str;
-
- extern {
- fn sel_registerName(name: *const libc::c_uchar) -> Sel;
- fn objc_getClass(class_name: *const libc::c_uchar) -> NsId;
- }
-
- #[cfg(target_arch="aarch64")]
- extern {
- fn objc_msgSend(obj: NsId, sel: Sel) -> NsId;
- #[link_name="objc_msgSend"]
- fn objc_msgSend_ul(obj: NsId, sel: Sel, i: libc::c_ulong) -> NsId;
- }
-
- #[cfg(not(target_arch="aarch64"))]
- extern {
- fn objc_msgSend(obj: NsId, sel: Sel, ...) -> NsId;
- #[link_name="objc_msgSend"]
- fn objc_msgSend_ul(obj: NsId, sel: Sel, ...) -> NsId;
- }
-
- type Sel = *const libc::c_void;
- type NsId = *const libc::c_void;
-
- let mut res = Vec::new();
-
- unsafe {
- let process_info_sel = sel_registerName("processInfo\0".as_ptr());
- let arguments_sel = sel_registerName("arguments\0".as_ptr());
- let utf8_sel = sel_registerName("UTF8String\0".as_ptr());
- let count_sel = sel_registerName("count\0".as_ptr());
- let object_at_sel = sel_registerName("objectAtIndex:\0".as_ptr());
-
- let klass = objc_getClass("NSProcessInfo\0".as_ptr());
- let info = objc_msgSend(klass, process_info_sel);
- let args = objc_msgSend(info, arguments_sel);
-
- let cnt: usize = mem::transmute(objc_msgSend(args, count_sel));
- for i in 0..cnt {
- let tmp = objc_msgSend_ul(args, object_at_sel, i as libc::c_ulong);
- let utf_c_str: *const libc::c_char =
- mem::transmute(objc_msgSend(tmp, utf8_sel));
- let bytes = CStr::from_ptr(utf_c_str).to_bytes();
- res.push(OsString::from(str::from_utf8(bytes).unwrap()))
- }
- }
-
- Args { iter: res.into_iter(), _dont_send_or_sync_me: PhantomData }
- }
-}
diff --git a/ctr-std/src/sys/unix/backtrace/mod.rs b/ctr-std/src/sys/unix/backtrace/mod.rs
deleted file mode 100644
index b5bf20c..0000000
--- a/ctr-std/src/sys/unix/backtrace/mod.rs
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/// Backtrace support built on libgcc with some extra OS-specific support
-///
-/// Some methods of getting a backtrace:
-///
-/// * The backtrace() functions on unix. It turns out this doesn't work very
-/// well for green threads on macOS, and the address to symbol portion of it
-/// suffers problems that are described below.
-///
-/// * Using libunwind. This is more difficult than it sounds because libunwind
-/// isn't installed everywhere by default. It's also a bit of a hefty library,
-/// so possibly not the best option. When testing, libunwind was excellent at
-/// getting both accurate backtraces and accurate symbols across platforms.
-/// This route was not chosen in favor of the next option, however.
-///
-/// * We're already using libgcc_s for exceptions in rust (triggering thread
-/// unwinding and running destructors on the stack), and it turns out that it
-/// conveniently comes with a function that also gives us a backtrace. All of
-/// these functions look like _Unwind_*, but it's not quite the full
-/// repertoire of the libunwind API. Due to it already being in use, this was
-/// the chosen route of getting a backtrace.
-///
-/// After choosing libgcc_s for backtraces, the sad part is that it will only
-/// give us a stack trace of instruction pointers. Thankfully these instruction
-/// pointers are accurate (they work for green and native threads), but it's
-/// then up to us again to figure out how to translate these addresses to
-/// symbols. As with before, we have a few options. Before, that, a little bit
-/// of an interlude about symbols. This is my very limited knowledge about
-/// symbol tables, and this information is likely slightly wrong, but the
-/// general idea should be correct.
-///
-/// When talking about symbols, it's helpful to know a few things about where
-/// symbols are located. Some symbols are located in the dynamic symbol table
-/// of the executable which in theory means that they're available for dynamic
-/// linking and lookup. Other symbols end up only in the local symbol table of
-/// the file. This loosely corresponds to pub and priv functions in Rust.
-///
-/// Armed with this knowledge, we know that our solution for address to symbol
-/// translation will need to consult both the local and dynamic symbol tables.
-/// With that in mind, here's our options of translating an address to
-/// a symbol.
-///
-/// * Use dladdr(). The original backtrace()-based idea actually uses dladdr()
-/// behind the scenes to translate, and this is why backtrace() was not used.
-/// Conveniently, this method works fantastically on macOS. It appears dladdr()
-/// uses magic to consult the local symbol table, or we're putting everything
-/// in the dynamic symbol table anyway. Regardless, for macOS, this is the
-/// method used for translation. It's provided by the system and easy to do.o
-///
-/// Sadly, all other systems have a dladdr() implementation that does not
-/// consult the local symbol table. This means that most functions are blank
-/// because they don't have symbols. This means that we need another solution.
-///
-/// * Use unw_get_proc_name(). This is part of the libunwind api (not the
-/// libgcc_s version of the libunwind api), but involves taking a dependency
-/// to libunwind. We may pursue this route in the future if we bundle
-/// libunwind, but libunwind was unwieldy enough that it was not chosen at
-/// this time to provide this functionality.
-///
-/// * Shell out to a utility like `readelf`. Crazy though it may sound, it's a
-/// semi-reasonable solution. The stdlib already knows how to spawn processes,
-/// so in theory it could invoke readelf, parse the output, and consult the
-/// local/dynamic symbol tables from there. This ended up not getting chosen
-/// due to the craziness of the idea plus the advent of the next option.
-///
-/// * Use `libbacktrace`. It turns out that this is a small library bundled in
-/// the gcc repository which provides backtrace and symbol translation
-/// functionality. All we really need from it is the backtrace functionality,
-/// and we only really need this on everything that's not macOS, so this is the
-/// chosen route for now.
-///
-/// In summary, the current situation uses libgcc_s to get a trace of stack
-/// pointers, and we use dladdr() or libbacktrace to translate these addresses
-/// to symbols. This is a bit of a hokey implementation as-is, but it works for
-/// all unix platforms we support right now, so it at least gets the job done.
-
-pub use self::tracing::unwind_backtrace;
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-
-// tracing impls:
-mod tracing;
-// symbol resolvers:
-mod printing;
-
-#[cfg(not(target_os = "emscripten"))]
-pub mod gnu {
- use io;
- use fs;
- use libc::c_char;
-
- #[cfg(not(any(target_os = "macos", target_os = "ios")))]
- pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
- Err(io::Error::new(io::ErrorKind::Other, "Not implemented"))
- }
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
- use env;
- use os::unix::ffi::OsStrExt;
-
- let filename = env::current_exe()?;
- let file = fs::File::open(&filename)?;
- let mut filename_cstr: Vec<_> = filename.as_os_str().as_bytes().iter()
- .map(|&x| x as c_char).collect();
- filename_cstr.push(0); // Null terminate
- Ok((filename_cstr, file))
- }
-}
-
-pub struct BacktraceContext;
diff --git a/ctr-std/src/sys/unix/backtrace/printing/dladdr.rs b/ctr-std/src/sys/unix/backtrace/printing/dladdr.rs
deleted file mode 100644
index bc56fd6..0000000
--- a/ctr-std/src/sys/unix/backtrace/printing/dladdr.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use io;
-use intrinsics;
-use ffi::CStr;
-use libc;
-use sys::backtrace::BacktraceContext;
-use sys_common::backtrace::Frame;
-
-pub fn resolve_symname<F>(frame: Frame,
- callback: F,
- _: &BacktraceContext) -> io::Result<()>
- where F: FnOnce(Option<&str>) -> io::Result<()>
-{
- unsafe {
- let mut info: Dl_info = intrinsics::init();
- let symname = if dladdr(frame.exact_position as *mut _, &mut info) == 0 ||
- info.dli_sname.is_null() {
- None
- } else {
- CStr::from_ptr(info.dli_sname).to_str().ok()
- };
- callback(symname)
- }
-}
-
-#[repr(C)]
-struct Dl_info {
- dli_fname: *const libc::c_char,
- dli_fbase: *mut libc::c_void,
- dli_sname: *const libc::c_char,
- dli_saddr: *mut libc::c_void,
-}
-
-extern {
- fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int;
-}
diff --git a/ctr-std/src/sys/unix/backtrace/printing/mod.rs b/ctr-std/src/sys/unix/backtrace/printing/mod.rs
deleted file mode 100644
index caa6071..0000000
--- a/ctr-std/src/sys/unix/backtrace/printing/mod.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014-2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod dladdr;
-
-use sys::backtrace::BacktraceContext;
-use sys_common::backtrace::Frame;
-use io;
-
-#[cfg(target_os = "emscripten")]
-pub use self::dladdr::resolve_symname;
-
-#[cfg(target_os = "emscripten")]
-pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
-where
- F: FnMut(&[u8], u32) -> io::Result<()>
-{
- Ok(false)
-}
-
-#[cfg(not(target_os = "emscripten"))]
-pub use sys_common::gnu::libbacktrace::foreach_symbol_fileline;
-
-#[cfg(not(target_os = "emscripten"))]
-pub fn resolve_symname<F>(frame: Frame, callback: F, bc: &BacktraceContext) -> io::Result<()>
-where
- F: FnOnce(Option<&str>) -> io::Result<()>
-{
- ::sys_common::gnu::libbacktrace::resolve_symname(frame, |symname| {
- if symname.is_some() {
- callback(symname)
- } else {
- dladdr::resolve_symname(frame, callback, bc)
- }
- }, bc)
-}
diff --git a/ctr-std/src/sys/unix/backtrace/tracing/backtrace_fn.rs b/ctr-std/src/sys/unix/backtrace/tracing/backtrace_fn.rs
deleted file mode 100644
index 6293eeb..0000000
--- a/ctr-std/src/sys/unix/backtrace/tracing/backtrace_fn.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/// As always - iOS on arm uses SjLj exceptions and
-/// _Unwind_Backtrace is even not available there. Still,
-/// backtraces could be extracted using a backtrace function,
-/// which thanks god is public
-///
-/// As mentioned in a huge comment block in `super::super`, backtrace
-/// doesn't play well with green threads, so while it is extremely nice and
-/// simple to use it should be used only on iOS devices as the only viable
-/// option.
-
-use io;
-use libc;
-use sys::backtrace::BacktraceContext;
-use sys_common::backtrace::Frame;
-
-#[inline(never)] // if we know this is a function call, we can skip it when
- // tracing
-pub fn unwind_backtrace(frames: &mut [Frame])
- -> io::Result<(usize, BacktraceContext)>
-{
- const FRAME_LEN: usize = 100;
- assert!(FRAME_LEN >= frames.len());
- let mut raw_frames = [::ptr::null_mut(); FRAME_LEN];
- let nb_frames = unsafe {
- backtrace(raw_frames.as_mut_ptr(), raw_frames.len() as libc::c_int)
- } as usize;
- for (from, to) in raw_frames.iter().zip(frames.iter_mut()).take(nb_frames) {
- *to = Frame {
- exact_position: *from as *mut u8,
- symbol_addr: *from as *mut u8,
- inline_context: 0,
- };
- }
- Ok((nb_frames as usize, BacktraceContext))
-}
-
-extern {
- fn backtrace(buf: *mut *mut libc::c_void, sz: libc::c_int) -> libc::c_int;
-}
diff --git a/ctr-std/src/sys/unix/backtrace/tracing/gcc_s.rs b/ctr-std/src/sys/unix/backtrace/tracing/gcc_s.rs
deleted file mode 100644
index 6e84156..0000000
--- a/ctr-std/src/sys/unix/backtrace/tracing/gcc_s.rs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use error::Error;
-use io;
-use libc;
-use sys::backtrace::BacktraceContext;
-use sys_common::backtrace::Frame;
-
-use unwind as uw;
-
-struct Context<'a> {
- idx: usize,
- frames: &'a mut [Frame],
-}
-
-#[derive(Debug)]
-struct UnwindError(uw::_Unwind_Reason_Code);
-
-impl Error for UnwindError {
- fn description(&self) -> &'static str {
- "unexpected return value while unwinding"
- }
-}
-
-impl ::fmt::Display for UnwindError {
- fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
- write!(f, "{}: {:?}", self.description(), self.0)
- }
-}
-
-#[inline(never)] // if we know this is a function call, we can skip it when
- // tracing
-pub fn unwind_backtrace(frames: &mut [Frame])
- -> io::Result<(usize, BacktraceContext)>
-{
- let mut cx = Context {
- idx: 0,
- frames,
- };
- let result_unwind = unsafe {
- uw::_Unwind_Backtrace(trace_fn,
- &mut cx as *mut Context
- as *mut libc::c_void)
- };
- // See libunwind:src/unwind/Backtrace.c for the return values.
- // No, there is no doc.
- match result_unwind {
- // These return codes seem to be benign and need to be ignored for backtraces
- // to show up properly on all tested platforms.
- uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
- Ok((cx.idx, BacktraceContext))
- }
- _ => {
- Err(io::Error::new(io::ErrorKind::Other,
- UnwindError(result_unwind)))
- }
- }
-}
-
-extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
- arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
- let cx = unsafe { &mut *(arg as *mut Context) };
- if cx.idx >= cx.frames.len() {
- return uw::_URC_NORMAL_STOP;
- }
-
- let mut ip_before_insn = 0;
- let mut ip = unsafe {
- uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
- };
- if !ip.is_null() && ip_before_insn == 0 {
- // this is a non-signaling frame, so `ip` refers to the address
- // after the calling instruction. account for that.
- ip = (ip as usize - 1) as *mut _;
- }
-
- // dladdr() on osx gets whiny when we use FindEnclosingFunction, and
- // it appears to work fine without it, so we only use
- // FindEnclosingFunction on non-osx platforms. In doing so, we get a
- // slightly more accurate stack trace in the process.
- //
- // This is often because panic involves the last instruction of a
- // function being "call std::rt::begin_unwind", with no ret
- // instructions after it. This means that the return instruction
- // pointer points *outside* of the calling function, and by
- // unwinding it we go back to the original function.
- let symaddr = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
- ip
- } else {
- unsafe { uw::_Unwind_FindEnclosingFunction(ip) }
- };
-
- cx.frames[cx.idx] = Frame {
- symbol_addr: symaddr as *mut u8,
- exact_position: ip as *mut u8,
- inline_context: 0,
- };
- cx.idx += 1;
-
- uw::_URC_NO_REASON
-}
diff --git a/ctr-std/src/sys/unix/backtrace/tracing/mod.rs b/ctr-std/src/sys/unix/backtrace/tracing/mod.rs
deleted file mode 100644
index c9c8e26..0000000
--- a/ctr-std/src/sys/unix/backtrace/tracing/mod.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub use self::imp::*;
-
-#[cfg(not(all(target_os = "ios", target_arch = "arm")))]
-#[path = "gcc_s.rs"]
-mod imp;
-#[cfg(all(target_os = "ios", target_arch = "arm"))]
-#[path = "backtrace_fn.rs"]
-mod imp;
diff --git a/ctr-std/src/sys/unix/cmath.rs b/ctr-std/src/sys/unix/cmath.rs
deleted file mode 100644
index 2bc9665..0000000
--- a/ctr-std/src/sys/unix/cmath.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![cfg(not(test))]
-
-use libc::{c_float, c_double};
-
-#[link_name = "m"]
-extern {
- pub fn acos(n: c_double) -> c_double;
- pub fn acosf(n: c_float) -> c_float;
- pub fn asin(n: c_double) -> c_double;
- pub fn asinf(n: c_float) -> c_float;
- pub fn atan(n: c_double) -> c_double;
- pub fn atan2(a: c_double, b: c_double) -> c_double;
- pub fn atan2f(a: c_float, b: c_float) -> c_float;
- pub fn atanf(n: c_float) -> c_float;
- pub fn cbrt(n: c_double) -> c_double;
- pub fn cbrtf(n: c_float) -> c_float;
- pub fn cosh(n: c_double) -> c_double;
- pub fn coshf(n: c_float) -> c_float;
- pub fn expm1(n: c_double) -> c_double;
- pub fn expm1f(n: c_float) -> c_float;
- pub fn fdim(a: c_double, b: c_double) -> c_double;
- pub fn fdimf(a: c_float, b: c_float) -> c_float;
- pub fn hypot(x: c_double, y: c_double) -> c_double;
- pub fn hypotf(x: c_float, y: c_float) -> c_float;
- pub fn log1p(n: c_double) -> c_double;
- pub fn log1pf(n: c_float) -> c_float;
- pub fn sinh(n: c_double) -> c_double;
- pub fn sinhf(n: c_float) -> c_float;
- pub fn tan(n: c_double) -> c_double;
- pub fn tanf(n: c_float) -> c_float;
- pub fn tanh(n: c_double) -> c_double;
- pub fn tanhf(n: c_float) -> c_float;
-}
diff --git a/ctr-std/src/sys/unix/condvar.rs b/ctr-std/src/sys/unix/condvar.rs
deleted file mode 100644
index 2007da7..0000000
--- a/ctr-std/src/sys/unix/condvar.rs
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use cell::UnsafeCell;
-use libc;
-use sys::mutex::{self, Mutex};
-use time::Duration;
-
-pub struct Condvar { inner: UnsafeCell<libc::pthread_cond_t> }
-
-unsafe impl Send for Condvar {}
-unsafe impl Sync for Condvar {}
-
-const TIMESPEC_MAX: libc::timespec = libc::timespec {
- tv_sec: <libc::time_t>::max_value(),
- tv_nsec: 1_000_000_000 - 1,
-};
-
-fn saturating_cast_to_time_t(value: u64) -> libc::time_t {
- if value > <libc::time_t>::max_value() as u64 {
- <libc::time_t>::max_value()
- } else {
- value as libc::time_t
- }
-}
-
-impl Condvar {
- pub const fn new() -> Condvar {
- // Might be moved and address is changing it is better to avoid
- // initialization of potentially opaque OS data before it landed
- Condvar { inner: UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER) }
- }
-
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "l4re",
- target_os = "android",
- target_os = "hermit"))]
- pub unsafe fn init(&mut self) {}
-
- #[cfg(not(any(target_os = "macos",
- target_os = "ios",
- target_os = "l4re",
- target_os = "android",
- target_os = "hermit")))]
- pub unsafe fn init(&mut self) {
- use mem;
- let mut attr: libc::pthread_condattr_t = mem::uninitialized();
- let r = libc::pthread_condattr_init(&mut attr);
- assert_eq!(r, 0);
- let r = libc::pthread_condattr_setclock(&mut attr, libc::CLOCK_MONOTONIC);
- assert_eq!(r, 0);
- let r = libc::pthread_cond_init(self.inner.get(), &attr);
- assert_eq!(r, 0);
- let r = libc::pthread_condattr_destroy(&mut attr);
- assert_eq!(r, 0);
- }
-
- #[inline]
- pub unsafe fn notify_one(&self) {
- let r = libc::pthread_cond_signal(self.inner.get());
- debug_assert_eq!(r, 0);
- }
-
- #[inline]
- pub unsafe fn notify_all(&self) {
- let r = libc::pthread_cond_broadcast(self.inner.get());
- debug_assert_eq!(r, 0);
- }
-
- #[inline]
- pub unsafe fn wait(&self, mutex: &Mutex) {
- let r = libc::pthread_cond_wait(self.inner.get(), mutex::raw(mutex));
- debug_assert_eq!(r, 0);
- }
-
- // This implementation is used on systems that support pthread_condattr_setclock
- // where we configure condition variable to use monotonic clock (instead of
- // default system clock). This approach avoids all problems that result
- // from changes made to the system time.
- #[cfg(not(any(target_os = "macos",
- target_os = "ios",
- target_os = "android",
- target_os = "hermit")))]
- pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
- use mem;
-
- let mut now: libc::timespec = mem::zeroed();
- let r = libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut now);
- assert_eq!(r, 0);
-
- // Nanosecond calculations can't overflow because both values are below 1e9.
- let nsec = dur.subsec_nanos() + now.tv_nsec as u32;
-
- let sec = saturating_cast_to_time_t(dur.as_secs())
- .checked_add((nsec / 1_000_000_000) as libc::time_t)
- .and_then(|s| s.checked_add(now.tv_sec));
- let nsec = nsec % 1_000_000_000;
-
- let timeout = sec.map(|s| {
- libc::timespec { tv_sec: s, tv_nsec: nsec as _}
- }).unwrap_or(TIMESPEC_MAX);
-
- let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
- &timeout);
- assert!(r == libc::ETIMEDOUT || r == 0);
- r == 0
- }
-
-
- // This implementation is modeled after libcxx's condition_variable
- // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46
- // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367
- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android", target_os = "hermit"))]
- pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool {
- use ptr;
- use time::Instant;
-
- // 1000 years
- let max_dur = Duration::from_secs(1000 * 365 * 86400);
-
- if dur > max_dur {
- // OSX implementation of `pthread_cond_timedwait` is buggy
- // with super long durations. When duration is greater than
- // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait`
- // in macOS Sierra return error 316.
- //
- // This program demonstrates the issue:
- // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c
- //
- // To work around this issue, and possible bugs of other OSes, timeout
- // is clamped to 1000 years, which is allowable per the API of `wait_timeout`
- // because of spurious wakeups.
-
- dur = max_dur;
- }
-
- // First, figure out what time it currently is, in both system and
- // stable time. pthread_cond_timedwait uses system time, but we want to
- // report timeout based on stable time.
- let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 };
- let stable_now = Instant::now();
- let r = libc::gettimeofday(&mut sys_now, ptr::null_mut());
- debug_assert_eq!(r, 0);
-
- let nsec = dur.subsec_nanos() as libc::c_long +
- (sys_now.tv_usec * 1000) as libc::c_long;
- let extra = (nsec / 1_000_000_000) as libc::time_t;
- let nsec = nsec % 1_000_000_000;
- let seconds = saturating_cast_to_time_t(dur.as_secs());
-
- let timeout = sys_now.tv_sec.checked_add(extra).and_then(|s| {
- s.checked_add(seconds)
- }).map(|s| {
- libc::timespec { tv_sec: s, tv_nsec: nsec }
- }).unwrap_or(TIMESPEC_MAX);
-
- // And wait!
- let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
- &timeout);
- debug_assert!(r == libc::ETIMEDOUT || r == 0);
-
- // ETIMEDOUT is not a totally reliable method of determining timeout due
- // to clock shifts, so do the check ourselves
- stable_now.elapsed() < dur
- }
-
- #[inline]
- #[cfg(not(target_os = "dragonfly"))]
- pub unsafe fn destroy(&self) {
- let r = libc::pthread_cond_destroy(self.inner.get());
- debug_assert_eq!(r, 0);
- }
-
- #[inline]
- #[cfg(target_os = "dragonfly")]
- pub unsafe fn destroy(&self) {
- let r = libc::pthread_cond_destroy(self.inner.get());
- // On DragonFly pthread_cond_destroy() returns EINVAL if called on
- // a condvar that was just initialized with
- // libc::PTHREAD_COND_INITIALIZER. Once it is used or
- // pthread_cond_init() is called, this behaviour no longer occurs.
- debug_assert!(r == 0 || r == libc::EINVAL);
- }
-}
diff --git a/ctr-std/src/sys/unix/env.rs b/ctr-std/src/sys/unix/env.rs
deleted file mode 100644
index ad116c5..0000000
--- a/ctr-std/src/sys/unix/env.rs
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[cfg(target_os = "linux")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "linux";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "macos")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "macos";
- pub const DLL_PREFIX: &'static str = "lib";
- pub const DLL_SUFFIX: &'static str = ".dylib";
- pub const DLL_EXTENSION: &'static str = "dylib";
- pub const EXE_SUFFIX: &'static str = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "ios")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "ios";
- pub const DLL_PREFIX: &'static str = "lib";
- pub const DLL_SUFFIX: &'static str = ".dylib";
- pub const DLL_EXTENSION: &'static str = "dylib";
- pub const EXE_SUFFIX: &'static str = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "freebsd")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "freebsd";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "dragonfly")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "dragonfly";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "bitrig")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "bitrig";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "netbsd")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "netbsd";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "openbsd")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "openbsd";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "android")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "android";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "solaris")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "solaris";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "haiku")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "haiku";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(all(target_os = "emscripten", target_arch = "asmjs"))]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "emscripten";
- 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 = ".js";
- pub const EXE_EXTENSION: &'static str = "js";
-}
-
-#[cfg(all(target_os = "emscripten", target_arch = "wasm32"))]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "emscripten";
- 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 = ".js";
- pub const EXE_EXTENSION: &'static str = "js";
-}
-
-#[cfg(target_os = "fuchsia")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "fuchsia";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "l4re")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "l4re";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "hermit")]
-pub mod os {
- pub const FAMILY: &'static str = "unix";
- pub const OS: &'static str = "hermit";
- 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 = "";
- pub const EXE_EXTENSION: &'static str = "";
-}
diff --git a/ctr-std/src/sys/unix/ext/ffi.rs b/ctr-std/src/sys/unix/ext/ffi.rs
deleted file mode 100644
index 8347145..0000000
--- a/ctr-std/src/sys/unix/ext/ffi.rs
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Unix-specific extension to the primitives in the `std::ffi` module
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use ffi::{OsStr, OsString};
-use mem;
-use sys::os_str::Buf;
-use sys_common::{FromInner, IntoInner, AsInner};
-
-/// Unix-specific extensions to [`OsString`].
-///
-/// [`OsString`]: ../../../../std/ffi/struct.OsString.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait OsStringExt {
- /// Creates an [`OsString`] from a byte vector.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsString;
- /// use std::os::unix::ffi::OsStringExt;
- ///
- /// let bytes = b"foo".to_vec();
- /// let os_string = OsString::from_vec(bytes);
- /// assert_eq!(os_string.to_str(), Some("foo"));
- /// ```
- ///
- /// [`OsString`]: ../../../ffi/struct.OsString.html
- #[stable(feature = "rust1", since = "1.0.0")]
- fn from_vec(vec: Vec<u8>) -> Self;
-
- /// Yields the underlying byte vector of this [`OsString`].
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsString;
- /// use std::os::unix::ffi::OsStringExt;
- ///
- /// let mut os_string = OsString::new();
- /// os_string.push("foo");
- /// let bytes = os_string.into_vec();
- /// assert_eq!(bytes, b"foo");
- /// ```
- ///
- /// [`OsString`]: ../../../ffi/struct.OsString.html
- #[stable(feature = "rust1", since = "1.0.0")]
- fn into_vec(self) -> Vec<u8>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl OsStringExt for OsString {
- fn from_vec(vec: Vec<u8>) -> OsString {
- FromInner::from_inner(Buf { inner: vec })
- }
- fn into_vec(self) -> Vec<u8> {
- self.into_inner().inner
- }
-}
-
-/// Unix-specific extensions to [`OsStr`].
-///
-/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait OsStrExt {
- #[stable(feature = "rust1", since = "1.0.0")]
- /// Creates an [`OsStr`] from a byte slice.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsStr;
- /// use std::os::unix::ffi::OsStrExt;
- ///
- /// let bytes = b"foo";
- /// let os_str = OsStr::from_bytes(bytes);
- /// assert_eq!(os_str.to_str(), Some("foo"));
- /// ```
- ///
- /// [`OsStr`]: ../../../ffi/struct.OsStr.html
- fn from_bytes(slice: &[u8]) -> &Self;
-
- /// Gets the underlying byte view of the [`OsStr`] slice.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsStr;
- /// use std::os::unix::ffi::OsStrExt;
- ///
- /// let mut os_str = OsStr::new("foo");
- /// let bytes = os_str.as_bytes();
- /// assert_eq!(bytes, b"foo");
- /// ```
- ///
- /// [`OsStr`]: ../../../ffi/struct.OsStr.html
- #[stable(feature = "rust1", since = "1.0.0")]
- fn as_bytes(&self) -> &[u8];
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl OsStrExt for OsStr {
- fn from_bytes(slice: &[u8]) -> &OsStr {
- unsafe { mem::transmute(slice) }
- }
- fn as_bytes(&self) -> &[u8] {
- &self.as_inner().inner
- }
-}
diff --git a/ctr-std/src/sys/unix/ext/fs.rs b/ctr-std/src/sys/unix/ext/fs.rs
deleted file mode 100644
index 507e9d8..0000000
--- a/ctr-std/src/sys/unix/ext/fs.rs
+++ /dev/null
@@ -1,863 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Unix-specific extensions to primitives in the `std::fs` module.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use fs::{self, Permissions, OpenOptions};
-use io;
-use libc;
-use path::Path;
-use sys;
-use sys_common::{FromInner, AsInner, AsInnerMut};
-use sys::platform::fs::MetadataExt as UnixMetadataExt;
-
-/// Unix-specific extensions to [`File`].
-///
-/// [`File`]: ../../../../std/fs/struct.File.html
-#[stable(feature = "file_offset", since = "1.15.0")]
-pub trait FileExt {
- /// Reads a number of bytes starting from a given offset.
- ///
- /// Returns the number of bytes read.
- ///
- /// The offset is relative to the start of the file and thus independent
- /// from the current cursor.
- ///
- /// The current file cursor is not affected by this function.
- ///
- /// Note that similar to [`File::read`], it is not an error to return with a
- /// short read.
- ///
- /// [`File::read`]: ../../../../std/fs/struct.File.html#method.read
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::io;
- /// use std::fs::File;
- /// use std::os::unix::prelude::FileExt;
- ///
- /// fn main() -> io::Result<()> {
- /// let mut buf = [0u8; 8];
- /// let file = File::open("foo.txt")?;
- ///
- /// // We now read 8 bytes from the offset 10.
- /// let num_bytes_read = file.read_at(&mut buf, 10)?;
- /// println!("read {} bytes: {:?}", num_bytes_read, buf);
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "file_offset", since = "1.15.0")]
- fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
-
- /// Reads the exact number of byte required to fill `buf` from the given offset.
- ///
- /// The offset is relative to the start of the file and thus independent
- /// from the current cursor.
- ///
- /// The current file cursor is not affected by this function.
- ///
- /// Similar to [`Read::read_exact`] but uses [`read_at`] instead of `read`.
- ///
- /// [`Read::read_exact`]: ../../../../std/io/trait.Read.html#method.read_exact
- /// [`read_at`]: #tymethod.read_at
- ///
- /// # Errors
- ///
- /// If this function encounters an error of the kind
- /// [`ErrorKind::Interrupted`] then the error is ignored and the operation
- /// will continue.
- ///
- /// If this function encounters an "end of file" before completely filling
- /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`].
- /// The contents of `buf` are unspecified in this case.
- ///
- /// If any other read error is encountered then this function immediately
- /// returns. The contents of `buf` are unspecified in this case.
- ///
- /// If this function returns an error, it is unspecified how many bytes it
- /// has read, but it will never read more than would be necessary to
- /// completely fill the buffer.
- ///
- /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted
- /// [`ErrorKind::UnexpectedEof`]: ../../../../std/io/enum.ErrorKind.html#variant.UnexpectedEof
- ///
- /// # Examples
- ///
- /// ```no_run
- /// #![feature(rw_exact_all_at)]
- /// use std::io;
- /// use std::fs::File;
- /// use std::os::unix::prelude::FileExt;
- ///
- /// fn main() -> io::Result<()> {
- /// let mut buf = [0u8; 8];
- /// let file = File::open("foo.txt")?;
- ///
- /// // We now read exactly 8 bytes from the offset 10.
- /// file.read_exact_at(&mut buf, 10)?;
- /// println!("read {} bytes: {:?}", buf.len(), buf);
- /// Ok(())
- /// }
- /// ```
- #[unstable(feature = "rw_exact_all_at", issue = "51984")]
- fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
- while !buf.is_empty() {
- match self.read_at(buf, offset) {
- Ok(0) => break,
- Ok(n) => {
- let tmp = buf;
- buf = &mut tmp[n..];
- offset += n as u64;
- }
- Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
- Err(e) => return Err(e),
- }
- }
- if !buf.is_empty() {
- Err(io::Error::new(io::ErrorKind::UnexpectedEof,
- "failed to fill whole buffer"))
- } else {
- Ok(())
- }
- }
-
- /// Writes a number of bytes starting from a given offset.
- ///
- /// Returns the number of bytes written.
- ///
- /// The offset is relative to the start of the file and thus independent
- /// from the current cursor.
- ///
- /// The current file cursor is not affected by this function.
- ///
- /// When writing beyond the end of the file, the file is appropriately
- /// extended and the intermediate bytes are initialized with the value 0.
- ///
- /// Note that similar to [`File::write`], it is not an error to return a
- /// short write.
- ///
- /// [`File::write`]: ../../../../std/fs/struct.File.html#write.v
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::File;
- /// use std::io;
- /// use std::os::unix::prelude::FileExt;
- ///
- /// fn main() -> io::Result<()> {
- /// let file = File::open("foo.txt")?;
- ///
- /// // We now write at the offset 10.
- /// file.write_at(b"sushi", 10)?;
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "file_offset", since = "1.15.0")]
- fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
-
- /// Attempts to write an entire buffer starting from a given offset.
- ///
- /// The offset is relative to the start of the file and thus independent
- /// from the current cursor.
- ///
- /// The current file cursor is not affected by this function.
- ///
- /// This method will continuously call [`write_at`] until there is no more data
- /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is
- /// returned. This method will not return until the entire buffer has been
- /// successfully written or such an error occurs. The first error that is
- /// not of [`ErrorKind::Interrupted`] kind generated from this method will be
- /// returned.
- ///
- /// # Errors
- ///
- /// This function will return the first error of
- /// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns.
- ///
- /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted
- /// [`write_at`]: #tymethod.write_at
- ///
- /// # Examples
- ///
- /// ```no_run
- /// #![feature(rw_exact_all_at)]
- /// use std::fs::File;
- /// use std::io;
- /// use std::os::unix::prelude::FileExt;
- ///
- /// fn main() -> io::Result<()> {
- /// let file = File::open("foo.txt")?;
- ///
- /// // We now write at the offset 10.
- /// file.write_all_at(b"sushi", 10)?;
- /// Ok(())
- /// }
- /// ```
- #[unstable(feature = "rw_exact_all_at", issue = "51984")]
- fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
- while !buf.is_empty() {
- match self.write_at(buf, offset) {
- Ok(0) => return Err(io::Error::new(io::ErrorKind::WriteZero,
- "failed to write whole buffer")),
- Ok(n) => {
- buf = &buf[n..];
- offset += n as u64
- }
- Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
- Err(e) => return Err(e),
- }
- }
- Ok(())
- }
-}
-
-#[stable(feature = "file_offset", since = "1.15.0")]
-impl FileExt for fs::File {
- fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
- self.as_inner().read_at(buf, offset)
- }
- fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
- self.as_inner().write_at(buf, offset)
- }
-}
-
-/// Unix-specific extensions to [`fs::Permissions`].
-///
-/// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html
-#[stable(feature = "fs_ext", since = "1.1.0")]
-pub trait PermissionsExt {
- /// Returns the underlying raw `st_mode` bits that contain the standard
- /// Unix permissions for this file.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::File;
- /// use std::os::unix::fs::PermissionsExt;
- ///
- /// fn main() -> std::io::Result<()> {
- /// let f = File::create("foo.txt")?;
- /// let metadata = f.metadata()?;
- /// let permissions = metadata.permissions();
- ///
- /// println!("permissions: {}", permissions.mode());
- /// Ok(()) }
- /// ```
- #[stable(feature = "fs_ext", since = "1.1.0")]
- fn mode(&self) -> u32;
-
- /// Sets the underlying raw bits for this set of permissions.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::File;
- /// use std::os::unix::fs::PermissionsExt;
- ///
- /// fn main() -> std::io::Result<()> {
- /// let f = File::create("foo.txt")?;
- /// let metadata = f.metadata()?;
- /// let mut permissions = metadata.permissions();
- ///
- /// permissions.set_mode(0o644); // Read/write for owner and read for others.
- /// assert_eq!(permissions.mode(), 0o644);
- /// Ok(()) }
- /// ```
- #[stable(feature = "fs_ext", since = "1.1.0")]
- fn set_mode(&mut self, mode: u32);
-
- /// Creates a new instance of `Permissions` from the given set of Unix
- /// permission bits.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::fs::Permissions;
- /// use std::os::unix::fs::PermissionsExt;
- ///
- /// // Read/write for owner and read for others.
- /// let permissions = Permissions::from_mode(0o644);
- /// assert_eq!(permissions.mode(), 0o644);
- /// ```
- #[stable(feature = "fs_ext", since = "1.1.0")]
- fn from_mode(mode: u32) -> Self;
-}
-
-#[stable(feature = "fs_ext", since = "1.1.0")]
-impl PermissionsExt for Permissions {
- fn mode(&self) -> u32 {
- self.as_inner().mode()
- }
-
- fn set_mode(&mut self, mode: u32) {
- *self = Permissions::from_inner(FromInner::from_inner(mode));
- }
-
- fn from_mode(mode: u32) -> Permissions {
- Permissions::from_inner(FromInner::from_inner(mode))
- }
-}
-
-/// Unix-specific extensions to [`fs::OpenOptions`].
-///
-/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
-#[stable(feature = "fs_ext", since = "1.1.0")]
-pub trait OpenOptionsExt {
- /// Sets the mode bits that a new file will be created with.
- ///
- /// If a new file is created as part of a `File::open_opts` call then this
- /// specified `mode` will be used as the permission bits for the new file.
- /// If no `mode` is set, the default of `0o666` will be used.
- /// The operating system masks out bits with the systems `umask`, to produce
- /// the final permissions.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::OpenOptions;
- /// use std::os::unix::fs::OpenOptionsExt;
- ///
- /// # fn main() {
- /// let mut options = OpenOptions::new();
- /// options.mode(0o644); // Give read/write for owner and read for others.
- /// let file = options.open("foo.txt");
- /// # }
- /// ```
- #[stable(feature = "fs_ext", since = "1.1.0")]
- fn mode(&mut self, mode: u32) -> &mut Self;
-
- /// Pass custom flags to the `flags` argument of `open`.
- ///
- /// The bits that define the access mode are masked out with `O_ACCMODE`, to
- /// ensure they do not interfere with the access mode set by Rusts options.
- ///
- /// Custom flags can only set flags, not remove flags set by Rusts options.
- /// This options overwrites any previously set custom flags.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// # #![feature(libc)]
- /// extern crate libc;
- /// use std::fs::OpenOptions;
- /// use std::os::unix::fs::OpenOptionsExt;
- ///
- /// # fn main() {
- /// let mut options = OpenOptions::new();
- /// options.write(true);
- /// if cfg!(unix) {
- /// options.custom_flags(libc::O_NOFOLLOW);
- /// }
- /// let file = options.open("foo.txt");
- /// # }
- /// ```
- #[stable(feature = "open_options_ext", since = "1.10.0")]
- fn custom_flags(&mut self, flags: i32) -> &mut Self;
-}
-
-#[stable(feature = "fs_ext", since = "1.1.0")]
-impl OpenOptionsExt for OpenOptions {
- fn mode(&mut self, mode: u32) -> &mut OpenOptions {
- self.as_inner_mut().mode(mode); self
- }
-
- fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
- self.as_inner_mut().custom_flags(flags); self
- }
-}
-
-/// Unix-specific extensions to [`fs::Metadata`].
-///
-/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
-#[stable(feature = "metadata_ext", since = "1.1.0")]
-pub trait MetadataExt {
- /// Returns the ID of the device containing the file.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::io;
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let dev_id = meta.dev();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn dev(&self) -> u64;
- /// Returns the inode number.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let inode = meta.ino();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn ino(&self) -> u64;
- /// Returns the rights applied to this file.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let mode = meta.mode();
- /// let user_has_write_access = mode & 0o200;
- /// let user_has_read_write_access = mode & 0o600;
- /// let group_has_read_access = mode & 0o040;
- /// let others_have_exec_access = mode & 0o001;
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn mode(&self) -> u32;
- /// Returns the number of hard links pointing to this file.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let nb_hard_links = meta.nlink();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn nlink(&self) -> u64;
- /// Returns the user ID of the owner of this file.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let user_id = meta.uid();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn uid(&self) -> u32;
- /// Returns the group ID of the owner of this file.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let group_id = meta.gid();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn gid(&self) -> u32;
- /// Returns the device ID of this file (if it is a special one).
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let device_id = meta.rdev();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn rdev(&self) -> u64;
- /// Returns the total size of this file in bytes.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let file_size = meta.size();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn size(&self) -> u64;
- /// Returns the time of the last access to the file.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let last_access_time = meta.atime();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn atime(&self) -> i64;
- /// Returns the time of the last access to the file in nanoseconds.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let nano_last_access_time = meta.atime_nsec();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn atime_nsec(&self) -> i64;
- /// Returns the time of the last modification of the file.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let last_modification_time = meta.mtime();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn mtime(&self) -> i64;
- /// Returns the time of the last modification of the file in nanoseconds.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let nano_last_modification_time = meta.mtime_nsec();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn mtime_nsec(&self) -> i64;
- /// Returns the time of the last status change of the file.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let last_status_change_time = meta.ctime();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn ctime(&self) -> i64;
- /// Returns the time of the last status change of the file in nanoseconds.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let nano_last_status_change_time = meta.ctime_nsec();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn ctime_nsec(&self) -> i64;
- /// Returns the blocksize for filesystem I/O.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let blocksize = meta.blksize();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn blksize(&self) -> u64;
- /// Returns the number of blocks allocated to the file, in 512-byte units.
- ///
- /// Please note that this may be smaller than `st_size / 512` when the file has holes.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::MetadataExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("some_file")?;
- /// let blocks = meta.blocks();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn blocks(&self) -> u64;
-}
-
-#[stable(feature = "metadata_ext", since = "1.1.0")]
-impl MetadataExt for fs::Metadata {
- fn dev(&self) -> u64 { self.st_dev() }
- fn ino(&self) -> u64 { self.st_ino() }
- fn mode(&self) -> u32 { self.st_mode() }
- fn nlink(&self) -> u64 { self.st_nlink() }
- fn uid(&self) -> u32 { self.st_uid() }
- fn gid(&self) -> u32 { self.st_gid() }
- fn rdev(&self) -> u64 { self.st_rdev() }
- fn size(&self) -> u64 { self.st_size() }
- fn atime(&self) -> i64 { self.st_atime() }
- fn atime_nsec(&self) -> i64 { self.st_atime_nsec() }
- fn mtime(&self) -> i64 { self.st_mtime() }
- fn mtime_nsec(&self) -> i64 { self.st_mtime_nsec() }
- fn ctime(&self) -> i64 { self.st_ctime() }
- fn ctime_nsec(&self) -> i64 { self.st_ctime_nsec() }
- fn blksize(&self) -> u64 { self.st_blksize() }
- fn blocks(&self) -> u64 { self.st_blocks() }
-}
-
-/// Unix-specific extensions for [`FileType`].
-///
-/// Adds support for special Unix file types such as block/character devices,
-/// pipes, and sockets.
-///
-/// [`FileType`]: ../../../../std/fs/struct.FileType.html
-#[stable(feature = "file_type_ext", since = "1.5.0")]
-pub trait FileTypeExt {
- /// Returns whether this file type is a block device.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::FileTypeExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("block_device_file")?;
- /// let file_type = meta.file_type();
- /// assert!(file_type.is_block_device());
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "file_type_ext", since = "1.5.0")]
- fn is_block_device(&self) -> bool;
- /// Returns whether this file type is a char device.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::FileTypeExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("char_device_file")?;
- /// let file_type = meta.file_type();
- /// assert!(file_type.is_char_device());
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "file_type_ext", since = "1.5.0")]
- fn is_char_device(&self) -> bool;
- /// Returns whether this file type is a fifo.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::FileTypeExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("fifo_file")?;
- /// let file_type = meta.file_type();
- /// assert!(file_type.is_fifo());
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "file_type_ext", since = "1.5.0")]
- fn is_fifo(&self) -> bool;
- /// Returns whether this file type is a socket.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs;
- /// use std::os::unix::fs::FileTypeExt;
- /// use std::io;
- ///
- /// fn main() -> io::Result<()> {
- /// let meta = fs::metadata("unix.socket")?;
- /// let file_type = meta.file_type();
- /// assert!(file_type.is_socket());
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "file_type_ext", since = "1.5.0")]
- fn is_socket(&self) -> bool;
-}
-
-#[stable(feature = "file_type_ext", since = "1.5.0")]
-impl FileTypeExt for fs::FileType {
- fn is_block_device(&self) -> bool { self.as_inner().is(libc::S_IFBLK) }
- fn is_char_device(&self) -> bool { self.as_inner().is(libc::S_IFCHR) }
- fn is_fifo(&self) -> bool { self.as_inner().is(libc::S_IFIFO) }
- fn is_socket(&self) -> bool { self.as_inner().is(libc::S_IFSOCK) }
-}
-
-/// Unix-specific extension methods for [`fs::DirEntry`].
-///
-/// [`fs::DirEntry`]: ../../../../std/fs/struct.DirEntry.html
-#[stable(feature = "dir_entry_ext", since = "1.1.0")]
-pub trait DirEntryExt {
- /// Returns the underlying `d_ino` field in the contained `dirent`
- /// structure.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::fs;
- /// use std::os::unix::fs::DirEntryExt;
- ///
- /// if let Ok(entries) = fs::read_dir(".") {
- /// for entry in entries {
- /// if let Ok(entry) = entry {
- /// // Here, `entry` is a `DirEntry`.
- /// println!("{:?}: {}", entry.file_name(), entry.ino());
- /// }
- /// }
- /// }
- /// ```
- #[stable(feature = "dir_entry_ext", since = "1.1.0")]
- fn ino(&self) -> u64;
-}
-
-#[stable(feature = "dir_entry_ext", since = "1.1.0")]
-impl DirEntryExt for fs::DirEntry {
- fn ino(&self) -> u64 { self.as_inner().ino() }
-}
-
-/// Creates a new symbolic link on the filesystem.
-///
-/// The `dst` path will be a symbolic link pointing to the `src` path.
-///
-/// # Note
-///
-/// On Windows, you must specify whether a symbolic link points to a file
-/// or directory. Use `os::windows::fs::symlink_file` to create a
-/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
-/// symbolic link to a directory. Additionally, the process must have
-/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
-/// symbolic link.
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::os::unix::fs;
-///
-/// fn main() -> std::io::Result<()> {
-/// fs::symlink("a.txt", "b.txt")?;
-/// Ok(())
-/// }
-/// ```
-#[stable(feature = "symlink", since = "1.1.0")]
-pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
-{
- sys::fs::symlink(src.as_ref(), dst.as_ref())
-}
-
-/// Unix-specific extensions to [`fs::DirBuilder`].
-///
-/// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html
-#[stable(feature = "dir_builder", since = "1.6.0")]
-pub trait DirBuilderExt {
- /// Sets the mode to create new directories with. This option defaults to
- /// 0o777.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::DirBuilder;
- /// use std::os::unix::fs::DirBuilderExt;
- ///
- /// let mut builder = DirBuilder::new();
- /// builder.mode(0o755);
- /// ```
- #[stable(feature = "dir_builder", since = "1.6.0")]
- fn mode(&mut self, mode: u32) -> &mut Self;
-}
-
-#[stable(feature = "dir_builder", since = "1.6.0")]
-impl DirBuilderExt for fs::DirBuilder {
- fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder {
- self.as_inner_mut().set_mode(mode);
- self
- }
-}
diff --git a/ctr-std/src/sys/unix/ext/io.rs b/ctr-std/src/sys/unix/ext/io.rs
deleted file mode 100644
index c9fe359..0000000
--- a/ctr-std/src/sys/unix/ext/io.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Unix-specific extensions to general I/O primitives
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use fs;
-use os::raw;
-use sys;
-use io;
-use sys_common::{AsInner, FromInner, IntoInner};
-use libc;
-
-/// Raw file descriptors.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type RawFd = raw::c_int;
-
-/// A trait to extract the raw unix file descriptor from an underlying
-/// object.
-///
-/// This is only available on unix platforms and must be imported in order
-/// to call the method. Windows platforms have a corresponding `AsRawHandle`
-/// and `AsRawSocket` set of traits.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait AsRawFd {
- /// Extracts the raw file descriptor.
- ///
- /// This method does **not** pass ownership of the raw file descriptor
- /// to the caller. The descriptor is only guaranteed to be valid while
- /// the original object has not yet been destroyed.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn as_raw_fd(&self) -> RawFd;
-}
-
-/// A trait to express the ability to construct an object from a raw file
-/// descriptor.
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-pub trait FromRawFd {
- /// Constructs a new instance of `Self` from the given raw file
- /// descriptor.
- ///
- /// This function **consumes ownership** of the specified file
- /// descriptor. The returned object will take responsibility for closing
- /// it when the object goes out of scope.
- ///
- /// This function is also unsafe as the primitives currently returned
- /// have the contract that they are the sole owner of the file
- /// descriptor they are wrapping. Usage of this function could
- /// accidentally allow violating this contract which can cause memory
- /// unsafety in code that relies on it being true.
- #[stable(feature = "from_raw_os", since = "1.1.0")]
- unsafe fn from_raw_fd(fd: RawFd) -> Self;
-}
-
-/// A trait to express the ability to consume an object and acquire ownership of
-/// its raw file descriptor.
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-pub trait IntoRawFd {
- /// Consumes this object, returning the raw underlying file descriptor.
- ///
- /// This function **transfers ownership** of the underlying file descriptor
- /// to the caller. Callers are then the unique owners of the file descriptor
- /// and must close the descriptor once it's no longer needed.
- #[stable(feature = "into_raw_os", since = "1.4.0")]
- fn into_raw_fd(self) -> RawFd;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawFd for fs::File {
- fn as_raw_fd(&self) -> RawFd {
- self.as_inner().fd().raw()
- }
-}
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawFd for fs::File {
- unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
- fs::File::from_inner(sys::fs::File::from_inner(fd))
- }
-}
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for fs::File {
- fn into_raw_fd(self) -> RawFd {
- self.into_inner().into_fd().into_raw()
- }
-}
-
-#[stable(feature = "asraw_stdio", since = "1.21.0")]
-impl AsRawFd for io::Stdin {
- fn as_raw_fd(&self) -> RawFd { libc::STDIN_FILENO }
-}
-
-#[stable(feature = "asraw_stdio", since = "1.21.0")]
-impl AsRawFd for io::Stdout {
- fn as_raw_fd(&self) -> RawFd { libc::STDOUT_FILENO }
-}
-
-#[stable(feature = "asraw_stdio", since = "1.21.0")]
-impl AsRawFd for io::Stderr {
- fn as_raw_fd(&self) -> RawFd { libc::STDERR_FILENO }
-}
diff --git a/ctr-std/src/sys/unix/ext/mod.rs b/ctr-std/src/sys/unix/ext/mod.rs
deleted file mode 100644
index 88e4237..0000000
--- a/ctr-std/src/sys/unix/ext/mod.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Experimental extensions to `std` for Unix platforms.
-//!
-//! Provides access to platform-level information on Unix platforms, and
-//! exposes Unix-specific functions that would otherwise be inappropriate as
-//! part of the core `std` library.
-//!
-//! It exposes more ways to deal with platform-specific strings (`OsStr`,
-//! `OsString`), allows to set permissions more granularly, extract low-level
-//! file descriptors from files and sockets, and has platform-specific helpers
-//! for spawning processes.
-//!
-//! # Examples
-//!
-//! ```no_run
-//! use std::fs::File;
-//! use std::os::unix::prelude::*;
-//!
-//! fn main() {
-//! let f = File::create("foo.txt").unwrap();
-//! let fd = f.as_raw_fd();
-//!
-//! // use fd with native unix bindings
-//! }
-//! ```
-
-#![stable(feature = "rust1", since = "1.0.0")]
-#![doc(cfg(unix))]
-#![allow(missing_docs)]
-
-pub mod io;
-pub mod ffi;
-pub mod fs;
-pub mod process;
-pub mod raw;
-pub mod thread;
-pub mod net;
-
-/// A prelude for conveniently writing platform-specific code.
-///
-/// Includes all extension traits, and some important type definitions.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod prelude {
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::ffi::{OsStrExt, OsStringExt};
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::fs::{PermissionsExt, OpenOptionsExt, MetadataExt, FileTypeExt};
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::fs::DirEntryExt;
- #[doc(no_inline)] #[stable(feature = "file_offset", since = "1.15.0")]
- pub use super::fs::FileExt;
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::thread::JoinHandleExt;
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::process::{CommandExt, ExitStatusExt};
-}
diff --git a/ctr-std/src/sys/unix/ext/net.rs b/ctr-std/src/sys/unix/ext/net.rs
deleted file mode 100644
index 55f43cc..0000000
--- a/ctr-std/src/sys/unix/ext/net.rs
+++ /dev/null
@@ -1,1824 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![stable(feature = "unix_socket", since = "1.10.0")]
-
-//! Unix-specific networking functionality
-
-#[cfg(unix)]
-use libc;
-
-// FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
-#[cfg(not(unix))]
-mod libc {
- pub use libc::c_int;
- pub type socklen_t = u32;
- pub struct sockaddr;
- #[derive(Clone)]
- pub struct sockaddr_un;
-}
-
-use ascii;
-use ffi::OsStr;
-use fmt;
-use io::{self, Initializer};
-use mem;
-use net::{self, Shutdown};
-use os::unix::ffi::OsStrExt;
-use os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
-use path::Path;
-use time::Duration;
-use sys::{self, cvt};
-use sys::net::Socket;
-use sys_common::{self, AsInner, FromInner, IntoInner};
-
-#[cfg(any(target_os = "linux", target_os = "android",
- target_os = "dragonfly", target_os = "freebsd",
- target_os = "openbsd", target_os = "netbsd",
- target_os = "haiku", target_os = "bitrig"))]
-use libc::MSG_NOSIGNAL;
-#[cfg(not(any(target_os = "linux", target_os = "android",
- target_os = "dragonfly", target_os = "freebsd",
- target_os = "openbsd", target_os = "netbsd",
- target_os = "haiku", target_os = "bitrig")))]
-const MSG_NOSIGNAL: libc::c_int = 0x0;
-
-fn sun_path_offset() -> usize {
- // Work with an actual instance of the type since using a null pointer is UB
- let addr: libc::sockaddr_un = unsafe { mem::uninitialized() };
- let base = &addr as *const _ as usize;
- let path = &addr.sun_path as *const _ as usize;
- path - base
-}
-
-unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
- let mut addr: libc::sockaddr_un = mem::zeroed();
- addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
-
- let bytes = path.as_os_str().as_bytes();
-
- if bytes.contains(&0) {
- return Err(io::Error::new(io::ErrorKind::InvalidInput,
- "paths may not contain interior null bytes"));
- }
-
- if bytes.len() >= addr.sun_path.len() {
- return Err(io::Error::new(io::ErrorKind::InvalidInput,
- "path must be shorter than SUN_LEN"));
- }
- for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) {
- *dst = *src as libc::c_char;
- }
- // null byte for pathname addresses is already there because we zeroed the
- // struct
-
- let mut len = sun_path_offset() + bytes.len();
- match bytes.get(0) {
- Some(&0) | None => {}
- Some(_) => len += 1,
- }
- Ok((addr, len as libc::socklen_t))
-}
-
-enum AddressKind<'a> {
- Unnamed,
- Pathname(&'a Path),
- Abstract(&'a [u8]),
-}
-
-/// An address associated with a Unix socket.
-///
-/// # Examples
-///
-/// ```
-/// use std::os::unix::net::UnixListener;
-///
-/// let socket = match UnixListener::bind("/tmp/sock") {
-/// Ok(sock) => sock,
-/// Err(e) => {
-/// println!("Couldn't bind: {:?}", e);
-/// return
-/// }
-/// };
-/// let addr = socket.local_addr().expect("Couldn't get local address");
-/// ```
-#[derive(Clone)]
-#[stable(feature = "unix_socket", since = "1.10.0")]
-pub struct SocketAddr {
- addr: libc::sockaddr_un,
- len: libc::socklen_t,
-}
-
-impl SocketAddr {
- fn new<F>(f: F) -> io::Result<SocketAddr>
- where F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::c_int
- {
- unsafe {
- let mut addr: libc::sockaddr_un = mem::zeroed();
- let mut len = mem::size_of::<libc::sockaddr_un>() as libc::socklen_t;
- cvt(f(&mut addr as *mut _ as *mut _, &mut len))?;
- SocketAddr::from_parts(addr, len)
- }
- }
-
- fn from_parts(addr: libc::sockaddr_un, mut len: libc::socklen_t) -> io::Result<SocketAddr> {
- if len == 0 {
- // When there is a datagram from unnamed unix socket
- // linux returns zero bytes of address
- len = sun_path_offset() as libc::socklen_t; // i.e. zero-length address
- } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
- return Err(io::Error::new(io::ErrorKind::InvalidInput,
- "file descriptor did not correspond to a Unix socket"));
- }
-
- Ok(SocketAddr {
- addr,
- len,
- })
- }
-
- /// Returns true if and only if the address is unnamed.
- ///
- /// # Examples
- ///
- /// A named address:
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixListener;
- ///
- /// let socket = UnixListener::bind("/tmp/sock").unwrap();
- /// let addr = socket.local_addr().expect("Couldn't get local address");
- /// assert_eq!(addr.is_unnamed(), false);
- /// ```
- ///
- /// An unnamed address:
- ///
- /// ```
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let socket = UnixDatagram::unbound().unwrap();
- /// let addr = socket.local_addr().expect("Couldn't get local address");
- /// assert_eq!(addr.is_unnamed(), true);
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn is_unnamed(&self) -> bool {
- if let AddressKind::Unnamed = self.address() {
- true
- } else {
- false
- }
- }
-
- /// Returns the contents of this address if it is a `pathname` address.
- ///
- /// # Examples
- ///
- /// With a pathname:
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixListener;
- /// use std::path::Path;
- ///
- /// let socket = UnixListener::bind("/tmp/sock").unwrap();
- /// let addr = socket.local_addr().expect("Couldn't get local address");
- /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
- /// ```
- ///
- /// Without a pathname:
- ///
- /// ```
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let socket = UnixDatagram::unbound().unwrap();
- /// let addr = socket.local_addr().expect("Couldn't get local address");
- /// assert_eq!(addr.as_pathname(), None);
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn as_pathname(&self) -> Option<&Path> {
- if let AddressKind::Pathname(path) = self.address() {
- Some(path)
- } else {
- None
- }
- }
-
- fn address<'a>(&'a self) -> AddressKind<'a> {
- let len = self.len as usize - sun_path_offset();
- let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
-
- // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
- if len == 0
- || (cfg!(not(any(target_os = "linux", target_os = "android")))
- && self.addr.sun_path[0] == 0)
- {
- AddressKind::Unnamed
- } else if self.addr.sun_path[0] == 0 {
- AddressKind::Abstract(&path[1..len])
- } else {
- AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
- }
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl fmt::Debug for SocketAddr {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- match self.address() {
- AddressKind::Unnamed => write!(fmt, "(unnamed)"),
- AddressKind::Abstract(name) => write!(fmt, "{} (abstract)", AsciiEscaped(name)),
- AddressKind::Pathname(path) => write!(fmt, "{:?} (pathname)", path),
- }
- }
-}
-
-struct AsciiEscaped<'a>(&'a [u8]);
-
-impl<'a> fmt::Display for AsciiEscaped<'a> {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- write!(fmt, "\"")?;
- for byte in self.0.iter().cloned().flat_map(ascii::escape_default) {
- write!(fmt, "{}", byte as char)?;
- }
- write!(fmt, "\"")
- }
-}
-
-/// A Unix stream socket.
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::os::unix::net::UnixStream;
-/// use std::io::prelude::*;
-///
-/// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
-/// stream.write_all(b"hello world").unwrap();
-/// let mut response = String::new();
-/// stream.read_to_string(&mut response).unwrap();
-/// println!("{}", response);
-/// ```
-#[stable(feature = "unix_socket", since = "1.10.0")]
-pub struct UnixStream(Socket);
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl fmt::Debug for UnixStream {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- let mut builder = fmt.debug_struct("UnixStream");
- builder.field("fd", self.0.as_inner());
- if let Ok(addr) = self.local_addr() {
- builder.field("local", &addr);
- }
- if let Ok(addr) = self.peer_addr() {
- builder.field("peer", &addr);
- }
- builder.finish()
- }
-}
-
-impl UnixStream {
- /// Connects to the socket named by `path`.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- ///
- /// let socket = match UnixStream::connect("/tmp/sock") {
- /// Ok(sock) => sock,
- /// Err(e) => {
- /// println!("Couldn't connect: {:?}", e);
- /// return
- /// }
- /// };
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
- fn inner(path: &Path) -> io::Result<UnixStream> {
- unsafe {
- let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
- let (addr, len) = sockaddr_un(path)?;
-
- cvt(libc::connect(*inner.as_inner(), &addr as *const _ as *const _, len))?;
- Ok(UnixStream(inner))
- }
- }
- inner(path.as_ref())
- }
-
- /// Creates an unnamed pair of connected sockets.
- ///
- /// Returns two `UnixStream`s which are connected to each other.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- ///
- /// let (sock1, sock2) = match UnixStream::pair() {
- /// Ok((sock1, sock2)) => (sock1, sock2),
- /// Err(e) => {
- /// println!("Couldn't create a pair of sockets: {:?}", e);
- /// return
- /// }
- /// };
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
- let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
- Ok((UnixStream(i1), UnixStream(i2)))
- }
-
- /// Creates a new independently owned handle to the underlying socket.
- ///
- /// The returned `UnixStream` is a reference to the same stream that this
- /// object references. Both handles will read and write the same stream of
- /// data, and options set on one stream will be propagated to the other
- /// stream.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn try_clone(&self) -> io::Result<UnixStream> {
- self.0.duplicate().map(UnixStream)
- }
-
- /// Returns the socket address of the local half of this connection.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// let addr = socket.local_addr().expect("Couldn't get local address");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn local_addr(&self) -> io::Result<SocketAddr> {
- SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
- }
-
- /// Returns the socket address of the remote half of this connection.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// let addr = socket.peer_addr().expect("Couldn't get peer address");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn peer_addr(&self) -> io::Result<SocketAddr> {
- SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
- }
-
- /// Sets the read timeout for the socket.
- ///
- /// If the provided value is [`None`], then [`read`] calls will block
- /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
- /// method.
- ///
- /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
- /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
- /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
- /// [`Duration`]: ../../../../std/time/struct.Duration.html
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- /// use std::time::Duration;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
- /// ```
- ///
- /// An [`Err`] is returned if the zero [`Duration`] is passed to this
- /// method:
- ///
- /// ```no_run
- /// use std::io;
- /// use std::os::unix::net::UnixStream;
- /// use std::time::Duration;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
- /// let err = result.unwrap_err();
- /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
- self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
- }
-
- /// Sets the write timeout for the socket.
- ///
- /// If the provided value is [`None`], then [`write`] calls will block
- /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
- /// passed to this method.
- ///
- /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
- /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
- /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write
- /// [`Duration`]: ../../../../std/time/struct.Duration.html
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- /// use std::time::Duration;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
- /// ```
- ///
- /// An [`Err`] is returned if the zero [`Duration`] is passed to this
- /// method:
- ///
- /// ```no_run
- /// use std::io;
- /// use std::net::UdpSocket;
- /// use std::time::Duration;
- ///
- /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
- /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
- /// let err = result.unwrap_err();
- /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
- self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
- }
-
- /// Returns the read timeout of this socket.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- /// use std::time::Duration;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
- /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
- self.0.timeout(libc::SO_RCVTIMEO)
- }
-
- /// Returns the write timeout of this socket.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- /// use std::time::Duration;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
- /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
- self.0.timeout(libc::SO_SNDTIMEO)
- }
-
- /// Moves the socket into or out of nonblocking mode.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- self.0.set_nonblocking(nonblocking)
- }
-
- /// Returns the value of the `SO_ERROR` option.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// if let Ok(Some(err)) = socket.take_error() {
- /// println!("Got error: {:?}", err);
- /// }
- /// ```
- ///
- /// # Platform specific
- /// On Redox this always returns None.
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- self.0.take_error()
- }
-
- /// Shuts down the read, write, or both halves of this connection.
- ///
- /// This function will cause all pending and future I/O calls on the
- /// specified portions to immediately return with an appropriate value
- /// (see the documentation of [`Shutdown`]).
- ///
- /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixStream;
- /// use std::net::Shutdown;
- ///
- /// let socket = UnixStream::connect("/tmp/sock").unwrap();
- /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
- self.0.shutdown(how)
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl io::Read for UnixStream {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- io::Read::read(&mut &*self, buf)
- }
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl<'a> io::Read for &'a UnixStream {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- self.0.read(buf)
- }
-
- #[inline]
- unsafe fn initializer(&self) -> Initializer {
- Initializer::nop()
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl io::Write for UnixStream {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- io::Write::write(&mut &*self, buf)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- io::Write::flush(&mut &*self)
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl<'a> io::Write for &'a UnixStream {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.0.write(buf)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- Ok(())
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl AsRawFd for UnixStream {
- fn as_raw_fd(&self) -> RawFd {
- *self.0.as_inner()
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl FromRawFd for UnixStream {
- unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
- UnixStream(Socket::from_inner(fd))
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl IntoRawFd for UnixStream {
- fn into_raw_fd(self) -> RawFd {
- self.0.into_inner()
- }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawFd for net::TcpStream {
- fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawFd for net::TcpListener {
- fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawFd for net::UdpSocket {
- fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
-}
-
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawFd for net::TcpStream {
- unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
- let socket = sys::net::Socket::from_inner(fd);
- net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(socket))
- }
-}
-
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawFd for net::TcpListener {
- unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
- let socket = sys::net::Socket::from_inner(fd);
- net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(socket))
- }
-}
-
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawFd for net::UdpSocket {
- unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
- let socket = sys::net::Socket::from_inner(fd);
- net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket))
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for net::TcpStream {
- fn into_raw_fd(self) -> RawFd {
- self.into_inner().into_socket().into_inner()
- }
-}
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for net::TcpListener {
- fn into_raw_fd(self) -> RawFd {
- self.into_inner().into_socket().into_inner()
- }
-}
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for net::UdpSocket {
- fn into_raw_fd(self) -> RawFd {
- self.into_inner().into_socket().into_inner()
- }
-}
-
-/// A structure representing a Unix domain socket server.
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::thread;
-/// use std::os::unix::net::{UnixStream, UnixListener};
-///
-/// fn handle_client(stream: UnixStream) {
-/// // ...
-/// }
-///
-/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
-///
-/// // accept connections and process them, spawning a new thread for each one
-/// for stream in listener.incoming() {
-/// match stream {
-/// Ok(stream) => {
-/// /* connection succeeded */
-/// thread::spawn(|| handle_client(stream));
-/// }
-/// Err(err) => {
-/// /* connection failed */
-/// break;
-/// }
-/// }
-/// }
-/// ```
-#[stable(feature = "unix_socket", since = "1.10.0")]
-pub struct UnixListener(Socket);
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl fmt::Debug for UnixListener {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- let mut builder = fmt.debug_struct("UnixListener");
- builder.field("fd", self.0.as_inner());
- if let Ok(addr) = self.local_addr() {
- builder.field("local", &addr);
- }
- builder.finish()
- }
-}
-
-impl UnixListener {
- /// Creates a new `UnixListener` bound to the specified socket.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixListener;
- ///
- /// let listener = match UnixListener::bind("/path/to/the/socket") {
- /// Ok(sock) => sock,
- /// Err(e) => {
- /// println!("Couldn't connect: {:?}", e);
- /// return
- /// }
- /// };
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
- fn inner(path: &Path) -> io::Result<UnixListener> {
- unsafe {
- let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
- let (addr, len) = sockaddr_un(path)?;
-
- cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?;
- cvt(libc::listen(*inner.as_inner(), 128))?;
-
- Ok(UnixListener(inner))
- }
- }
- inner(path.as_ref())
- }
-
- /// Accepts a new incoming connection to this listener.
- ///
- /// This function will block the calling thread until a new Unix connection
- /// is established. When established, the corresponding [`UnixStream`] and
- /// the remote peer's address will be returned.
- ///
- /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixListener;
- ///
- /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
- ///
- /// match listener.accept() {
- /// Ok((socket, addr)) => println!("Got a client: {:?}", addr),
- /// Err(e) => println!("accept function failed: {:?}", e),
- /// }
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
- let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
- let mut len = mem::size_of_val(&storage) as libc::socklen_t;
- let sock = self.0.accept(&mut storage as *mut _ as *mut _, &mut len)?;
- let addr = SocketAddr::from_parts(storage, len)?;
- Ok((UnixStream(sock), addr))
- }
-
- /// Creates a new independently owned handle to the underlying socket.
- ///
- /// The returned `UnixListener` is a reference to the same socket that this
- /// object references. Both handles can be used to accept incoming
- /// connections and options set on one listener will affect the other.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixListener;
- ///
- /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
- ///
- /// let listener_copy = listener.try_clone().expect("try_clone failed");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn try_clone(&self) -> io::Result<UnixListener> {
- self.0.duplicate().map(UnixListener)
- }
-
- /// Returns the local socket address of this listener.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixListener;
- ///
- /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
- ///
- /// let addr = listener.local_addr().expect("Couldn't get local address");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn local_addr(&self) -> io::Result<SocketAddr> {
- SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
- }
-
- /// Moves the socket into or out of nonblocking mode.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixListener;
- ///
- /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
- ///
- /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- self.0.set_nonblocking(nonblocking)
- }
-
- /// Returns the value of the `SO_ERROR` option.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixListener;
- ///
- /// let listener = UnixListener::bind("/tmp/sock").unwrap();
- ///
- /// if let Ok(Some(err)) = listener.take_error() {
- /// println!("Got error: {:?}", err);
- /// }
- /// ```
- ///
- /// # Platform specific
- /// On Redox this always returns None.
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- self.0.take_error()
- }
-
- /// Returns an iterator over incoming connections.
- ///
- /// The iterator will never return [`None`] and will also not yield the
- /// peer's [`SocketAddr`] structure.
- ///
- /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
- /// [`SocketAddr`]: struct.SocketAddr.html
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::thread;
- /// use std::os::unix::net::{UnixStream, UnixListener};
- ///
- /// fn handle_client(stream: UnixStream) {
- /// // ...
- /// }
- ///
- /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
- ///
- /// for stream in listener.incoming() {
- /// match stream {
- /// Ok(stream) => {
- /// thread::spawn(|| handle_client(stream));
- /// }
- /// Err(err) => {
- /// break;
- /// }
- /// }
- /// }
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn incoming<'a>(&'a self) -> Incoming<'a> {
- Incoming { listener: self }
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl AsRawFd for UnixListener {
- fn as_raw_fd(&self) -> RawFd {
- *self.0.as_inner()
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl FromRawFd for UnixListener {
- unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
- UnixListener(Socket::from_inner(fd))
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl IntoRawFd for UnixListener {
- fn into_raw_fd(self) -> RawFd {
- self.0.into_inner()
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl<'a> IntoIterator for &'a UnixListener {
- type Item = io::Result<UnixStream>;
- type IntoIter = Incoming<'a>;
-
- fn into_iter(self) -> Incoming<'a> {
- self.incoming()
- }
-}
-
-/// An iterator over incoming connections to a [`UnixListener`].
-///
-/// It will never return [`None`].
-///
-/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-/// [`UnixListener`]: struct.UnixListener.html
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::thread;
-/// use std::os::unix::net::{UnixStream, UnixListener};
-///
-/// fn handle_client(stream: UnixStream) {
-/// // ...
-/// }
-///
-/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
-///
-/// for stream in listener.incoming() {
-/// match stream {
-/// Ok(stream) => {
-/// thread::spawn(|| handle_client(stream));
-/// }
-/// Err(err) => {
-/// break;
-/// }
-/// }
-/// }
-/// ```
-#[derive(Debug)]
-#[stable(feature = "unix_socket", since = "1.10.0")]
-pub struct Incoming<'a> {
- listener: &'a UnixListener,
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl<'a> Iterator for Incoming<'a> {
- type Item = io::Result<UnixStream>;
-
- fn next(&mut self) -> Option<io::Result<UnixStream>> {
- Some(self.listener.accept().map(|s| s.0))
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (usize::max_value(), None)
- }
-}
-
-/// A Unix datagram socket.
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::os::unix::net::UnixDatagram;
-///
-/// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
-/// socket.send_to(b"hello world", "/path/to/other/socket").unwrap();
-/// let mut buf = [0; 100];
-/// let (count, address) = socket.recv_from(&mut buf).unwrap();
-/// println!("socket {:?} sent {:?}", address, &buf[..count]);
-/// ```
-#[stable(feature = "unix_socket", since = "1.10.0")]
-pub struct UnixDatagram(Socket);
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl fmt::Debug for UnixDatagram {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- let mut builder = fmt.debug_struct("UnixDatagram");
- builder.field("fd", self.0.as_inner());
- if let Ok(addr) = self.local_addr() {
- builder.field("local", &addr);
- }
- if let Ok(addr) = self.peer_addr() {
- builder.field("peer", &addr);
- }
- builder.finish()
- }
-}
-
-impl UnixDatagram {
- /// Creates a Unix datagram socket bound to the given path.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
- /// Ok(sock) => sock,
- /// Err(e) => {
- /// println!("Couldn't bind: {:?}", e);
- /// return
- /// }
- /// };
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
- fn inner(path: &Path) -> io::Result<UnixDatagram> {
- unsafe {
- let socket = UnixDatagram::unbound()?;
- let (addr, len) = sockaddr_un(path)?;
-
- cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?;
-
- Ok(socket)
- }
- }
- inner(path.as_ref())
- }
-
- /// Creates a Unix Datagram socket which is not bound to any address.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = match UnixDatagram::unbound() {
- /// Ok(sock) => sock,
- /// Err(e) => {
- /// println!("Couldn't unbound: {:?}", e);
- /// return
- /// }
- /// };
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn unbound() -> io::Result<UnixDatagram> {
- let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
- Ok(UnixDatagram(inner))
- }
-
- /// Create an unnamed pair of connected sockets.
- ///
- /// Returns two `UnixDatagrams`s which are connected to each other.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let (sock1, sock2) = match UnixDatagram::pair() {
- /// Ok((sock1, sock2)) => (sock1, sock2),
- /// Err(e) => {
- /// println!("Couldn't unbound: {:?}", e);
- /// return
- /// }
- /// };
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
- let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
- Ok((UnixDatagram(i1), UnixDatagram(i2)))
- }
-
- /// Connects the socket to the specified address.
- ///
- /// The [`send`] method may be used to send data to the specified address.
- /// [`recv`] and [`recv_from`] will only receive data from that address.
- ///
- /// [`send`]: #method.send
- /// [`recv`]: #method.recv
- /// [`recv_from`]: #method.recv_from
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// match sock.connect("/path/to/the/socket") {
- /// Ok(sock) => sock,
- /// Err(e) => {
- /// println!("Couldn't connect: {:?}", e);
- /// return
- /// }
- /// };
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
- fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
- unsafe {
- let (addr, len) = sockaddr_un(path)?;
-
- cvt(libc::connect(*d.0.as_inner(), &addr as *const _ as *const _, len))?;
-
- Ok(())
- }
- }
- inner(self, path.as_ref())
- }
-
- /// Creates a new independently owned handle to the underlying socket.
- ///
- /// The returned `UnixDatagram` is a reference to the same socket that this
- /// object references. Both handles can be used to accept incoming
- /// connections and options set on one side will affect the other.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
- ///
- /// let sock_copy = sock.try_clone().expect("try_clone failed");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn try_clone(&self) -> io::Result<UnixDatagram> {
- self.0.duplicate().map(UnixDatagram)
- }
-
- /// Returns the address of this socket.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
- ///
- /// let addr = sock.local_addr().expect("Couldn't get local address");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn local_addr(&self) -> io::Result<SocketAddr> {
- SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
- }
-
- /// Returns the address of this socket's peer.
- ///
- /// The [`connect`] method will connect the socket to a peer.
- ///
- /// [`connect`]: #method.connect
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// sock.connect("/path/to/the/socket").unwrap();
- ///
- /// let addr = sock.peer_addr().expect("Couldn't get peer address");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn peer_addr(&self) -> io::Result<SocketAddr> {
- SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
- }
-
- /// Receives data from the socket.
- ///
- /// On success, returns the number of bytes read and the address from
- /// whence the data came.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// let mut buf = vec![0; 10];
- /// match sock.recv_from(buf.as_mut_slice()) {
- /// Ok((size, sender)) => println!("received {} bytes from {:?}", size, sender),
- /// Err(e) => println!("recv_from function failed: {:?}", e),
- /// }
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- let mut count = 0;
- let addr = SocketAddr::new(|addr, len| {
- unsafe {
- count = libc::recvfrom(*self.0.as_inner(),
- buf.as_mut_ptr() as *mut _,
- buf.len(),
- 0,
- addr,
- len);
- if count > 0 {
- 1
- } else if count == 0 {
- 0
- } else {
- -1
- }
- }
- })?;
-
- Ok((count as usize, addr))
- }
-
- /// Receives data from the socket.
- ///
- /// On success, returns the number of bytes read.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
- /// let mut buf = vec![0; 10];
- /// sock.recv(buf.as_mut_slice()).expect("recv function failed");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.0.read(buf)
- }
-
- /// Sends data on the socket to the specified address.
- ///
- /// On success, returns the number of bytes written.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
- fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
- unsafe {
- let (addr, len) = sockaddr_un(path)?;
-
- let count = cvt(libc::sendto(*d.0.as_inner(),
- buf.as_ptr() as *const _,
- buf.len(),
- MSG_NOSIGNAL,
- &addr as *const _ as *const _,
- len))?;
- Ok(count as usize)
- }
- }
- inner(self, buf, path.as_ref())
- }
-
- /// Sends data on the socket to the socket's peer.
- ///
- /// The peer address may be set by the `connect` method, and this method
- /// will return an error if the socket has not already been connected.
- ///
- /// On success, returns the number of bytes written.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// sock.connect("/some/sock").expect("Couldn't connect");
- /// sock.send(b"omelette au fromage").expect("send_to function failed");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
- self.0.write(buf)
- }
-
- /// Sets the read timeout for the socket.
- ///
- /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
- /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
- /// is passed to this method.
- ///
- /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
- /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
- /// [`recv`]: #method.recv
- /// [`recv_from`]: #method.recv_from
- /// [`Duration`]: ../../../../std/time/struct.Duration.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::os::unix::net::UnixDatagram;
- /// use std::time::Duration;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
- /// ```
- ///
- /// An [`Err`] is returned if the zero [`Duration`] is passed to this
- /// method:
- ///
- /// ```no_run
- /// use std::io;
- /// use std::os::unix::net::UnixDatagram;
- /// use std::time::Duration;
- ///
- /// let socket = UnixDatagram::unbound().unwrap();
- /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
- /// let err = result.unwrap_err();
- /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
- self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
- }
-
- /// Sets the write timeout for the socket.
- ///
- /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
- /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
- /// method.
- ///
- /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
- /// [`send`]: #method.send
- /// [`send_to`]: #method.send_to
- /// [`Duration`]: ../../../../std/time/struct.Duration.html
- ///
- /// # Examples
- ///
- /// ```
- /// use std::os::unix::net::UnixDatagram;
- /// use std::time::Duration;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// sock.set_write_timeout(Some(Duration::new(1, 0)))
- /// .expect("set_write_timeout function failed");
- /// ```
- ///
- /// An [`Err`] is returned if the zero [`Duration`] is passed to this
- /// method:
- ///
- /// ```no_run
- /// use std::io;
- /// use std::os::unix::net::UnixDatagram;
- /// use std::time::Duration;
- ///
- /// let socket = UnixDatagram::unbound().unwrap();
- /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
- /// let err = result.unwrap_err();
- /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
- self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
- }
-
- /// Returns the read timeout of this socket.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::os::unix::net::UnixDatagram;
- /// use std::time::Duration;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
- /// assert_eq!(sock.read_timeout().unwrap(), Some(Duration::new(1, 0)));
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
- self.0.timeout(libc::SO_RCVTIMEO)
- }
-
- /// Returns the write timeout of this socket.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::os::unix::net::UnixDatagram;
- /// use std::time::Duration;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// sock.set_write_timeout(Some(Duration::new(1, 0)))
- /// .expect("set_write_timeout function failed");
- /// assert_eq!(sock.write_timeout().unwrap(), Some(Duration::new(1, 0)));
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
- self.0.timeout(libc::SO_SNDTIMEO)
- }
-
- /// Moves the socket into or out of nonblocking mode.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- self.0.set_nonblocking(nonblocking)
- }
-
- /// Returns the value of the `SO_ERROR` option.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// if let Ok(Some(err)) = sock.take_error() {
- /// println!("Got error: {:?}", err);
- /// }
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- self.0.take_error()
- }
-
- /// Shut down the read, write, or both halves of this connection.
- ///
- /// This function will cause all pending and future I/O calls on the
- /// specified portions to immediately return with an appropriate value
- /// (see the documentation of [`Shutdown`]).
- ///
- /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
- ///
- /// ```no_run
- /// use std::os::unix::net::UnixDatagram;
- /// use std::net::Shutdown;
- ///
- /// let sock = UnixDatagram::unbound().unwrap();
- /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
- /// ```
- #[stable(feature = "unix_socket", since = "1.10.0")]
- pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
- self.0.shutdown(how)
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl AsRawFd for UnixDatagram {
- fn as_raw_fd(&self) -> RawFd {
- *self.0.as_inner()
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl FromRawFd for UnixDatagram {
- unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
- UnixDatagram(Socket::from_inner(fd))
- }
-}
-
-#[stable(feature = "unix_socket", since = "1.10.0")]
-impl IntoRawFd for UnixDatagram {
- fn into_raw_fd(self) -> RawFd {
- self.0.into_inner()
- }
-}
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod test {
- use thread;
- use io::{self, ErrorKind};
- use io::prelude::*;
- use time::Duration;
- use sys_common::io::test::tmpdir;
-
- use super::*;
-
- macro_rules! or_panic {
- ($e:expr) => {
- match $e {
- Ok(e) => e,
- Err(e) => panic!("{}", e),
- }
- }
- }
-
- #[test]
- fn basic() {
- let dir = tmpdir();
- let socket_path = dir.path().join("sock");
- let msg1 = b"hello";
- let msg2 = b"world!";
-
- let listener = or_panic!(UnixListener::bind(&socket_path));
- let thread = thread::spawn(move || {
- let mut stream = or_panic!(listener.accept()).0;
- let mut buf = [0; 5];
- or_panic!(stream.read(&mut buf));
- assert_eq!(&msg1[..], &buf[..]);
- or_panic!(stream.write_all(msg2));
- });
-
- let mut stream = or_panic!(UnixStream::connect(&socket_path));
- assert_eq!(Some(&*socket_path),
- stream.peer_addr().unwrap().as_pathname());
- or_panic!(stream.write_all(msg1));
- let mut buf = vec![];
- or_panic!(stream.read_to_end(&mut buf));
- assert_eq!(&msg2[..], &buf[..]);
- drop(stream);
-
- thread.join().unwrap();
- }
-
- #[test]
- fn pair() {
- let msg1 = b"hello";
- let msg2 = b"world!";
-
- let (mut s1, mut s2) = or_panic!(UnixStream::pair());
- let thread = thread::spawn(move || {
- // s1 must be moved in or the test will hang!
- let mut buf = [0; 5];
- or_panic!(s1.read(&mut buf));
- assert_eq!(&msg1[..], &buf[..]);
- or_panic!(s1.write_all(msg2));
- });
-
- or_panic!(s2.write_all(msg1));
- let mut buf = vec![];
- or_panic!(s2.read_to_end(&mut buf));
- assert_eq!(&msg2[..], &buf[..]);
- drop(s2);
-
- thread.join().unwrap();
- }
-
- #[test]
- fn try_clone() {
- let dir = tmpdir();
- let socket_path = dir.path().join("sock");
- let msg1 = b"hello";
- let msg2 = b"world";
-
- let listener = or_panic!(UnixListener::bind(&socket_path));
- let thread = thread::spawn(move || {
- let mut stream = or_panic!(listener.accept()).0;
- or_panic!(stream.write_all(msg1));
- or_panic!(stream.write_all(msg2));
- });
-
- let mut stream = or_panic!(UnixStream::connect(&socket_path));
- let mut stream2 = or_panic!(stream.try_clone());
-
- let mut buf = [0; 5];
- or_panic!(stream.read(&mut buf));
- assert_eq!(&msg1[..], &buf[..]);
- or_panic!(stream2.read(&mut buf));
- assert_eq!(&msg2[..], &buf[..]);
-
- thread.join().unwrap();
- }
-
- #[test]
- fn iter() {
- let dir = tmpdir();
- let socket_path = dir.path().join("sock");
-
- let listener = or_panic!(UnixListener::bind(&socket_path));
- let thread = thread::spawn(move || {
- for stream in listener.incoming().take(2) {
- let mut stream = or_panic!(stream);
- let mut buf = [0];
- or_panic!(stream.read(&mut buf));
- }
- });
-
- for _ in 0..2 {
- let mut stream = or_panic!(UnixStream::connect(&socket_path));
- or_panic!(stream.write_all(&[0]));
- }
-
- thread.join().unwrap();
- }
-
- #[test]
- fn long_path() {
- let dir = tmpdir();
- let socket_path = dir.path()
- .join("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
- sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf");
- match UnixStream::connect(&socket_path) {
- Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
- Err(e) => panic!("unexpected error {}", e),
- Ok(_) => panic!("unexpected success"),
- }
-
- match UnixListener::bind(&socket_path) {
- Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
- Err(e) => panic!("unexpected error {}", e),
- Ok(_) => panic!("unexpected success"),
- }
-
- match UnixDatagram::bind(&socket_path) {
- Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
- Err(e) => panic!("unexpected error {}", e),
- Ok(_) => panic!("unexpected success"),
- }
- }
-
- #[test]
- fn timeouts() {
- let dir = tmpdir();
- let socket_path = dir.path().join("sock");
-
- let _listener = or_panic!(UnixListener::bind(&socket_path));
-
- let stream = or_panic!(UnixStream::connect(&socket_path));
- let dur = Duration::new(15410, 0);
-
- assert_eq!(None, or_panic!(stream.read_timeout()));
-
- or_panic!(stream.set_read_timeout(Some(dur)));
- assert_eq!(Some(dur), or_panic!(stream.read_timeout()));
-
- assert_eq!(None, or_panic!(stream.write_timeout()));
-
- or_panic!(stream.set_write_timeout(Some(dur)));
- assert_eq!(Some(dur), or_panic!(stream.write_timeout()));
-
- or_panic!(stream.set_read_timeout(None));
- assert_eq!(None, or_panic!(stream.read_timeout()));
-
- or_panic!(stream.set_write_timeout(None));
- assert_eq!(None, or_panic!(stream.write_timeout()));
- }
-
- #[test]
- fn test_read_timeout() {
- let dir = tmpdir();
- let socket_path = dir.path().join("sock");
-
- let _listener = or_panic!(UnixListener::bind(&socket_path));
-
- let mut stream = or_panic!(UnixStream::connect(&socket_path));
- or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
- let mut buf = [0; 10];
- let kind = stream.read(&mut buf).err().expect("expected error").kind();
- assert!(kind == io::ErrorKind::WouldBlock || kind == io::ErrorKind::TimedOut);
- }
-
- #[test]
- fn test_read_with_timeout() {
- let dir = tmpdir();
- let socket_path = dir.path().join("sock");
-
- let listener = or_panic!(UnixListener::bind(&socket_path));
-
- let mut stream = or_panic!(UnixStream::connect(&socket_path));
- or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
-
- let mut other_end = or_panic!(listener.accept()).0;
- or_panic!(other_end.write_all(b"hello world"));
-
- let mut buf = [0; 11];
- or_panic!(stream.read(&mut buf));
- assert_eq!(b"hello world", &buf[..]);
-
- let kind = stream.read(&mut buf).err().expect("expected error").kind();
- assert!(kind == io::ErrorKind::WouldBlock || kind == io::ErrorKind::TimedOut);
- }
-
- // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
- // when passed zero Durations
- #[test]
- fn test_unix_stream_timeout_zero_duration() {
- let dir = tmpdir();
- let socket_path = dir.path().join("sock");
-
- let listener = or_panic!(UnixListener::bind(&socket_path));
- let stream = or_panic!(UnixStream::connect(&socket_path));
-
- let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
- let err = result.unwrap_err();
- assert_eq!(err.kind(), ErrorKind::InvalidInput);
-
- let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
- let err = result.unwrap_err();
- assert_eq!(err.kind(), ErrorKind::InvalidInput);
-
- drop(listener);
- }
-
- #[test]
- fn test_unix_datagram() {
- let dir = tmpdir();
- let path1 = dir.path().join("sock1");
- let path2 = dir.path().join("sock2");
-
- let sock1 = or_panic!(UnixDatagram::bind(&path1));
- let sock2 = or_panic!(UnixDatagram::bind(&path2));
-
- let msg = b"hello world";
- or_panic!(sock1.send_to(msg, &path2));
- let mut buf = [0; 11];
- or_panic!(sock2.recv_from(&mut buf));
- assert_eq!(msg, &buf[..]);
- }
-
- #[test]
- fn test_unnamed_unix_datagram() {
- let dir = tmpdir();
- let path1 = dir.path().join("sock1");
-
- let sock1 = or_panic!(UnixDatagram::bind(&path1));
- let sock2 = or_panic!(UnixDatagram::unbound());
-
- let msg = b"hello world";
- or_panic!(sock2.send_to(msg, &path1));
- let mut buf = [0; 11];
- let (usize, addr) = or_panic!(sock1.recv_from(&mut buf));
- assert_eq!(usize, 11);
- assert!(addr.is_unnamed());
- assert_eq!(msg, &buf[..]);
- }
-
- #[test]
- fn test_connect_unix_datagram() {
- let dir = tmpdir();
- let path1 = dir.path().join("sock1");
- let path2 = dir.path().join("sock2");
-
- let bsock1 = or_panic!(UnixDatagram::bind(&path1));
- let bsock2 = or_panic!(UnixDatagram::bind(&path2));
- let sock = or_panic!(UnixDatagram::unbound());
- or_panic!(sock.connect(&path1));
-
- // Check send()
- let msg = b"hello there";
- or_panic!(sock.send(msg));
- let mut buf = [0; 11];
- let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf));
- assert_eq!(usize, 11);
- assert!(addr.is_unnamed());
- assert_eq!(msg, &buf[..]);
-
- // Changing default socket works too
- or_panic!(sock.connect(&path2));
- or_panic!(sock.send(msg));
- or_panic!(bsock2.recv_from(&mut buf));
- }
-
- #[test]
- fn test_unix_datagram_recv() {
- let dir = tmpdir();
- let path1 = dir.path().join("sock1");
-
- let sock1 = or_panic!(UnixDatagram::bind(&path1));
- let sock2 = or_panic!(UnixDatagram::unbound());
- or_panic!(sock2.connect(&path1));
-
- let msg = b"hello world";
- or_panic!(sock2.send(msg));
- let mut buf = [0; 11];
- let size = or_panic!(sock1.recv(&mut buf));
- assert_eq!(size, 11);
- assert_eq!(msg, &buf[..]);
- }
-
- #[test]
- fn datagram_pair() {
- let msg1 = b"hello";
- let msg2 = b"world!";
-
- let (s1, s2) = or_panic!(UnixDatagram::pair());
- let thread = thread::spawn(move || {
- // s1 must be moved in or the test will hang!
- let mut buf = [0; 5];
- or_panic!(s1.recv(&mut buf));
- assert_eq!(&msg1[..], &buf[..]);
- or_panic!(s1.send(msg2));
- });
-
- or_panic!(s2.send(msg1));
- let mut buf = [0; 6];
- or_panic!(s2.recv(&mut buf));
- assert_eq!(&msg2[..], &buf[..]);
- drop(s2);
-
- thread.join().unwrap();
- }
-
- // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
- // when passed zero Durations
- #[test]
- fn test_unix_datagram_timeout_zero_duration() {
- let dir = tmpdir();
- let path = dir.path().join("sock");
-
- let datagram = or_panic!(UnixDatagram::bind(&path));
-
- let result = datagram.set_write_timeout(Some(Duration::new(0, 0)));
- let err = result.unwrap_err();
- assert_eq!(err.kind(), ErrorKind::InvalidInput);
-
- let result = datagram.set_read_timeout(Some(Duration::new(0, 0)));
- let err = result.unwrap_err();
- assert_eq!(err.kind(), ErrorKind::InvalidInput);
- }
-
- #[test]
- fn abstract_namespace_not_allowed() {
- assert!(UnixStream::connect("\0asdf").is_err());
- }
-}
diff --git a/ctr-std/src/sys/unix/ext/process.rs b/ctr-std/src/sys/unix/ext/process.rs
deleted file mode 100644
index 21630ae..0000000
--- a/ctr-std/src/sys/unix/ext/process.rs
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Unix-specific extensions to primitives in the `std::process` module.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use io;
-use os::unix::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd};
-use process;
-use sys;
-use sys_common::{AsInnerMut, AsInner, FromInner, IntoInner};
-
-/// Unix-specific extensions to the [`process::Command`] builder.
-///
-/// [`process::Command`]: ../../../../std/process/struct.Command.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait CommandExt {
- /// Sets the child process's user id. This translates to a
- /// `setuid` call in the child process. Failure in the `setuid`
- /// call will cause the spawn to fail.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn uid(&mut self, id: u32) -> &mut process::Command;
-
- /// Similar to `uid`, but sets the group id of the child process. This has
- /// the same semantics as the `uid` field.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn gid(&mut self, id: u32) -> &mut process::Command;
-
- /// Schedules a closure to be run just before the `exec` function is
- /// invoked.
- ///
- /// The closure is allowed to return an I/O error whose OS error code will
- /// be communicated back to the parent and returned as an error from when
- /// the spawn was requested.
- ///
- /// Multiple closures can be registered and they will be called in order of
- /// their registration. If a closure returns `Err` then no further closures
- /// will be called and the spawn operation will immediately return with a
- /// failure.
- ///
- /// # Notes
- ///
- /// This closure will be run in the context of the child process after a
- /// `fork`. This primarily means that any modifications made to memory on
- /// behalf of this closure will **not** be visible to the parent process.
- /// This is often a very constrained environment where normal operations
- /// like `malloc` or acquiring a mutex are not guaranteed to work (due to
- /// other threads perhaps still running when the `fork` was run).
- ///
- /// When this closure is run, aspects such as the stdio file descriptors and
- /// working directory have successfully been changed, so output to these
- /// locations may not appear where intended.
- #[stable(feature = "process_exec", since = "1.15.0")]
- fn before_exec<F>(&mut self, f: F) -> &mut process::Command
- where F: FnMut() -> io::Result<()> + Send + Sync + 'static;
-
- /// Performs all the required setup by this `Command`, followed by calling
- /// the `execvp` syscall.
- ///
- /// On success this function will not return, and otherwise it will return
- /// an error indicating why the exec (or another part of the setup of the
- /// `Command`) failed.
- ///
- /// `exec` not returning has the same implications as calling
- /// [`process::exit`] – no destructors on the current stack or any other
- /// thread’s stack will be run. Therefore, it is recommended to only call
- /// `exec` at a point where it is fine to not run any destructors. Note,
- /// that the `execvp` syscall independently guarantees that all memory is
- /// freed and all file descriptors with the `CLOEXEC` option (set by default
- /// on all file descriptors opened by the standard library) are closed.
- ///
- /// This function, unlike `spawn`, will **not** `fork` the process to create
- /// a new child. Like spawn, however, the default behavior for the stdio
- /// descriptors will be to inherited from the current process.
- ///
- /// [`process::exit`]: ../../../process/fn.exit.html
- ///
- /// # Notes
- ///
- /// The process may be in a "broken state" if this function returns in
- /// error. For example the working directory, environment variables, signal
- /// handling settings, various user/group information, or aspects of stdio
- /// file descriptors may have changed. If a "transactional spawn" is
- /// required to gracefully handle errors it is recommended to use the
- /// cross-platform `spawn` instead.
- #[stable(feature = "process_exec2", since = "1.9.0")]
- fn exec(&mut self) -> io::Error;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl CommandExt for process::Command {
- fn uid(&mut self, id: u32) -> &mut process::Command {
- self.as_inner_mut().uid(id);
- self
- }
-
- fn gid(&mut self, id: u32) -> &mut process::Command {
- self.as_inner_mut().gid(id);
- self
- }
-
- fn before_exec<F>(&mut self, f: F) -> &mut process::Command
- where F: FnMut() -> io::Result<()> + Send + Sync + 'static
- {
- self.as_inner_mut().before_exec(Box::new(f));
- self
- }
-
- fn exec(&mut self) -> io::Error {
- self.as_inner_mut().exec(sys::process::Stdio::Inherit)
- }
-}
-
-/// Unix-specific extensions to [`process::ExitStatus`].
-///
-/// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait ExitStatusExt {
- /// Creates a new `ExitStatus` from the raw underlying `i32` return value of
- /// a process.
- #[stable(feature = "exit_status_from", since = "1.12.0")]
- fn from_raw(raw: i32) -> Self;
-
- /// If the process was terminated by a signal, returns that signal.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn signal(&self) -> Option<i32>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl ExitStatusExt for process::ExitStatus {
- fn from_raw(raw: i32) -> Self {
- process::ExitStatus::from_inner(From::from(raw))
- }
-
- fn signal(&self) -> Option<i32> {
- self.as_inner().signal()
- }
-}
-
-#[stable(feature = "process_extensions", since = "1.2.0")]
-impl FromRawFd for process::Stdio {
- unsafe fn from_raw_fd(fd: RawFd) -> process::Stdio {
- let fd = sys::fd::FileDesc::new(fd);
- let io = sys::process::Stdio::Fd(fd);
- process::Stdio::from_inner(io)
- }
-}
-
-#[stable(feature = "process_extensions", since = "1.2.0")]
-impl AsRawFd for process::ChildStdin {
- fn as_raw_fd(&self) -> RawFd {
- self.as_inner().fd().raw()
- }
-}
-
-#[stable(feature = "process_extensions", since = "1.2.0")]
-impl AsRawFd for process::ChildStdout {
- fn as_raw_fd(&self) -> RawFd {
- self.as_inner().fd().raw()
- }
-}
-
-#[stable(feature = "process_extensions", since = "1.2.0")]
-impl AsRawFd for process::ChildStderr {
- fn as_raw_fd(&self) -> RawFd {
- self.as_inner().fd().raw()
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for process::ChildStdin {
- fn into_raw_fd(self) -> RawFd {
- self.into_inner().into_fd().into_raw()
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for process::ChildStdout {
- fn into_raw_fd(self) -> RawFd {
- self.into_inner().into_fd().into_raw()
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for process::ChildStderr {
- fn into_raw_fd(self) -> RawFd {
- self.into_inner().into_fd().into_raw()
- }
-}
-
-/// Returns the OS-assigned process identifier associated with this process's parent.
-#[stable(feature = "unix_ppid", since = "1.27.0")]
-pub fn parent_id() -> u32 {
- ::sys::os::getppid()
-}
diff --git a/ctr-std/src/sys/unix/ext/raw.rs b/ctr-std/src/sys/unix/ext/raw.rs
deleted file mode 100644
index 7972990..0000000
--- a/ctr-std/src/sys/unix/ext/raw.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Unix-specific primitives available on all unix platforms
-
-#![stable(feature = "raw_ext", since = "1.1.0")]
-#![rustc_deprecated(since = "1.8.0",
- reason = "these type aliases are no longer supported by \
- the standard library, the `libc` crate on \
- crates.io should be used instead for the correct \
- definitions")]
-#![allow(deprecated)]
-
-#[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 pid_t = i32;
-
-#[doc(inline)]
-#[stable(feature = "pthread_t", since = "1.8.0")]
-pub use sys::platform::raw::pthread_t;
-#[doc(inline)]
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub use sys::platform::raw::{dev_t, ino_t, mode_t, nlink_t, off_t, blksize_t};
-#[doc(inline)]
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub use sys::platform::raw::{blkcnt_t, time_t};
diff --git a/ctr-std/src/sys/unix/ext/thread.rs b/ctr-std/src/sys/unix/ext/thread.rs
deleted file mode 100644
index 8dadf29..0000000
--- a/ctr-std/src/sys/unix/ext/thread.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Unix-specific extensions to primitives in the `std::thread` module.
-
-#![stable(feature = "thread_extensions", since = "1.9.0")]
-
-#[allow(deprecated)]
-use os::unix::raw::pthread_t;
-use sys_common::{AsInner, IntoInner};
-use thread::JoinHandle;
-
-#[stable(feature = "thread_extensions", since = "1.9.0")]
-#[allow(deprecated)]
-pub type RawPthread = pthread_t;
-
-/// Unix-specific extensions to [`thread::JoinHandle`].
-///
-/// [`thread::JoinHandle`]: ../../../../std/thread/struct.JoinHandle.html
-#[stable(feature = "thread_extensions", since = "1.9.0")]
-pub trait JoinHandleExt {
- /// Extracts the raw pthread_t without taking ownership
- #[stable(feature = "thread_extensions", since = "1.9.0")]
- fn as_pthread_t(&self) -> RawPthread;
-
- /// Consumes the thread, returning the raw pthread_t
- ///
- /// This function **transfers ownership** of the underlying pthread_t to
- /// the caller. Callers are then the unique owners of the pthread_t and
- /// must either detach or join the pthread_t once it's no longer needed.
- #[stable(feature = "thread_extensions", since = "1.9.0")]
- fn into_pthread_t(self) -> RawPthread;
-}
-
-#[stable(feature = "thread_extensions", since = "1.9.0")]
-impl<T> JoinHandleExt for JoinHandle<T> {
- fn as_pthread_t(&self) -> RawPthread {
- self.as_inner().id() as RawPthread
- }
-
- fn into_pthread_t(self) -> RawPthread {
- self.into_inner().into_id() as RawPthread
- }
-}
diff --git a/ctr-std/src/sys/unix/fast_thread_local.rs b/ctr-std/src/sys/unix/fast_thread_local.rs
deleted file mode 100644
index c13a0fe..0000000
--- a/ctr-std/src/sys/unix/fast_thread_local.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![cfg(target_thread_local)]
-#![unstable(feature = "thread_local_internals", issue = "0")]
-
-// Since what appears to be glibc 2.18 this symbol has been shipped which
-// GCC and clang both use to invoke destructors in thread_local globals, so
-// let's do the same!
-//
-// Note, however, that we run on lots older linuxes, as well as cross
-// compiling from a newer linux to an older linux, so we also have a
-// fallback implementation to use as well.
-//
-// Due to rust-lang/rust#18804, make sure this is not generic!
-#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit"))]
-pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
- use libc;
- use mem;
- use sys_common::thread_local::register_dtor_fallback;
-
- extern {
- #[linkage = "extern_weak"]
- static __dso_handle: *mut u8;
- #[linkage = "extern_weak"]
- static __cxa_thread_atexit_impl: *const libc::c_void;
- }
- if !__cxa_thread_atexit_impl.is_null() {
- type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
- arg: *mut u8,
- dso_handle: *mut u8) -> libc::c_int;
- mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)
- (dtor, t, &__dso_handle as *const _ as *mut _);
- return
- }
- register_dtor_fallback(t, dtor);
-}
-
-// macOS's analog of the above linux function is this _tlv_atexit function.
-// The disassembly of thread_local globals in C++ (at least produced by
-// clang) will have this show up in the output.
-#[cfg(target_os = "macos")]
-pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
- extern {
- fn _tlv_atexit(dtor: unsafe extern fn(*mut u8),
- arg: *mut u8);
- }
- _tlv_atexit(dtor, t);
-}
-
-pub fn requires_move_before_drop() -> bool {
- // The macOS implementation of TLS apparently had an odd aspect to it
- // where the pointer we have may be overwritten while this destructor
- // is running. Specifically if a TLS destructor re-accesses TLS it may
- // trigger a re-initialization of all TLS variables, paving over at
- // least some destroyed ones with initial values.
- //
- // This means that if we drop a TLS value in place on macOS that we could
- // revert the value to its original state halfway through the
- // destructor, which would be bad!
- //
- // Hence, we use `ptr::read` on macOS (to move to a "safe" location)
- // instead of drop_in_place.
- cfg!(target_os = "macos")
-}
diff --git a/ctr-std/src/sys/unix/fd.rs b/ctr-std/src/sys/unix/fd.rs
deleted file mode 100644
index 4830e38..0000000
--- a/ctr-std/src/sys/unix/fd.rs
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(reason = "not public", issue = "0", feature = "fd")]
-
-use cmp;
-use io::{self, Read};
-use libc::{self, c_int, c_void, ssize_t};
-use mem;
-use sync::atomic::{AtomicBool, Ordering};
-use sys::cvt;
-use sys_common::AsInner;
-
-#[derive(Debug)]
-pub struct FileDesc {
- fd: c_int,
-}
-
-fn max_len() -> usize {
- // The maximum read limit on most posix-like systems is `SSIZE_MAX`,
- // with the man page quoting that if the count of bytes to read is
- // greater than `SSIZE_MAX` the result is "unspecified".
- //
- // On macOS, however, apparently the 64-bit libc is either buggy or
- // intentionally showing odd behavior by rejecting any read with a size
- // larger than or equal to INT_MAX. To handle both of these the read
- // size is capped on both platforms.
- if cfg!(target_os = "macos") {
- <c_int>::max_value() as usize - 1
- } else {
- <ssize_t>::max_value() as usize
- }
-}
-
-impl FileDesc {
- pub fn new(fd: c_int) -> FileDesc {
- FileDesc { fd: fd }
- }
-
- pub fn raw(&self) -> c_int { self.fd }
-
- /// Extracts the actual filedescriptor without closing it.
- pub fn into_raw(self) -> c_int {
- let fd = self.fd;
- mem::forget(self);
- fd
- }
-
- pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- let ret = cvt(unsafe {
- libc::read(self.fd,
- buf.as_mut_ptr() as *mut c_void,
- cmp::min(buf.len(), max_len()))
- })?;
- Ok(ret as usize)
- }
-
- pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
- let mut me = self;
- (&mut me).read_to_end(buf)
- }
-
- pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
- #[cfg(target_os = "android")]
- use super::android::cvt_pread64;
-
- #[cfg(target_os = "emscripten")]
- unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: usize, offset: i64)
- -> io::Result<isize>
- {
- use convert::TryInto;
- use libc::pread64;
- // pread64 on emscripten actually takes a 32 bit offset
- if let Ok(o) = offset.try_into() {
- cvt(pread64(fd, buf, count, o))
- } else {
- Err(io::Error::new(io::ErrorKind::InvalidInput,
- "cannot pread >2GB"))
- }
- }
-
- #[cfg(not(any(target_os = "android", target_os = "emscripten")))]
- unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: usize, offset: i64)
- -> io::Result<isize>
- {
- #[cfg(target_os = "linux")]
- use libc::pread64;
- #[cfg(not(target_os = "linux"))]
- use libc::pread as pread64;
- cvt(pread64(fd, buf, count, offset))
- }
-
- unsafe {
- cvt_pread64(self.fd,
- buf.as_mut_ptr() as *mut c_void,
- cmp::min(buf.len(), max_len()),
- offset as i64)
- .map(|n| n as usize)
- }
- }
-
- pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
- let ret = cvt(unsafe {
- libc::write(self.fd,
- buf.as_ptr() as *const c_void,
- cmp::min(buf.len(), max_len()))
- })?;
- Ok(ret as usize)
- }
-
- pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
- #[cfg(target_os = "android")]
- use super::android::cvt_pwrite64;
-
- #[cfg(target_os = "emscripten")]
- unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: usize, offset: i64)
- -> io::Result<isize>
- {
- use convert::TryInto;
- use libc::pwrite64;
- // pwrite64 on emscripten actually takes a 32 bit offset
- if let Ok(o) = offset.try_into() {
- cvt(pwrite64(fd, buf, count, o))
- } else {
- Err(io::Error::new(io::ErrorKind::InvalidInput,
- "cannot pwrite >2GB"))
- }
- }
-
- #[cfg(not(any(target_os = "android", target_os = "emscripten")))]
- unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: usize, offset: i64)
- -> io::Result<isize>
- {
- #[cfg(target_os = "linux")]
- use libc::pwrite64;
- #[cfg(not(target_os = "linux"))]
- use libc::pwrite as pwrite64;
- cvt(pwrite64(fd, buf, count, offset))
- }
-
- unsafe {
- cvt_pwrite64(self.fd,
- buf.as_ptr() as *const c_void,
- cmp::min(buf.len(), max_len()),
- offset as i64)
- .map(|n| n as usize)
- }
- }
-
- #[cfg(target_os = "linux")]
- pub fn get_cloexec(&self) -> io::Result<bool> {
- unsafe {
- Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0)
- }
- }
-
- #[cfg(not(any(target_env = "newlib",
- target_os = "solaris",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "l4re",
- target_os = "haiku")))]
- pub fn set_cloexec(&self) -> io::Result<()> {
- unsafe {
- cvt(libc::ioctl(self.fd, libc::FIOCLEX))?;
- Ok(())
- }
- }
- #[cfg(any(target_env = "newlib",
- target_os = "solaris",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "l4re",
- target_os = "haiku"))]
- pub fn set_cloexec(&self) -> io::Result<()> {
- unsafe {
- let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?;
- let new = previous | libc::FD_CLOEXEC;
- if new != previous {
- cvt(libc::fcntl(self.fd, libc::F_SETFD, new))?;
- }
- Ok(())
- }
- }
-
- #[cfg(target_os = "linux")]
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- unsafe {
- let v = nonblocking as c_int;
- cvt(libc::ioctl(self.fd, libc::FIONBIO, &v))?;
- Ok(())
- }
- }
-
- #[cfg(not(target_os = "linux"))]
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- unsafe {
- let previous = cvt(libc::fcntl(self.fd, libc::F_GETFL))?;
- let new = if nonblocking {
- previous | libc::O_NONBLOCK
- } else {
- previous & !libc::O_NONBLOCK
- };
- if new != previous {
- cvt(libc::fcntl(self.fd, libc::F_SETFL, new))?;
- }
- Ok(())
- }
- }
-
- pub fn duplicate(&self) -> io::Result<FileDesc> {
- // We want to atomically duplicate this file descriptor and set the
- // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
- // flag, however, isn't supported on older Linux kernels (earlier than
- // 2.6.24).
- //
- // To detect this and ensure that CLOEXEC is still set, we
- // follow a strategy similar to musl [1] where if passing
- // F_DUPFD_CLOEXEC causes `fcntl` to return EINVAL it means it's not
- // supported (the third parameter, 0, is always valid), so we stop
- // trying that.
- //
- // Also note that Android doesn't have F_DUPFD_CLOEXEC, but get it to
- // resolve so we at least compile this.
- //
- // [1]: http://comments.gmane.org/gmane.linux.lib.musl.general/2963
- #[cfg(any(target_os = "android", target_os = "haiku"))]
- use libc::F_DUPFD as F_DUPFD_CLOEXEC;
- #[cfg(not(any(target_os = "android", target_os="haiku")))]
- use libc::F_DUPFD_CLOEXEC;
-
- let make_filedesc = |fd| {
- let fd = FileDesc::new(fd);
- fd.set_cloexec()?;
- Ok(fd)
- };
- static TRY_CLOEXEC: AtomicBool =
- AtomicBool::new(!cfg!(target_os = "android"));
- let fd = self.raw();
- if TRY_CLOEXEC.load(Ordering::Relaxed) {
- match cvt(unsafe { libc::fcntl(fd, F_DUPFD_CLOEXEC, 0) }) {
- // We *still* call the `set_cloexec` method as apparently some
- // linux kernel at some point stopped setting CLOEXEC even
- // though it reported doing so on F_DUPFD_CLOEXEC.
- Ok(fd) => {
- return Ok(if cfg!(target_os = "linux") {
- make_filedesc(fd)?
- } else {
- FileDesc::new(fd)
- })
- }
- Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {
- TRY_CLOEXEC.store(false, Ordering::Relaxed);
- }
- Err(e) => return Err(e),
- }
- }
- cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD, 0) }).and_then(make_filedesc)
- }
-}
-
-impl<'a> Read for &'a FileDesc {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- (**self).read(buf)
- }
-}
-
-impl AsInner<c_int> for FileDesc {
- fn as_inner(&self) -> &c_int { &self.fd }
-}
-
-impl Drop for FileDesc {
- fn drop(&mut self) {
- // Note that errors are ignored when closing a file descriptor. The
- // reason for this is that if an error occurs we don't actually know if
- // the file descriptor was closed or not, and if we retried (for
- // something like EINTR), we might close another valid file descriptor
- // (opened after we closed ours.
- let _ = unsafe { libc::close(self.fd) };
- }
-}
diff --git a/ctr-std/src/sys/unix/fs.rs b/ctr-std/src/sys/unix/fs.rs
deleted file mode 100644
index 7a89d98..0000000
--- a/ctr-std/src/sys/unix/fs.rs
+++ /dev/null
@@ -1,945 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use os::unix::prelude::*;
-
-use ffi::{CString, CStr, OsString, OsStr};
-use fmt;
-use io::{self, Error, ErrorKind, SeekFrom};
-use libc::{self, c_int, mode_t};
-use mem;
-use path::{Path, PathBuf};
-use ptr;
-use sync::Arc;
-use sys::fd::FileDesc;
-use sys::time::SystemTime;
-use sys::{cvt, cvt_r};
-use sys_common::{AsInner, FromInner};
-
-#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "l4re"))]
-use libc::{stat64, fstat64, lstat64, off64_t, ftruncate64, lseek64, dirent64, readdir64_r, open64};
-#[cfg(any(target_os = "linux", target_os = "emscripten"))]
-use libc::fstatat64;
-#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
-use libc::dirfd;
-#[cfg(target_os = "android")]
-use libc::{stat as stat64, fstat as fstat64, fstatat as fstatat64, lstat as lstat64, lseek64,
- dirent as dirent64, open as open64};
-#[cfg(not(any(target_os = "linux",
- target_os = "emscripten",
- target_os = "l4re",
- target_os = "android")))]
-use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, off_t as off64_t,
- ftruncate as ftruncate64, lseek as lseek64, dirent as dirent64, open as open64};
-#[cfg(not(any(target_os = "linux",
- target_os = "emscripten",
- target_os = "solaris",
- target_os = "l4re",
- target_os = "fuchsia")))]
-use libc::{readdir_r as readdir64_r};
-
-pub struct File(FileDesc);
-
-#[derive(Clone)]
-pub struct FileAttr {
- stat: stat64,
-}
-
-// all DirEntry's will have a reference to this struct
-struct InnerReadDir {
- dirp: Dir,
- root: PathBuf,
-}
-
-#[derive(Clone)]
-pub struct ReadDir {
- inner: Arc<InnerReadDir>,
- end_of_stream: bool,
-}
-
-struct Dir(*mut libc::DIR);
-
-unsafe impl Send for Dir {}
-unsafe impl Sync for Dir {}
-
-pub struct DirEntry {
- entry: dirent64,
- dir: ReadDir,
- // We need to store an owned copy of the entry name
- // on Solaris and Fuchsia because a) it uses a zero-length
- // array to store the name, b) its lifetime between readdir
- // calls is not guaranteed.
- #[cfg(any(target_os = "solaris", target_os = "fuchsia"))]
- name: Box<[u8]>
-}
-
-#[derive(Clone, Debug)]
-pub struct OpenOptions {
- // generic
- read: bool,
- write: bool,
- append: bool,
- truncate: bool,
- create: bool,
- create_new: bool,
- // system-specific
- custom_flags: i32,
- mode: mode_t,
-}
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct FilePermissions { mode: mode_t }
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-pub struct FileType { mode: mode_t }
-
-#[derive(Debug)]
-pub struct DirBuilder { mode: mode_t }
-
-impl FileAttr {
- pub fn size(&self) -> u64 { self.stat.st_size as u64 }
- pub fn perm(&self) -> FilePermissions {
- FilePermissions { mode: (self.stat.st_mode as mode_t) }
- }
-
- pub fn file_type(&self) -> FileType {
- FileType { mode: self.stat.st_mode as mode_t }
- }
-}
-
-#[cfg(target_os = "netbsd")]
-impl FileAttr {
- pub fn modified(&self) -> io::Result<SystemTime> {
- Ok(SystemTime::from(libc::timespec {
- tv_sec: self.stat.st_mtime as libc::time_t,
- tv_nsec: self.stat.st_mtimensec as libc::c_long,
- }))
- }
-
- pub fn accessed(&self) -> io::Result<SystemTime> {
- Ok(SystemTime::from(libc::timespec {
- tv_sec: self.stat.st_atime as libc::time_t,
- tv_nsec: self.stat.st_atimensec as libc::c_long,
- }))
- }
-
- pub fn created(&self) -> io::Result<SystemTime> {
- Ok(SystemTime::from(libc::timespec {
- tv_sec: self.stat.st_birthtime as libc::time_t,
- tv_nsec: self.stat.st_birthtimensec as libc::c_long,
- }))
- }
-}
-
-#[cfg(not(target_os = "netbsd"))]
-impl FileAttr {
- pub fn modified(&self) -> io::Result<SystemTime> {
- Ok(SystemTime::from(libc::timespec {
- tv_sec: self.stat.st_mtime as libc::time_t,
- tv_nsec: self.stat.st_mtime_nsec as _,
- }))
- }
-
- pub fn accessed(&self) -> io::Result<SystemTime> {
- Ok(SystemTime::from(libc::timespec {
- tv_sec: self.stat.st_atime as libc::time_t,
- tv_nsec: self.stat.st_atime_nsec as _,
- }))
- }
-
- #[cfg(any(target_os = "bitrig",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "macos",
- target_os = "ios"))]
- pub fn created(&self) -> io::Result<SystemTime> {
- Ok(SystemTime::from(libc::timespec {
- tv_sec: self.stat.st_birthtime as libc::time_t,
- tv_nsec: self.stat.st_birthtime_nsec as libc::c_long,
- }))
- }
-
- #[cfg(not(any(target_os = "bitrig",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "macos",
- target_os = "ios")))]
- pub fn created(&self) -> io::Result<SystemTime> {
- Err(io::Error::new(io::ErrorKind::Other,
- "creation time is not available on this platform \
- currently"))
- }
-}
-
-impl AsInner<stat64> for FileAttr {
- fn as_inner(&self) -> &stat64 { &self.stat }
-}
-
-impl FilePermissions {
- pub fn readonly(&self) -> bool {
- // check if any class (owner, group, others) has write permission
- self.mode & 0o222 == 0
- }
-
- pub fn set_readonly(&mut self, readonly: bool) {
- if readonly {
- // remove write permission for all classes; equivalent to `chmod a-w <file>`
- self.mode &= !0o222;
- } else {
- // add write permission for all classes; equivalent to `chmod a+w <file>`
- self.mode |= 0o222;
- }
- }
- pub fn mode(&self) -> u32 { self.mode as u32 }
-}
-
-impl FileType {
- pub fn is_dir(&self) -> bool { self.is(libc::S_IFDIR) }
- pub fn is_file(&self) -> bool { self.is(libc::S_IFREG) }
- pub fn is_symlink(&self) -> bool { self.is(libc::S_IFLNK) }
-
- pub fn is(&self, mode: mode_t) -> bool { self.mode & libc::S_IFMT == mode }
-}
-
-impl FromInner<u32> for FilePermissions {
- fn from_inner(mode: u32) -> FilePermissions {
- FilePermissions { mode: mode as mode_t }
- }
-}
-
-impl fmt::Debug for ReadDir {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame.
- // Thus the result will be e g 'ReadDir("/home")'
- fmt::Debug::fmt(&*self.inner.root, f)
- }
-}
-
-impl Iterator for ReadDir {
- type Item = io::Result<DirEntry>;
-
- #[cfg(any(target_os = "solaris", target_os = "fuchsia"))]
- fn next(&mut self) -> Option<io::Result<DirEntry>> {
- unsafe {
- loop {
- // Although readdir_r(3) would be a correct function to use here because
- // of the thread safety, on Illumos and Fuchsia the readdir(3C) function
- // is safe to use in threaded applications and it is generally preferred
- // over the readdir_r(3C) function.
- super::os::set_errno(0);
- let entry_ptr = libc::readdir(self.inner.dirp.0);
- if entry_ptr.is_null() {
- // NULL can mean either the end is reached or an error occurred.
- // So we had to clear errno beforehand to check for an error now.
- return match super::os::errno() {
- 0 => None,
- e => Some(Err(Error::from_raw_os_error(e))),
- }
- }
-
- let name = (*entry_ptr).d_name.as_ptr();
- let namelen = libc::strlen(name) as usize;
-
- let ret = DirEntry {
- entry: *entry_ptr,
- name: ::slice::from_raw_parts(name as *const u8,
- namelen as usize).to_owned().into_boxed_slice(),
- dir: self.clone()
- };
- if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
- return Some(Ok(ret))
- }
- }
- }
- }
-
- #[cfg(not(any(target_os = "solaris", target_os = "fuchsia")))]
- fn next(&mut self) -> Option<io::Result<DirEntry>> {
- if self.end_of_stream {
- return None;
- }
-
- unsafe {
- let mut ret = DirEntry {
- entry: mem::zeroed(),
- dir: self.clone(),
- };
- let mut entry_ptr = ptr::null_mut();
- loop {
- if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
- if entry_ptr.is_null() {
- // We encountered an error (which will be returned in this iteration), but
- // we also reached the end of the directory stream. The `end_of_stream`
- // flag is enabled to make sure that we return `None` in the next iteration
- // (instead of looping forever)
- self.end_of_stream = true;
- }
- return Some(Err(Error::last_os_error()))
- }
- if entry_ptr.is_null() {
- return None
- }
- if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
- return Some(Ok(ret))
- }
- }
- }
- }
-}
-
-impl Drop for Dir {
- fn drop(&mut self) {
- let r = unsafe { libc::closedir(self.0) };
- debug_assert_eq!(r, 0);
- }
-}
-
-impl DirEntry {
- pub fn path(&self) -> PathBuf {
- self.dir.inner.root.join(OsStr::from_bytes(self.name_bytes()))
- }
-
- pub fn file_name(&self) -> OsString {
- OsStr::from_bytes(self.name_bytes()).to_os_string()
- }
-
- #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
- pub fn metadata(&self) -> io::Result<FileAttr> {
- let fd = cvt(unsafe {dirfd(self.dir.inner.dirp.0)})?;
- let mut stat: stat64 = unsafe { mem::zeroed() };
- cvt(unsafe {
- fstatat64(fd, self.entry.d_name.as_ptr(), &mut stat, libc::AT_SYMLINK_NOFOLLOW)
- })?;
- Ok(FileAttr { stat: stat })
- }
-
- #[cfg(not(any(target_os = "linux", target_os = "emscripten", target_os = "android")))]
- pub fn metadata(&self) -> io::Result<FileAttr> {
- lstat(&self.path())
- }
-
- #[cfg(any(target_os = "solaris", target_os = "haiku", target_os = "hermit"))]
- pub fn file_type(&self) -> io::Result<FileType> {
- lstat(&self.path()).map(|m| m.file_type())
- }
-
- #[cfg(not(any(target_os = "solaris", target_os = "haiku", target_os = "hermit")))]
- pub fn file_type(&self) -> io::Result<FileType> {
- match self.entry.d_type {
- libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }),
- libc::DT_FIFO => Ok(FileType { mode: libc::S_IFIFO }),
- libc::DT_LNK => Ok(FileType { mode: libc::S_IFLNK }),
- libc::DT_REG => Ok(FileType { mode: libc::S_IFREG }),
- libc::DT_SOCK => Ok(FileType { mode: libc::S_IFSOCK }),
- libc::DT_DIR => Ok(FileType { mode: libc::S_IFDIR }),
- libc::DT_BLK => Ok(FileType { mode: libc::S_IFBLK }),
- _ => lstat(&self.path()).map(|m| m.file_type()),
- }
- }
-
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "linux",
- target_os = "emscripten",
- target_os = "android",
- target_os = "solaris",
- target_os = "haiku",
- target_os = "l4re",
- target_os = "fuchsia",
- target_os = "hermit"))]
- pub fn ino(&self) -> u64 {
- self.entry.d_ino as u64
- }
-
- #[cfg(any(target_os = "freebsd",
- target_os = "openbsd",
- target_os = "bitrig",
- target_os = "netbsd",
- target_os = "dragonfly"))]
- pub fn ino(&self) -> u64 {
- self.entry.d_fileno as u64
- }
-
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "bitrig"))]
- fn name_bytes(&self) -> &[u8] {
- unsafe {
- ::slice::from_raw_parts(self.entry.d_name.as_ptr() as *const u8,
- self.entry.d_namlen as usize)
- }
- }
- #[cfg(any(target_os = "android",
- target_os = "linux",
- target_os = "emscripten",
- target_os = "l4re",
- target_os = "haiku",
- target_os = "hermit"))]
- fn name_bytes(&self) -> &[u8] {
- unsafe {
- CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes()
- }
- }
- #[cfg(any(target_os = "solaris",
- target_os = "fuchsia"))]
- fn name_bytes(&self) -> &[u8] {
- &*self.name
- }
-}
-
-impl OpenOptions {
- pub fn new() -> OpenOptions {
- OpenOptions {
- // generic
- read: false,
- write: false,
- append: false,
- truncate: false,
- create: false,
- create_new: false,
- // system-specific
- custom_flags: 0,
- mode: 0o666,
- }
- }
-
- pub fn read(&mut self, read: bool) { self.read = read; }
- pub fn write(&mut self, write: bool) { self.write = write; }
- pub fn append(&mut self, append: bool) { self.append = append; }
- pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; }
- pub fn create(&mut self, create: bool) { self.create = create; }
- pub fn create_new(&mut self, create_new: bool) { self.create_new = create_new; }
-
- pub fn custom_flags(&mut self, flags: i32) { self.custom_flags = flags; }
- pub fn mode(&mut self, mode: u32) { self.mode = mode as mode_t; }
-
- fn get_access_mode(&self) -> io::Result<c_int> {
- match (self.read, self.write, self.append) {
- (true, false, false) => Ok(libc::O_RDONLY),
- (false, true, false) => Ok(libc::O_WRONLY),
- (true, true, false) => Ok(libc::O_RDWR),
- (false, _, true) => Ok(libc::O_WRONLY | libc::O_APPEND),
- (true, _, true) => Ok(libc::O_RDWR | libc::O_APPEND),
- (false, false, false) => Err(Error::from_raw_os_error(libc::EINVAL)),
- }
- }
-
- fn get_creation_mode(&self) -> io::Result<c_int> {
- match (self.write, self.append) {
- (true, false) => {}
- (false, false) =>
- if self.truncate || self.create || self.create_new {
- return Err(Error::from_raw_os_error(libc::EINVAL));
- },
- (_, true) =>
- if self.truncate && !self.create_new {
- return Err(Error::from_raw_os_error(libc::EINVAL));
- },
- }
-
- Ok(match (self.create, self.truncate, self.create_new) {
- (false, false, false) => 0,
- (true, false, false) => libc::O_CREAT,
- (false, true, false) => libc::O_TRUNC,
- (true, true, false) => libc::O_CREAT | libc::O_TRUNC,
- (_, _, true) => libc::O_CREAT | libc::O_EXCL,
- })
- }
-}
-
-impl File {
- pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
- let path = cstr(path)?;
- File::open_c(&path, opts)
- }
-
- pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> {
- let flags = libc::O_CLOEXEC |
- opts.get_access_mode()? |
- opts.get_creation_mode()? |
- (opts.custom_flags as c_int & !libc::O_ACCMODE);
- let fd = cvt_r(|| unsafe {
- open64(path.as_ptr(), flags, opts.mode as c_int)
- })?;
- let fd = FileDesc::new(fd);
-
- // Currently the standard library supports Linux 2.6.18 which did not
- // have the O_CLOEXEC flag (passed above). If we're running on an older
- // Linux kernel then the flag is just ignored by the OS. After we open
- // the first file, we check whether it has CLOEXEC set. If it doesn't,
- // we will explicitly ask for a CLOEXEC fd for every further file we
- // open, if it does, we will skip that step.
- //
- // The CLOEXEC flag, however, is supported on versions of macOS/BSD/etc
- // that we support, so we only do this on Linux currently.
- #[cfg(target_os = "linux")]
- fn ensure_cloexec(fd: &FileDesc) -> io::Result<()> {
- use sync::atomic::{AtomicUsize, Ordering};
-
- const OPEN_CLOEXEC_UNKNOWN: usize = 0;
- const OPEN_CLOEXEC_SUPPORTED: usize = 1;
- const OPEN_CLOEXEC_NOTSUPPORTED: usize = 2;
- static OPEN_CLOEXEC: AtomicUsize = AtomicUsize::new(OPEN_CLOEXEC_UNKNOWN);
-
- let need_to_set;
- match OPEN_CLOEXEC.load(Ordering::Relaxed) {
- OPEN_CLOEXEC_UNKNOWN => {
- need_to_set = !fd.get_cloexec()?;
- OPEN_CLOEXEC.store(if need_to_set {
- OPEN_CLOEXEC_NOTSUPPORTED
- } else {
- OPEN_CLOEXEC_SUPPORTED
- }, Ordering::Relaxed);
- },
- OPEN_CLOEXEC_SUPPORTED => need_to_set = false,
- OPEN_CLOEXEC_NOTSUPPORTED => need_to_set = true,
- _ => unreachable!(),
- }
- if need_to_set {
- fd.set_cloexec()?;
- }
- Ok(())
- }
-
- #[cfg(not(target_os = "linux"))]
- fn ensure_cloexec(_: &FileDesc) -> io::Result<()> {
- Ok(())
- }
-
- ensure_cloexec(&fd)?;
- Ok(File(fd))
- }
-
- pub fn file_attr(&self) -> io::Result<FileAttr> {
- let mut stat: stat64 = unsafe { mem::zeroed() };
- cvt(unsafe {
- fstat64(self.0.raw(), &mut stat)
- })?;
- Ok(FileAttr { stat: stat })
- }
-
- pub fn fsync(&self) -> io::Result<()> {
- cvt_r(|| unsafe { libc::fsync(self.0.raw()) })?;
- Ok(())
- }
-
- pub fn datasync(&self) -> io::Result<()> {
- cvt_r(|| unsafe { os_datasync(self.0.raw()) })?;
- return Ok(());
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- unsafe fn os_datasync(fd: c_int) -> c_int {
- libc::fcntl(fd, libc::F_FULLFSYNC)
- }
- #[cfg(target_os = "linux")]
- unsafe fn os_datasync(fd: c_int) -> c_int { libc::fdatasync(fd) }
- #[cfg(not(any(target_os = "macos",
- target_os = "ios",
- target_os = "linux")))]
- unsafe fn os_datasync(fd: c_int) -> c_int { libc::fsync(fd) }
- }
-
- pub fn truncate(&self, size: u64) -> io::Result<()> {
- #[cfg(target_os = "android")]
- return ::sys::android::ftruncate64(self.0.raw(), size);
-
- #[cfg(not(target_os = "android"))]
- return cvt_r(|| unsafe {
- ftruncate64(self.0.raw(), size as off64_t)
- }).map(|_| ());
- }
-
- pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.0.read(buf)
- }
-
- pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
- self.0.read_at(buf, offset)
- }
-
- pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
- self.0.write(buf)
- }
-
- pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
- self.0.write_at(buf, offset)
- }
-
- pub fn flush(&self) -> io::Result<()> { Ok(()) }
-
- pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
- let (whence, pos) = match pos {
- // Casting to `i64` is fine, too large values will end up as
- // negative which will cause an error in `lseek64`.
- SeekFrom::Start(off) => (libc::SEEK_SET, off as i64),
- SeekFrom::End(off) => (libc::SEEK_END, off),
- SeekFrom::Current(off) => (libc::SEEK_CUR, off),
- };
- #[cfg(target_os = "emscripten")]
- let pos = pos as i32;
- let n = cvt(unsafe { lseek64(self.0.raw(), pos, whence) })?;
- Ok(n as u64)
- }
-
- pub fn duplicate(&self) -> io::Result<File> {
- self.0.duplicate().map(File)
- }
-
- pub fn fd(&self) -> &FileDesc { &self.0 }
-
- pub fn into_fd(self) -> FileDesc { self.0 }
-
- pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
- cvt_r(|| unsafe { libc::fchmod(self.0.raw(), perm.mode) })?;
- Ok(())
- }
-}
-
-impl DirBuilder {
- pub fn new() -> DirBuilder {
- DirBuilder { mode: 0o777 }
- }
-
- pub fn mkdir(&self, p: &Path) -> io::Result<()> {
- let p = cstr(p)?;
- cvt(unsafe { libc::mkdir(p.as_ptr(), self.mode) })?;
- Ok(())
- }
-
- pub fn set_mode(&mut self, mode: u32) {
- self.mode = mode as mode_t;
- }
-}
-
-fn cstr(path: &Path) -> io::Result<CString> {
- Ok(CString::new(path.as_os_str().as_bytes())?)
-}
-
-impl FromInner<c_int> for File {
- fn from_inner(fd: c_int) -> File {
- File(FileDesc::new(fd))
- }
-}
-
-impl fmt::Debug for File {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- #[cfg(target_os = "linux")]
- fn get_path(fd: c_int) -> Option<PathBuf> {
- let mut p = PathBuf::from("/proc/self/fd");
- p.push(&fd.to_string());
- readlink(&p).ok()
- }
-
- #[cfg(target_os = "macos")]
- fn get_path(fd: c_int) -> Option<PathBuf> {
- // FIXME: The use of PATH_MAX is generally not encouraged, but it
- // is inevitable in this case because macOS defines `fcntl` with
- // `F_GETPATH` in terms of `MAXPATHLEN`, and there are no
- // alternatives. If a better method is invented, it should be used
- // instead.
- let mut buf = vec![0;libc::PATH_MAX as usize];
- let n = unsafe { libc::fcntl(fd, libc::F_GETPATH, buf.as_ptr()) };
- if n == -1 {
- return None;
- }
- let l = buf.iter().position(|&c| c == 0).unwrap();
- buf.truncate(l as usize);
- buf.shrink_to_fit();
- Some(PathBuf::from(OsString::from_vec(buf)))
- }
-
- #[cfg(not(any(target_os = "linux", target_os = "macos")))]
- fn get_path(_fd: c_int) -> Option<PathBuf> {
- // FIXME(#24570): implement this for other Unix platforms
- None
- }
-
- #[cfg(any(target_os = "linux", target_os = "macos"))]
- fn get_mode(fd: c_int) -> Option<(bool, bool)> {
- let mode = unsafe { libc::fcntl(fd, libc::F_GETFL) };
- if mode == -1 {
- return None;
- }
- match mode & libc::O_ACCMODE {
- libc::O_RDONLY => Some((true, false)),
- libc::O_RDWR => Some((true, true)),
- libc::O_WRONLY => Some((false, true)),
- _ => None
- }
- }
-
- #[cfg(not(any(target_os = "linux", target_os = "macos")))]
- fn get_mode(_fd: c_int) -> Option<(bool, bool)> {
- // FIXME(#24570): implement this for other Unix platforms
- None
- }
-
- let fd = self.0.raw();
- let mut b = f.debug_struct("File");
- b.field("fd", &fd);
- if let Some(path) = get_path(fd) {
- b.field("path", &path);
- }
- if let Some((read, write)) = get_mode(fd) {
- b.field("read", &read).field("write", &write);
- }
- b.finish()
- }
-}
-
-pub fn readdir(p: &Path) -> io::Result<ReadDir> {
- let root = p.to_path_buf();
- let p = cstr(p)?;
- unsafe {
- let ptr = libc::opendir(p.as_ptr());
- if ptr.is_null() {
- Err(Error::last_os_error())
- } else {
- let inner = InnerReadDir { dirp: Dir(ptr), root };
- Ok(ReadDir{
- inner: Arc::new(inner),
- end_of_stream: false,
- })
- }
- }
-}
-
-pub fn unlink(p: &Path) -> io::Result<()> {
- let p = cstr(p)?;
- cvt(unsafe { libc::unlink(p.as_ptr()) })?;
- Ok(())
-}
-
-pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
- let old = cstr(old)?;
- let new = cstr(new)?;
- cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) })?;
- Ok(())
-}
-
-pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
- let p = cstr(p)?;
- cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) })?;
- Ok(())
-}
-
-pub fn rmdir(p: &Path) -> io::Result<()> {
- let p = cstr(p)?;
- cvt(unsafe { libc::rmdir(p.as_ptr()) })?;
- Ok(())
-}
-
-pub fn remove_dir_all(path: &Path) -> io::Result<()> {
- let filetype = lstat(path)?.file_type();
- if filetype.is_symlink() {
- unlink(path)
- } else {
- remove_dir_all_recursive(path)
- }
-}
-
-fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
- for child in readdir(path)? {
- let child = child?;
- if child.file_type()?.is_dir() {
- remove_dir_all_recursive(&child.path())?;
- } else {
- unlink(&child.path())?;
- }
- }
- rmdir(path)
-}
-
-pub fn readlink(p: &Path) -> io::Result<PathBuf> {
- let c_path = cstr(p)?;
- let p = c_path.as_ptr();
-
- let mut buf = Vec::with_capacity(256);
-
- loop {
- let buf_read = cvt(unsafe {
- libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity())
- })? as usize;
-
- unsafe { buf.set_len(buf_read); }
-
- if buf_read != buf.capacity() {
- buf.shrink_to_fit();
-
- return Ok(PathBuf::from(OsString::from_vec(buf)));
- }
-
- // Trigger the internal buffer resizing logic of `Vec` by requiring
- // more space than the current capacity. The length is guaranteed to be
- // the same as the capacity due to the if statement above.
- buf.reserve(1);
- }
-}
-
-pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
- let src = cstr(src)?;
- let dst = cstr(dst)?;
- cvt(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })?;
- Ok(())
-}
-
-pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
- let src = cstr(src)?;
- let dst = cstr(dst)?;
- cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })?;
- Ok(())
-}
-
-pub fn stat(p: &Path) -> io::Result<FileAttr> {
- let p = cstr(p)?;
- let mut stat: stat64 = unsafe { mem::zeroed() };
- cvt(unsafe {
- stat64(p.as_ptr(), &mut stat)
- })?;
- Ok(FileAttr { stat: stat })
-}
-
-pub fn lstat(p: &Path) -> io::Result<FileAttr> {
- let p = cstr(p)?;
- let mut stat: stat64 = unsafe { mem::zeroed() };
- cvt(unsafe {
- lstat64(p.as_ptr(), &mut stat)
- })?;
- Ok(FileAttr { stat: stat })
-}
-
-pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
- let path = CString::new(p.as_os_str().as_bytes())?;
- let buf;
- unsafe {
- let r = libc::realpath(path.as_ptr(), ptr::null_mut());
- if r.is_null() {
- return Err(io::Error::last_os_error())
- }
- buf = CStr::from_ptr(r).to_bytes().to_vec();
- libc::free(r as *mut _);
- }
- Ok(PathBuf::from(OsString::from_vec(buf)))
-}
-
-#[cfg(not(any(target_os = "linux", target_os = "android")))]
-pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
- use fs::File;
- if !from.is_file() {
- return Err(Error::new(ErrorKind::InvalidInput,
- "the source path is not an existing regular file"))
- }
-
- let mut reader = File::open(from)?;
- let mut writer = File::create(to)?;
- let perm = reader.metadata()?.permissions();
-
- let ret = io::copy(&mut reader, &mut writer)?;
- writer.set_permissions(perm)?;
- Ok(ret)
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
- use cmp;
- use fs::File;
- use sync::atomic::{AtomicBool, Ordering};
-
- // Kernel prior to 4.5 don't have copy_file_range
- // We store the availability in a global to avoid unneccessary syscalls
- static HAS_COPY_FILE_RANGE: AtomicBool = AtomicBool::new(true);
-
- unsafe fn copy_file_range(
- fd_in: libc::c_int,
- off_in: *mut libc::loff_t,
- fd_out: libc::c_int,
- off_out: *mut libc::loff_t,
- len: libc::size_t,
- flags: libc::c_uint,
- ) -> libc::c_long {
- libc::syscall(
- libc::SYS_copy_file_range,
- fd_in,
- off_in,
- fd_out,
- off_out,
- len,
- flags,
- )
- }
-
- if !from.is_file() {
- return Err(Error::new(ErrorKind::InvalidInput,
- "the source path is not an existing regular file"))
- }
-
- let mut reader = File::open(from)?;
- let mut writer = File::create(to)?;
- let (perm, len) = {
- let metadata = reader.metadata()?;
- (metadata.permissions(), metadata.size())
- };
-
- let has_copy_file_range = HAS_COPY_FILE_RANGE.load(Ordering::Relaxed);
- let mut written = 0u64;
- while written < len {
- let copy_result = if has_copy_file_range {
- let bytes_to_copy = cmp::min(len - written, usize::max_value() as u64) as usize;
- let copy_result = unsafe {
- // We actually don't have to adjust the offsets,
- // because copy_file_range adjusts the file offset automatically
- cvt(copy_file_range(reader.as_raw_fd(),
- ptr::null_mut(),
- writer.as_raw_fd(),
- ptr::null_mut(),
- bytes_to_copy,
- 0)
- )
- };
- if let Err(ref copy_err) = copy_result {
- match copy_err.raw_os_error() {
- Some(libc::ENOSYS) | Some(libc::EPERM) => {
- HAS_COPY_FILE_RANGE.store(false, Ordering::Relaxed);
- }
- _ => {}
- }
- }
- copy_result
- } else {
- Err(io::Error::from_raw_os_error(libc::ENOSYS))
- };
- match copy_result {
- Ok(ret) => written += ret as u64,
- Err(err) => {
- match err.raw_os_error() {
- Some(os_err) if os_err == libc::ENOSYS
- || os_err == libc::EXDEV
- || os_err == libc::EPERM => {
- // Try fallback io::copy if either:
- // - Kernel version is < 4.5 (ENOSYS)
- // - Files are mounted on different fs (EXDEV)
- // - copy_file_range is disallowed, for example by seccomp (EPERM)
- assert_eq!(written, 0);
- let ret = io::copy(&mut reader, &mut writer)?;
- writer.set_permissions(perm)?;
- return Ok(ret)
- },
- _ => return Err(err),
- }
- }
- }
- }
- writer.set_permissions(perm)?;
- Ok(written)
-}
diff --git a/ctr-std/src/sys/unix/l4re.rs b/ctr-std/src/sys/unix/l4re.rs
deleted file mode 100644
index 2121848..0000000
--- a/ctr-std/src/sys/unix/l4re.rs
+++ /dev/null
@@ -1,441 +0,0 @@
-// Copyright 2016-2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-macro_rules! unimpl {
- () => (return Err(io::Error::new(io::ErrorKind::Other, "No networking available on L4Re."));)
-}
-
-pub mod net {
- #![allow(warnings)]
- use fmt;
- use io;
- use libc;
- use net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
- use sys_common::{AsInner, FromInner, IntoInner};
- use sys::fd::FileDesc;
- use time::Duration;
-
-
- pub extern crate libc as netc;
-
- pub struct Socket(FileDesc);
- impl Socket {
- pub fn new(_: &SocketAddr, _: libc::c_int) -> io::Result<Socket> {
- unimpl!();
- }
-
- pub fn new_raw(_: libc::c_int, _: libc::c_int) -> io::Result<Socket> {
- unimpl!();
- }
-
- pub fn new_pair(_: libc::c_int, _: libc::c_int) -> io::Result<(Socket, Socket)> {
- unimpl!();
- }
-
- pub fn connect_timeout(&self, _: &SocketAddr, _: Duration) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn accept(&self, _: *mut libc::sockaddr, _: *mut libc::socklen_t)
- -> io::Result<Socket> {
- unimpl!();
- }
-
- pub fn duplicate(&self) -> io::Result<Socket> {
- unimpl!();
- }
-
- pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
- unimpl!();
- }
-
- pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
- unimpl!();
- }
-
- pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- unimpl!();
- }
-
- pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- unimpl!();
- }
-
- pub fn write(&self, _: &[u8]) -> io::Result<usize> {
- unimpl!();
- }
-
- pub fn set_timeout(&self, _: Option<Duration>, _: libc::c_int) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn timeout(&self, _: libc::c_int) -> io::Result<Option<Duration>> {
- unimpl!();
- }
-
- pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn nodelay(&self) -> io::Result<bool> {
- unimpl!();
- }
-
- pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- unimpl!();
- }
- }
-
- impl AsInner<libc::c_int> for Socket {
- fn as_inner(&self) -> &libc::c_int { self.0.as_inner() }
- }
-
- impl FromInner<libc::c_int> for Socket {
- fn from_inner(fd: libc::c_int) -> Socket { Socket(FileDesc::new(fd)) }
- }
-
- impl IntoInner<libc::c_int> for Socket {
- fn into_inner(self) -> libc::c_int { self.0.into_raw() }
- }
-
- pub struct TcpStream {
- inner: Socket,
- }
-
- impl TcpStream {
- pub fn connect(_: &SocketAddr) -> io::Result<TcpStream> {
- unimpl!();
- }
-
- pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
- unimpl!();
- }
-
- pub fn socket(&self) -> &Socket { &self.inner }
-
- pub fn into_socket(self) -> Socket { self.inner }
-
- pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
- unimpl!();
- }
-
- pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
- unimpl!();
- }
-
- pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
- unimpl!();
- }
-
- pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
- unimpl!();
- }
-
- pub fn write(&self, _: &[u8]) -> io::Result<usize> {
- unimpl!();
- }
-
- pub fn peer_addr(&self) -> io::Result<SocketAddr> {
- unimpl!();
- }
-
- pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- unimpl!();
- }
-
- pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn duplicate(&self) -> io::Result<TcpStream> {
- unimpl!();
- }
-
- pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn nodelay(&self) -> io::Result<bool> {
- unimpl!();
- }
-
- pub fn set_ttl(&self, _: u32) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn ttl(&self) -> io::Result<u32> {
- unimpl!();
- }
-
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- unimpl!();
- }
-
- pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
- unimpl!();
- }
- }
-
- impl FromInner<Socket> for TcpStream {
- fn from_inner(socket: Socket) -> TcpStream {
- TcpStream { inner: socket }
- }
- }
-
- impl fmt::Debug for TcpStream {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "No networking support available on L4Re")
- }
- }
-
- pub struct TcpListener {
- inner: Socket,
- }
-
- impl TcpListener {
- pub fn bind(_: &SocketAddr) -> io::Result<TcpListener> {
- unimpl!();
- }
-
- pub fn socket(&self) -> &Socket { &self.inner }
-
- pub fn into_socket(self) -> Socket { self.inner }
-
- pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- unimpl!();
- }
-
- pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
- unimpl!();
- }
-
- pub fn duplicate(&self) -> io::Result<TcpListener> {
- unimpl!();
- }
-
- pub fn set_ttl(&self, _: u32) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn ttl(&self) -> io::Result<u32> {
- unimpl!();
- }
-
- pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn only_v6(&self) -> io::Result<bool> {
- unimpl!();
- }
-
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- unimpl!();
- }
-
- pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
- unimpl!();
- }
- }
-
- impl FromInner<Socket> for TcpListener {
- fn from_inner(socket: Socket) -> TcpListener {
- TcpListener { inner: socket }
- }
- }
-
- impl fmt::Debug for TcpListener {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "No networking support available on L4Re.")
- }
- }
-
- pub struct UdpSocket {
- inner: Socket,
- }
-
- impl UdpSocket {
- pub fn bind(_: &SocketAddr) -> io::Result<UdpSocket> {
- unimpl!();
- }
-
- pub fn socket(&self) -> &Socket { &self.inner }
-
- pub fn into_socket(self) -> Socket { self.inner }
-
- pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- unimpl!();
- }
-
- pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- unimpl!();
- }
-
- pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- unimpl!();
- }
-
- pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
- unimpl!();
- }
-
- pub fn duplicate(&self) -> io::Result<UdpSocket> {
- unimpl!();
- }
-
- pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
- unimpl!();
- }
-
- pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
- unimpl!();
- }
-
- pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn broadcast(&self) -> io::Result<bool> {
- unimpl!();
- }
-
- pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn multicast_loop_v4(&self) -> io::Result<bool> {
- unimpl!();
- }
-
- pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
- unimpl!();
- }
-
- pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn multicast_loop_v6(&self) -> io::Result<bool> {
- unimpl!();
- }
-
- pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
- -> io::Result<()> {
- unimpl!();
- }
-
- pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
- -> io::Result<()> {
- unimpl!();
- }
-
- pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
- -> io::Result<()> {
- unimpl!();
- }
-
- pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
- -> io::Result<()> {
- unimpl!();
- }
-
- pub fn set_ttl(&self, _: u32) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn ttl(&self) -> io::Result<u32> {
- unimpl!();
- }
-
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- unimpl!();
- }
-
- pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
- unimpl!();
- }
-
- pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
- unimpl!();
- }
-
- pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
- unimpl!();
- }
-
- pub fn send(&self, _: &[u8]) -> io::Result<usize> {
- unimpl!();
- }
-
- pub fn connect(&self, _: &SocketAddr) -> io::Result<()> {
- unimpl!();
- }
- }
-
- impl FromInner<Socket> for UdpSocket {
- fn from_inner(socket: Socket) -> UdpSocket {
- UdpSocket { inner: socket }
- }
- }
-
- impl fmt::Debug for UdpSocket {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "No networking support on L4Re available.")
- }
- }
-
- pub struct LookupHost {
- original: *mut libc::addrinfo,
- cur: *mut libc::addrinfo,
- }
-
- impl Iterator for LookupHost {
- type Item = SocketAddr;
- fn next(&mut self) -> Option<SocketAddr> {
- None
- }
- }
-
- unsafe impl Sync for LookupHost {}
- unsafe impl Send for LookupHost {}
-
- pub fn lookup_host(_: &str) -> io::Result<LookupHost> {
- unimpl!();
- }
-}
-
diff --git a/ctr-std/src/sys/unix/memchr.rs b/ctr-std/src/sys/unix/memchr.rs
deleted file mode 100644
index f49adc2..0000000
--- a/ctr-std/src/sys/unix/memchr.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-//
-// Original implementation taken from rust-memchr
-// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
-
-pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
- use libc;
-
- let p = unsafe {
- libc::memchr(
- haystack.as_ptr() as *const libc::c_void,
- needle as libc::c_int,
- haystack.len())
- };
- if p.is_null() {
- None
- } else {
- Some(p as usize - (haystack.as_ptr() as usize))
- }
-}
-
-pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
-
- #[cfg(target_os = "linux")]
- fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
- use libc;
-
- // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
- if haystack.is_empty() {return None}
- let p = unsafe {
- libc::memrchr(
- haystack.as_ptr() as *const libc::c_void,
- needle as libc::c_int,
- haystack.len())
- };
- if p.is_null() {
- None
- } else {
- Some(p as usize - (haystack.as_ptr() as usize))
- }
- }
-
- #[cfg(not(target_os = "linux"))]
- fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
- ::core::slice::memchr::memrchr(needle, haystack)
- }
-
- memrchr_specific(needle, haystack)
-}
diff --git a/ctr-std/src/sys/unix/mod.rs b/ctr-std/src/sys/unix/mod.rs
deleted file mode 100644
index c738003..0000000
--- a/ctr-std/src/sys/unix/mod.rs
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(missing_docs, bad_style)]
-
-use io::{self, ErrorKind};
-use libc;
-
-#[cfg(any(dox, target_os = "linux"))] pub use os::linux as platform;
-
-#[cfg(all(not(dox), target_os = "android"))] pub use os::android as platform;
-#[cfg(all(not(dox), target_os = "bitrig"))] pub use os::bitrig as platform;
-#[cfg(all(not(dox), target_os = "dragonfly"))] pub use os::dragonfly as platform;
-#[cfg(all(not(dox), target_os = "freebsd"))] pub use os::freebsd as platform;
-#[cfg(all(not(dox), target_os = "haiku"))] pub use os::haiku as platform;
-#[cfg(all(not(dox), target_os = "ios"))] pub use os::ios as platform;
-#[cfg(all(not(dox), target_os = "macos"))] pub use os::macos as platform;
-#[cfg(all(not(dox), target_os = "netbsd"))] pub use os::netbsd as platform;
-#[cfg(all(not(dox), target_os = "openbsd"))] pub use os::openbsd as platform;
-#[cfg(all(not(dox), target_os = "solaris"))] pub use os::solaris as platform;
-#[cfg(all(not(dox), target_os = "emscripten"))] pub use os::emscripten as platform;
-#[cfg(all(not(dox), target_os = "fuchsia"))] pub use os::fuchsia as platform;
-#[cfg(all(not(dox), target_os = "l4re"))] pub use os::linux as platform;
-#[cfg(all(not(dox), target_os = "hermit"))] pub use os::hermit as platform;
-
-pub use self::rand::hashmap_random_keys;
-pub use libc::strlen;
-
-#[macro_use]
-pub mod weak;
-
-pub mod args;
-pub mod android;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
-pub mod cmath;
-pub mod condvar;
-pub mod env;
-pub mod ext;
-pub mod fast_thread_local;
-pub mod fd;
-pub mod fs;
-pub mod memchr;
-pub mod mutex;
-#[cfg(not(target_os = "l4re"))]
-pub mod net;
-#[cfg(target_os = "l4re")]
-mod l4re;
-#[cfg(target_os = "l4re")]
-pub use self::l4re::net;
-pub mod os;
-pub mod os_str;
-pub mod path;
-pub mod pipe;
-pub mod process;
-pub mod rand;
-pub mod rwlock;
-pub mod stack_overflow;
-pub mod thread;
-pub mod thread_local;
-pub mod time;
-pub mod stdio;
-
-#[cfg(not(test))]
-pub fn init() {
- // 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
- // want!
- //
- // Hence, we set SIGPIPE to ignore when the program starts up in order
- // to prevent this problem.
- unsafe {
- reset_sigpipe();
- }
-
- #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia")))]
- unsafe fn reset_sigpipe() {
- assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR);
- }
- #[cfg(any(target_os = "emscripten", target_os = "fuchsia"))]
- unsafe fn reset_sigpipe() {}
-}
-
-#[cfg(target_os = "android")]
-pub use sys::android::signal;
-#[cfg(not(target_os = "android"))]
-pub use libc::signal;
-
-pub fn decode_error_kind(errno: i32) -> ErrorKind {
- match errno as libc::c_int {
- libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
- libc::ECONNRESET => ErrorKind::ConnectionReset,
- libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied,
- libc::EPIPE => ErrorKind::BrokenPipe,
- libc::ENOTCONN => ErrorKind::NotConnected,
- libc::ECONNABORTED => ErrorKind::ConnectionAborted,
- libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
- libc::EADDRINUSE => ErrorKind::AddrInUse,
- libc::ENOENT => ErrorKind::NotFound,
- libc::EINTR => ErrorKind::Interrupted,
- libc::EINVAL => ErrorKind::InvalidInput,
- libc::ETIMEDOUT => ErrorKind::TimedOut,
- libc::EEXIST => ErrorKind::AlreadyExists,
-
- // These two constants can have the same value on some systems,
- // but different values on others, so we can't use a match
- // clause
- x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
- ErrorKind::WouldBlock,
-
- _ => ErrorKind::Other,
- }
-}
-
-#[doc(hidden)]
-pub trait IsMinusOne {
- fn is_minus_one(&self) -> bool;
-}
-
-macro_rules! impl_is_minus_one {
- ($($t:ident)*) => ($(impl IsMinusOne for $t {
- fn is_minus_one(&self) -> bool {
- *self == -1
- }
- })*)
-}
-
-impl_is_minus_one! { i8 i16 i32 i64 isize }
-
-pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
- if t.is_minus_one() {
- Err(io::Error::last_os_error())
- } else {
- Ok(t)
- }
-}
-
-pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
- where T: IsMinusOne,
- F: FnMut() -> T
-{
- loop {
- match cvt(f()) {
- Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
- other => return other,
- }
- }
-}
-
-// On Unix-like platforms, libc::abort will unregister signal handlers
-// including the SIGABRT handler, preventing the abort from being blocked, and
-// fclose streams, with the side effect of flushing them so libc bufferred
-// output will be printed. Additionally the shell will generally print a more
-// understandable error message like "Abort trap" rather than "Illegal
-// instruction" that intrinsics::abort would cause, as intrinsics::abort is
-// implemented as an illegal instruction.
-pub unsafe fn abort_internal() -> ! {
- ::libc::abort()
-}
diff --git a/ctr-std/src/sys/unix/mutex.rs b/ctr-std/src/sys/unix/mutex.rs
deleted file mode 100644
index 1d447de..0000000
--- a/ctr-std/src/sys/unix/mutex.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use cell::UnsafeCell;
-use libc;
-use mem;
-
-pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t> }
-
-#[inline]
-pub unsafe fn raw(m: &Mutex) -> *mut libc::pthread_mutex_t {
- m.inner.get()
-}
-
-unsafe impl Send for Mutex {}
-unsafe impl Sync for Mutex {}
-
-#[allow(dead_code)] // sys isn't exported yet
-impl Mutex {
- pub const fn new() -> Mutex {
- // Might be moved to a different address, so it is better to avoid
- // initialization of potentially opaque OS data before it landed.
- // Be very careful using this newly constructed `Mutex`, reentrant
- // locking is undefined behavior until `init` is called!
- Mutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
- }
- #[inline]
- pub unsafe fn init(&mut self) {
- // Issue #33770
- //
- // A pthread mutex initialized with PTHREAD_MUTEX_INITIALIZER will have
- // a type of PTHREAD_MUTEX_DEFAULT, which has undefined behavior if you
- // try to re-lock it from the same thread when you already hold a lock.
- //
- // In practice, glibc takes advantage of this undefined behavior to
- // implement hardware lock elision, which uses hardware transactional
- // memory to avoid acquiring the lock. While a transaction is in
- // progress, the lock appears to be unlocked. This isn't a problem for
- // other threads since the transactional memory will abort if a conflict
- // is detected, however no abort is generated if re-locking from the
- // same thread.
- //
- // Since locking the same mutex twice will result in two aliasing &mut
- // references, we instead create the mutex with type
- // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to
- // re-lock it from the same thread, thus avoiding undefined behavior.
- let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
- let r = libc::pthread_mutexattr_init(&mut attr);
- debug_assert_eq!(r, 0);
- let r = libc::pthread_mutexattr_settype(&mut attr, libc::PTHREAD_MUTEX_NORMAL);
- debug_assert_eq!(r, 0);
- let r = libc::pthread_mutex_init(self.inner.get(), &attr);
- debug_assert_eq!(r, 0);
- let r = libc::pthread_mutexattr_destroy(&mut attr);
- debug_assert_eq!(r, 0);
- }
- #[inline]
- pub unsafe fn lock(&self) {
- let r = libc::pthread_mutex_lock(self.inner.get());
- debug_assert_eq!(r, 0);
- }
- #[inline]
- pub unsafe fn unlock(&self) {
- let r = libc::pthread_mutex_unlock(self.inner.get());
- debug_assert_eq!(r, 0);
- }
- #[inline]
- pub unsafe fn try_lock(&self) -> bool {
- libc::pthread_mutex_trylock(self.inner.get()) == 0
- }
- #[inline]
- #[cfg(not(target_os = "dragonfly"))]
- pub unsafe fn destroy(&self) {
- let r = libc::pthread_mutex_destroy(self.inner.get());
- debug_assert_eq!(r, 0);
- }
- #[inline]
- #[cfg(target_os = "dragonfly")]
- pub unsafe fn destroy(&self) {
- use libc;
- let r = libc::pthread_mutex_destroy(self.inner.get());
- // On DragonFly pthread_mutex_destroy() returns EINVAL if called on a
- // mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER.
- // Once it is used (locked/unlocked) or pthread_mutex_init() is called,
- // this behaviour no longer occurs.
- debug_assert!(r == 0 || r == libc::EINVAL);
- }
-}
-
-pub struct ReentrantMutex { inner: UnsafeCell<libc::pthread_mutex_t> }
-
-unsafe impl Send for ReentrantMutex {}
-unsafe impl Sync for ReentrantMutex {}
-
-impl ReentrantMutex {
- pub unsafe fn uninitialized() -> ReentrantMutex {
- ReentrantMutex { inner: mem::uninitialized() }
- }
-
- pub unsafe fn init(&mut self) {
- let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
- let result = libc::pthread_mutexattr_init(&mut attr as *mut _);
- debug_assert_eq!(result, 0);
- let result = libc::pthread_mutexattr_settype(&mut attr as *mut _,
- libc::PTHREAD_MUTEX_RECURSIVE);
- debug_assert_eq!(result, 0);
- let result = libc::pthread_mutex_init(self.inner.get(), &attr as *const _);
- debug_assert_eq!(result, 0);
- let result = libc::pthread_mutexattr_destroy(&mut attr as *mut _);
- debug_assert_eq!(result, 0);
- }
-
- pub unsafe fn lock(&self) {
- let result = libc::pthread_mutex_lock(self.inner.get());
- debug_assert_eq!(result, 0);
- }
-
- #[inline]
- pub unsafe fn try_lock(&self) -> bool {
- libc::pthread_mutex_trylock(self.inner.get()) == 0
- }
-
- pub unsafe fn unlock(&self) {
- let result = libc::pthread_mutex_unlock(self.inner.get());
- debug_assert_eq!(result, 0);
- }
-
- pub unsafe fn destroy(&self) {
- let result = libc::pthread_mutex_destroy(self.inner.get());
- debug_assert_eq!(result, 0);
- }
-}
diff --git a/ctr-std/src/sys/unix/net.rs b/ctr-std/src/sys/unix/net.rs
deleted file mode 100644
index 04d9f0b..0000000
--- a/ctr-std/src/sys/unix/net.rs
+++ /dev/null
@@ -1,424 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use ffi::CStr;
-use io;
-use libc::{self, c_int, c_void, size_t, sockaddr, socklen_t, EAI_SYSTEM, MSG_PEEK};
-use mem;
-use net::{SocketAddr, Shutdown};
-use str;
-use sys::fd::FileDesc;
-use sys_common::{AsInner, FromInner, IntoInner};
-use sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr};
-use time::{Duration, Instant};
-use cmp;
-
-pub use sys::{cvt, cvt_r};
-pub extern crate libc as netc;
-
-pub type wrlen_t = size_t;
-
-// See below for the usage of SOCK_CLOEXEC, but this constant is only defined on
-// Linux currently (e.g. support doesn't exist on other platforms). In order to
-// get name resolution to work and things to compile we just define a dummy
-// SOCK_CLOEXEC here for other platforms. Note that the dummy constant isn't
-// actually ever used (the blocks below are wrapped in `if cfg!` as well.
-#[cfg(target_os = "linux")]
-use libc::SOCK_CLOEXEC;
-#[cfg(not(target_os = "linux"))]
-const SOCK_CLOEXEC: c_int = 0;
-
-// Another conditional contant for name resolution: Macos et iOS use
-// SO_NOSIGPIPE as a setsockopt flag to disable SIGPIPE emission on socket.
-// Other platforms do otherwise.
-#[cfg(target_vendor = "apple")]
-use libc::SO_NOSIGPIPE;
-#[cfg(not(target_vendor = "apple"))]
-const SO_NOSIGPIPE: c_int = 0;
-
-pub struct Socket(FileDesc);
-
-pub fn init() {}
-
-pub fn cvt_gai(err: c_int) -> io::Result<()> {
- if err == 0 {
- return Ok(())
- }
-
- // We may need to trigger a glibc workaround. See on_resolver_failure() for details.
- on_resolver_failure();
-
- if err == EAI_SYSTEM {
- return Err(io::Error::last_os_error())
- }
-
- let detail = unsafe {
- str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap()
- .to_owned()
- };
- Err(io::Error::new(io::ErrorKind::Other,
- &format!("failed to lookup address information: {}",
- detail)[..]))
-}
-
-impl Socket {
- pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
- let fam = match *addr {
- SocketAddr::V4(..) => libc::AF_INET,
- SocketAddr::V6(..) => libc::AF_INET6,
- };
- Socket::new_raw(fam, ty)
- }
-
- pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
- unsafe {
- // On linux we first attempt to pass the SOCK_CLOEXEC flag to
- // atomically create the socket and set it as CLOEXEC. Support for
- // this option, however, was added in 2.6.27, and we still support
- // 2.6.18 as a kernel, so if the returned error is EINVAL we
- // fallthrough to the fallback.
- if cfg!(target_os = "linux") {
- match cvt(libc::socket(fam, ty | SOCK_CLOEXEC, 0)) {
- Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
- Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
- Err(e) => return Err(e),
- }
- }
-
- let fd = cvt(libc::socket(fam, ty, 0))?;
- let fd = FileDesc::new(fd);
- fd.set_cloexec()?;
- let socket = Socket(fd);
- if cfg!(target_vendor = "apple") {
- setsockopt(&socket, libc::SOL_SOCKET, SO_NOSIGPIPE, 1)?;
- }
- Ok(socket)
- }
- }
-
- pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> {
- unsafe {
- let mut fds = [0, 0];
-
- // Like above, see if we can set cloexec atomically
- if cfg!(target_os = "linux") {
- match cvt(libc::socketpair(fam, ty | SOCK_CLOEXEC, 0, fds.as_mut_ptr())) {
- Ok(_) => {
- return Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1]))));
- }
- Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {},
- Err(e) => return Err(e),
- }
- }
-
- cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?;
- let a = FileDesc::new(fds[0]);
- let b = FileDesc::new(fds[1]);
- a.set_cloexec()?;
- b.set_cloexec()?;
- Ok((Socket(a), Socket(b)))
- }
- }
-
- pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
- self.set_nonblocking(true)?;
- let r = unsafe {
- let (addrp, len) = addr.into_inner();
- cvt(libc::connect(self.0.raw(), addrp, len))
- };
- self.set_nonblocking(false)?;
-
- match r {
- Ok(_) => return Ok(()),
- // there's no ErrorKind for EINPROGRESS :(
- Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
- Err(e) => return Err(e),
- }
-
- let mut pollfd = libc::pollfd {
- fd: self.0.raw(),
- events: libc::POLLOUT,
- revents: 0,
- };
-
- if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
- return Err(io::Error::new(io::ErrorKind::InvalidInput,
- "cannot set a 0 duration timeout"));
- }
-
- let start = Instant::now();
-
- loop {
- let elapsed = start.elapsed();
- if elapsed >= timeout {
- return Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out"));
- }
-
- let timeout = timeout - elapsed;
- let mut timeout = timeout.as_secs()
- .saturating_mul(1_000)
- .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
- if timeout == 0 {
- timeout = 1;
- }
-
- let timeout = cmp::min(timeout, c_int::max_value() as u64) as c_int;
-
- match unsafe { libc::poll(&mut pollfd, 1, timeout) } {
- -1 => {
- let err = io::Error::last_os_error();
- if err.kind() != io::ErrorKind::Interrupted {
- return Err(err);
- }
- }
- 0 => {}
- _ => {
- // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
- // for POLLHUP rather than read readiness
- if pollfd.revents & libc::POLLHUP != 0 {
- let e = self.take_error()?
- .unwrap_or_else(|| {
- io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
- });
- return Err(e);
- }
-
- return Ok(());
- }
- }
- }
- }
-
- pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t)
- -> io::Result<Socket> {
- // Unfortunately the only known way right now to accept a socket and
- // atomically set the CLOEXEC flag is to use the `accept4` syscall on
- // Linux. This was added in 2.6.28, however, and because we support
- // 2.6.18 we must detect this support dynamically.
- if cfg!(target_os = "linux") {
- weak! {
- fn accept4(c_int, *mut sockaddr, *mut socklen_t, c_int) -> c_int
- }
- if let Some(accept) = accept4.get() {
- let res = cvt_r(|| unsafe {
- accept(self.0.raw(), storage, len, SOCK_CLOEXEC)
- });
- match res {
- Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
- Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {}
- Err(e) => return Err(e),
- }
- }
- }
-
- let fd = cvt_r(|| unsafe {
- libc::accept(self.0.raw(), storage, len)
- })?;
- let fd = FileDesc::new(fd);
- fd.set_cloexec()?;
- Ok(Socket(fd))
- }
-
- pub fn duplicate(&self) -> io::Result<Socket> {
- self.0.duplicate().map(Socket)
- }
-
- fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
- let ret = cvt(unsafe {
- libc::recv(self.0.raw(),
- buf.as_mut_ptr() as *mut c_void,
- buf.len(),
- flags)
- })?;
- Ok(ret as usize)
- }
-
- pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.recv_with_flags(buf, 0)
- }
-
- pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.recv_with_flags(buf, MSG_PEEK)
- }
-
- fn recv_from_with_flags(&self, buf: &mut [u8], flags: c_int)
- -> io::Result<(usize, SocketAddr)> {
- let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
- let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
-
- let n = cvt(unsafe {
- libc::recvfrom(self.0.raw(),
- buf.as_mut_ptr() as *mut c_void,
- buf.len(),
- flags,
- &mut storage as *mut _ as *mut _,
- &mut addrlen)
- })?;
- Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
- }
-
- pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- self.recv_from_with_flags(buf, 0)
- }
-
- pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- self.recv_from_with_flags(buf, MSG_PEEK)
- }
-
- pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
- self.0.write(buf)
- }
-
- pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> {
- let timeout = match dur {
- Some(dur) => {
- if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
- return Err(io::Error::new(io::ErrorKind::InvalidInput,
- "cannot set a 0 duration timeout"));
- }
-
- let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
- libc::time_t::max_value()
- } else {
- dur.as_secs() as libc::time_t
- };
- let mut timeout = libc::timeval {
- tv_sec: secs,
- tv_usec: (dur.subsec_nanos() / 1000) as libc::suseconds_t,
- };
- if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
- timeout.tv_usec = 1;
- }
- timeout
- }
- None => {
- libc::timeval {
- tv_sec: 0,
- tv_usec: 0,
- }
- }
- };
- setsockopt(self, libc::SOL_SOCKET, kind, timeout)
- }
-
- pub fn timeout(&self, kind: libc::c_int) -> io::Result<Option<Duration>> {
- let raw: libc::timeval = getsockopt(self, libc::SOL_SOCKET, kind)?;
- if raw.tv_sec == 0 && raw.tv_usec == 0 {
- Ok(None)
- } else {
- let sec = raw.tv_sec as u64;
- let nsec = (raw.tv_usec as u32) * 1000;
- Ok(Some(Duration::new(sec, nsec)))
- }
- }
-
- pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
- let how = match how {
- Shutdown::Write => libc::SHUT_WR,
- Shutdown::Read => libc::SHUT_RD,
- Shutdown::Both => libc::SHUT_RDWR,
- };
- cvt(unsafe { libc::shutdown(self.0.raw(), how) })?;
- Ok(())
- }
-
- pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
- setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int)
- }
-
- pub fn nodelay(&self) -> io::Result<bool> {
- let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY)?;
- Ok(raw != 0)
- }
-
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- let mut nonblocking = nonblocking as libc::c_int;
- cvt(unsafe { libc::ioctl(*self.as_inner(), libc::FIONBIO, &mut nonblocking) }).map(|_| ())
- }
-
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
- if raw == 0 {
- Ok(None)
- } else {
- Ok(Some(io::Error::from_raw_os_error(raw as i32)))
- }
- }
-}
-
-impl AsInner<c_int> for Socket {
- fn as_inner(&self) -> &c_int { self.0.as_inner() }
-}
-
-impl FromInner<c_int> for Socket {
- fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) }
-}
-
-impl IntoInner<c_int> for Socket {
- fn into_inner(self) -> c_int { self.0.into_raw() }
-}
-
-// In versions of glibc prior to 2.26, there's a bug where the DNS resolver
-// will cache the contents of /etc/resolv.conf, so changes to that file on disk
-// can be ignored by a long-running program. That can break DNS lookups on e.g.
-// laptops where the network comes and goes. See
-// https://sourceware.org/bugzilla/show_bug.cgi?id=984. Note however that some
-// distros including Debian have patched glibc to fix this for a long time.
-//
-// A workaround for this bug is to call the res_init libc function, to clear
-// the cached configs. Unfortunately, while we believe glibc's implementation
-// of res_init is thread-safe, we know that other implementations are not
-// (https://github.com/rust-lang/rust/issues/43592). Code here in libstd could
-// try to synchronize its res_init calls with a Mutex, but that wouldn't
-// protect programs that call into libc in other ways. So instead of calling
-// res_init unconditionally, we call it only when we detect we're linking
-// against glibc version < 2.26. (That is, when we both know its needed and
-// believe it's thread-safe).
-#[cfg(target_env = "gnu")]
-fn on_resolver_failure() {
- use sys;
-
- // If the version fails to parse, we treat it the same as "not glibc".
- if let Some(version) = sys::os::glibc_version() {
- if version < (2, 26) {
- unsafe { libc::res_init() };
- }
- }
-}
-
-#[cfg(not(target_env = "gnu"))]
-fn on_resolver_failure() {}
-
-#[cfg(all(test, taget_env = "gnu"))]
-mod test {
- use super::*;
-
- #[test]
- fn test_res_init() {
- // This mostly just tests that the weak linkage doesn't panic wildly...
- res_init_if_glibc_before_2_26().unwrap();
- }
-
- #[test]
- fn test_parse_glibc_version() {
- let cases = [
- ("0.0", Some((0, 0))),
- ("01.+2", Some((1, 2))),
- ("3.4.5.six", Some((3, 4))),
- ("1", None),
- ("1.-2", None),
- ("1.foo", None),
- ("foo.1", None),
- ];
- for &(version_str, parsed) in cases.iter() {
- assert_eq!(parsed, parse_glibc_version(version_str));
- }
- }
-}
diff --git a/ctr-std/src/sys/unix/os.rs b/ctr-std/src/sys/unix/os.rs
deleted file mode 100644
index f8f0bbd..0000000
--- a/ctr-std/src/sys/unix/os.rs
+++ /dev/null
@@ -1,571 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Implementation of `std::os` functionality for unix systems
-
-#![allow(unused_imports)] // lots of cfg code here
-
-use os::unix::prelude::*;
-
-use error::Error as StdError;
-use ffi::{CString, CStr, OsString, OsStr};
-use fmt;
-use io;
-use iter;
-use libc::{self, c_int, c_char, c_void};
-use marker::PhantomData;
-use mem;
-use memchr;
-use path::{self, PathBuf};
-use ptr;
-use slice;
-use str;
-use sys_common::mutex::Mutex;
-use sys::cvt;
-use sys::fd;
-use vec;
-
-const TMPBUF_SZ: usize = 128;
-// We never call `ENV_LOCK.init()`, so it is UB to attempt to
-// acquire this mutex reentrantly!
-static ENV_LOCK: Mutex = Mutex::new();
-
-
-extern {
- #[cfg(not(target_os = "dragonfly"))]
- #[cfg_attr(any(target_os = "linux",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "l4re"),
- link_name = "__errno_location")]
- #[cfg_attr(any(target_os = "bitrig",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "android",
- target_os = "hermit",
- target_env = "newlib"),
- link_name = "__errno")]
- #[cfg_attr(target_os = "solaris", link_name = "___errno")]
- #[cfg_attr(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd"),
- link_name = "__error")]
- #[cfg_attr(target_os = "haiku", link_name = "_errnop")]
- fn errno_location() -> *mut c_int;
-}
-
-/// Returns the platform-specific value of errno
-#[cfg(not(target_os = "dragonfly"))]
-pub fn errno() -> i32 {
- unsafe {
- (*errno_location()) as i32
- }
-}
-
-/// Sets the platform-specific value of errno
-#[cfg(any(target_os = "solaris", target_os = "fuchsia"))] // only needed for readdir so far
-pub fn set_errno(e: i32) {
- unsafe {
- *errno_location() = e as c_int
- }
-}
-
-#[cfg(target_os = "dragonfly")]
-pub fn errno() -> i32 {
- extern {
- #[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 {
- 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;
- }
-
- let mut buf = [0 as c_char; TMPBUF_SZ];
-
- let p = buf.as_mut_ptr();
- unsafe {
- if strerror_r(errno as c_int, p, buf.len()) < 0 {
- panic!("strerror_r failure");
- }
-
- let p = p as *const _;
- str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
- }
-}
-
-pub fn getcwd() -> io::Result<PathBuf> {
- let mut buf = Vec::with_capacity(512);
- loop {
- unsafe {
- let ptr = buf.as_mut_ptr() as *mut libc::c_char;
- if !libc::getcwd(ptr, buf.capacity()).is_null() {
- let len = CStr::from_ptr(buf.as_ptr() as *const libc::c_char).to_bytes().len();
- buf.set_len(len);
- buf.shrink_to_fit();
- return Ok(PathBuf::from(OsString::from_vec(buf)));
- } else {
- let error = io::Error::last_os_error();
- if error.raw_os_error() != Some(libc::ERANGE) {
- return Err(error);
- }
- }
-
- // Trigger the internal buffer resizing logic of `Vec` by requiring
- // more space than the current capacity.
- let cap = buf.capacity();
- buf.set_len(cap);
- buf.reserve(1);
- }
- }
-}
-
-pub fn chdir(p: &path::Path) -> io::Result<()> {
- let p: &OsStr = p.as_ref();
- let p = CString::new(p.as_bytes())?;
- unsafe {
- match libc::chdir(p.as_ptr()) == (0 as c_int) {
- true => Ok(()),
- false => Err(io::Error::last_os_error()),
- }
- }
-}
-
-pub struct SplitPaths<'a> {
- iter: iter::Map<slice::Split<'a, u8, fn(&u8) -> bool>,
- fn(&'a [u8]) -> PathBuf>,
-}
-
-pub fn split_paths(unparsed: &OsStr) -> SplitPaths {
- fn bytes_to_path(b: &[u8]) -> PathBuf {
- PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
- }
- fn is_colon(b: &u8) -> bool { *b == b':' }
- let unparsed = unparsed.as_bytes();
- SplitPaths {
- iter: unparsed.split(is_colon as fn(&u8) -> bool)
- .map(bytes_to_path as fn(&[u8]) -> PathBuf)
- }
-}
-
-impl<'a> Iterator for SplitPaths<'a> {
- type Item = PathBuf;
- fn next(&mut self) -> Option<PathBuf> { self.iter.next() }
- fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
-}
-
-#[derive(Debug)]
-pub struct JoinPathsError;
-
-pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
- where I: Iterator<Item=T>, T: AsRef<OsStr>
-{
- let mut joined = Vec::new();
- let sep = b':';
-
- for (i, path) in paths.enumerate() {
- let path = path.as_ref().as_bytes();
- if i > 0 { joined.push(sep) }
- if path.contains(&sep) {
- return Err(JoinPathsError)
- }
- joined.extend_from_slice(path);
- }
- Ok(OsStringExt::from_vec(joined))
-}
-
-impl fmt::Display for JoinPathsError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- "path segment contains separator `:`".fmt(f)
- }
-}
-
-impl StdError for JoinPathsError {
- fn description(&self) -> &str { "failed to join paths" }
-}
-
-#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
-pub fn current_exe() -> io::Result<PathBuf> {
- unsafe {
- let mut mib = [libc::CTL_KERN as c_int,
- libc::KERN_PROC as c_int,
- libc::KERN_PROC_PATHNAME as c_int,
- -1 as c_int];
- let mut sz = 0;
- cvt(libc::sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint,
- ptr::null_mut(), &mut sz, ptr::null_mut(), 0))?;
- if sz == 0 {
- return Err(io::Error::last_os_error())
- }
- let mut v: Vec<u8> = Vec::with_capacity(sz);
- cvt(libc::sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint,
- v.as_mut_ptr() as *mut libc::c_void, &mut sz,
- ptr::null_mut(), 0))?;
- if sz == 0 {
- return Err(io::Error::last_os_error());
- }
- v.set_len(sz - 1); // chop off trailing NUL
- Ok(PathBuf::from(OsString::from_vec(v)))
- }
-}
-
-#[cfg(target_os = "netbsd")]
-pub fn current_exe() -> io::Result<PathBuf> {
- fn sysctl() -> io::Result<PathBuf> {
- unsafe {
- let mib = [libc::CTL_KERN, libc::KERN_PROC_ARGS, -1, libc::KERN_PROC_PATHNAME];
- let mut path_len: usize = 0;
- cvt(libc::sysctl(mib.as_ptr(), mib.len() as ::libc::c_uint,
- ptr::null_mut(), &mut path_len,
- ptr::null(), 0))?;
- if path_len <= 1 {
- return Err(io::Error::new(io::ErrorKind::Other,
- "KERN_PROC_PATHNAME sysctl returned zero-length string"))
- }
- let mut path: Vec<u8> = Vec::with_capacity(path_len);
- cvt(libc::sysctl(mib.as_ptr(), mib.len() as ::libc::c_uint,
- path.as_ptr() as *mut libc::c_void, &mut path_len,
- ptr::null(), 0))?;
- path.set_len(path_len - 1); // chop off NUL
- Ok(PathBuf::from(OsString::from_vec(path)))
- }
- }
- fn procfs() -> io::Result<PathBuf> {
- let curproc_exe = path::Path::new("/proc/curproc/exe");
- if curproc_exe.is_file() {
- return ::fs::read_link(curproc_exe);
- }
- Err(io::Error::new(io::ErrorKind::Other,
- "/proc/curproc/exe doesn't point to regular file."))
- }
- sysctl().or_else(|_| procfs())
-}
-
-#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
-pub fn current_exe() -> io::Result<PathBuf> {
- unsafe {
- let mut mib = [libc::CTL_KERN,
- libc::KERN_PROC_ARGS,
- libc::getpid(),
- libc::KERN_PROC_ARGV];
- let mib = mib.as_mut_ptr();
- let mut argv_len = 0;
- cvt(libc::sysctl(mib, 4, ptr::null_mut(), &mut argv_len,
- ptr::null_mut(), 0))?;
- let mut argv = Vec::<*const libc::c_char>::with_capacity(argv_len as usize);
- cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _,
- &mut argv_len, ptr::null_mut(), 0))?;
- argv.set_len(argv_len as usize);
- if argv[0].is_null() {
- return Err(io::Error::new(io::ErrorKind::Other,
- "no current exe available"))
- }
- let argv0 = CStr::from_ptr(argv[0]).to_bytes();
- if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') {
- ::fs::canonicalize(OsStr::from_bytes(argv0))
- } else {
- Ok(PathBuf::from(OsStr::from_bytes(argv0)))
- }
- }
-}
-
-#[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))]
-pub fn current_exe() -> io::Result<PathBuf> {
- let selfexe = PathBuf::from("/proc/self/exe");
- if selfexe.exists() {
- ::fs::read_link(selfexe)
- } else {
- Err(io::Error::new(io::ErrorKind::Other, "no /proc/self/exe available. Is /proc mounted?"))
- }
-}
-
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-pub fn current_exe() -> io::Result<PathBuf> {
- extern {
- fn _NSGetExecutablePath(buf: *mut libc::c_char,
- bufsize: *mut u32) -> libc::c_int;
- }
- unsafe {
- let mut sz: u32 = 0;
- _NSGetExecutablePath(ptr::null_mut(), &mut sz);
- if sz == 0 { return Err(io::Error::last_os_error()); }
- let mut v: Vec<u8> = Vec::with_capacity(sz as usize);
- let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
- if err != 0 { return Err(io::Error::last_os_error()); }
- v.set_len(sz as usize - 1); // chop off trailing NUL
- Ok(PathBuf::from(OsString::from_vec(v)))
- }
-}
-
-#[cfg(any(target_os = "solaris"))]
-pub fn current_exe() -> io::Result<PathBuf> {
- extern {
- fn getexecname() -> *const c_char;
- }
- unsafe {
- let path = getexecname();
- if path.is_null() {
- Err(io::Error::last_os_error())
- } else {
- let filename = CStr::from_ptr(path).to_bytes();
- let path = PathBuf::from(<OsStr as OsStrExt>::from_bytes(filename));
-
- // Prepend a current working directory to the path if
- // it doesn't contain an absolute pathname.
- if filename[0] == b'/' {
- Ok(path)
- } else {
- getcwd().map(|cwd| cwd.join(path))
- }
- }
- }
-}
-
-#[cfg(target_os = "haiku")]
-pub fn current_exe() -> io::Result<PathBuf> {
- // Use Haiku's image info functions
- #[repr(C)]
- struct image_info {
- id: i32,
- type_: i32,
- sequence: i32,
- init_order: i32,
- init_routine: *mut libc::c_void, // function pointer
- term_routine: *mut libc::c_void, // function pointer
- device: libc::dev_t,
- node: libc::ino_t,
- name: [libc::c_char; 1024], // MAXPATHLEN
- text: *mut libc::c_void,
- data: *mut libc::c_void,
- text_size: i32,
- data_size: i32,
- api_version: i32,
- abi: i32,
- }
-
- unsafe {
- extern {
- fn _get_next_image_info(team_id: i32, cookie: *mut i32,
- info: *mut image_info, size: i32) -> i32;
- }
-
- let mut info: image_info = mem::zeroed();
- let mut cookie: i32 = 0;
- // the executable can be found at team id 0
- let result = _get_next_image_info(0, &mut cookie, &mut info,
- mem::size_of::<image_info>() as i32);
- if result != 0 {
- use io::ErrorKind;
- Err(io::Error::new(ErrorKind::Other, "Error getting executable path"))
- } else {
- let name = CStr::from_ptr(info.name.as_ptr()).to_bytes();
- Ok(PathBuf::from(OsStr::from_bytes(name)))
- }
- }
-}
-
-#[cfg(any(target_os = "fuchsia", target_os = "l4re", target_os = "hermit"))]
-pub fn current_exe() -> io::Result<PathBuf> {
- use io::ErrorKind;
- Err(io::Error::new(ErrorKind::Other, "Not yet implemented!"))
-}
-
-pub struct Env {
- iter: vec::IntoIter<(OsString, OsString)>,
- _dont_send_or_sync_me: PhantomData<*mut ()>,
-}
-
-impl Iterator for Env {
- type Item = (OsString, OsString);
- fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() }
- fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
-}
-
-#[cfg(target_os = "macos")]
-pub unsafe fn environ() -> *mut *const *const c_char {
- extern { fn _NSGetEnviron() -> *mut *const *const c_char; }
- _NSGetEnviron()
-}
-
-#[cfg(not(target_os = "macos"))]
-pub unsafe fn environ() -> *mut *const *const c_char {
- extern { static mut environ: *const *const c_char; }
- &mut environ
-}
-
-/// Returns a vector of (variable, value) byte-vector pairs for all the
-/// environment variables of the current process.
-pub fn env() -> Env {
- unsafe {
- let _guard = ENV_LOCK.lock();
- let mut environ = *environ();
- let mut result = Vec::new();
- while environ != ptr::null() && *environ != ptr::null() {
- if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
- result.push(key_value);
- }
- environ = environ.offset(1);
- }
- return Env {
- iter: result.into_iter(),
- _dont_send_or_sync_me: PhantomData,
- }
- }
-
- fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
- // Strategy (copied from glibc): Variable name and value are separated
- // by an ASCII equals sign '='. Since a variable name must not be
- // empty, allow variable names starting with an equals sign. Skip all
- // malformed lines.
- if input.is_empty() {
- return None;
- }
- let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
- pos.map(|p| (
- OsStringExt::from_vec(input[..p].to_vec()),
- OsStringExt::from_vec(input[p+1..].to_vec()),
- ))
- }
-}
-
-pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
- // environment variables with a nul byte can't be set, so their value is
- // always None as well
- let k = CString::new(k.as_bytes())?;
- unsafe {
- let _guard = ENV_LOCK.lock();
- let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
- let ret = if s.is_null() {
- None
- } else {
- Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
- };
- Ok(ret)
- }
-}
-
-pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
- let k = CString::new(k.as_bytes())?;
- let v = CString::new(v.as_bytes())?;
-
- unsafe {
- let _guard = ENV_LOCK.lock();
- cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ())
- }
-}
-
-pub fn unsetenv(n: &OsStr) -> io::Result<()> {
- let nbuf = CString::new(n.as_bytes())?;
-
- unsafe {
- let _guard = ENV_LOCK.lock();
- cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ())
- }
-}
-
-pub fn page_size() -> usize {
- unsafe {
- libc::sysconf(libc::_SC_PAGESIZE) as usize
- }
-}
-
-pub fn temp_dir() -> PathBuf {
- ::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| {
- if cfg!(target_os = "android") {
- PathBuf::from("/data/local/tmp")
- } else {
- PathBuf::from("/tmp")
- }
- })
-}
-
-pub fn home_dir() -> Option<PathBuf> {
- return ::env::var_os("HOME").or_else(|| unsafe {
- fallback()
- }).map(PathBuf::from);
-
- #[cfg(any(target_os = "android",
- target_os = "ios",
- target_os = "emscripten"))]
- unsafe fn fallback() -> Option<OsString> { None }
- #[cfg(not(any(target_os = "android",
- target_os = "ios",
- target_os = "emscripten")))]
- unsafe fn fallback() -> Option<OsString> {
- let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
- n if n < 0 => 512 as usize,
- n => n as usize,
- };
- let mut buf = Vec::with_capacity(amt);
- let mut passwd: libc::passwd = mem::zeroed();
- let mut result = ptr::null_mut();
- match libc::getpwuid_r(libc::getuid(), &mut passwd, buf.as_mut_ptr(),
- buf.capacity(), &mut result) {
- 0 if !result.is_null() => {
- let ptr = passwd.pw_dir as *const _;
- let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
- Some(OsStringExt::from_vec(bytes))
- },
- _ => None,
- }
- }
-}
-
-pub fn exit(code: i32) -> ! {
- unsafe { libc::exit(code as c_int) }
-}
-
-pub fn getpid() -> u32 {
- unsafe { libc::getpid() as u32 }
-}
-
-pub fn getppid() -> u32 {
- unsafe { libc::getppid() as u32 }
-}
-
-#[cfg(target_env = "gnu")]
-pub fn glibc_version() -> Option<(usize, usize)> {
- if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) {
- parse_glibc_version(version_str)
- } else {
- None
- }
-}
-
-#[cfg(target_env = "gnu")]
-fn glibc_version_cstr() -> Option<&'static CStr> {
- weak! {
- fn gnu_get_libc_version() -> *const libc::c_char
- }
- if let Some(f) = gnu_get_libc_version.get() {
- unsafe { Some(CStr::from_ptr(f())) }
- } else {
- None
- }
-}
-
-// Returns Some((major, minor)) if the string is a valid "x.y" version,
-// ignoring any extra dot-separated parts. Otherwise return None.
-#[cfg(target_env = "gnu")]
-fn parse_glibc_version(version: &str) -> Option<(usize, usize)> {
- let mut parsed_ints = version.split('.').map(str::parse::<usize>).fuse();
- match (parsed_ints.next(), parsed_ints.next()) {
- (Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)),
- _ => None
- }
-}
diff --git a/ctr-std/src/sys/unix/os_str.rs b/ctr-std/src/sys/unix/os_str.rs
deleted file mode 100644
index 01c0fb8..0000000
--- a/ctr-std/src/sys/unix/os_str.rs
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/// The underlying OsString/OsStr implementation on Unix systems: just
-/// a `Vec<u8>`/`[u8]`.
-
-use borrow::Cow;
-use fmt;
-use str;
-use mem;
-use rc::Rc;
-use sync::Arc;
-use sys_common::{AsInner, IntoInner};
-use sys_common::bytestring::debug_fmt_bytestring;
-use core::str::lossy::Utf8Lossy;
-
-#[derive(Clone, Hash)]
-pub struct Buf {
- pub inner: Vec<u8>
-}
-
-pub struct Slice {
- pub inner: [u8]
-}
-
-impl fmt::Debug for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- debug_fmt_bytestring(&self.inner, formatter)
- }
-}
-
-impl fmt::Display for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
- }
-}
-
-impl fmt::Debug for Buf {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Debug::fmt(self.as_slice(), formatter)
- }
-}
-
-impl fmt::Display for Buf {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self.as_slice(), formatter)
- }
-}
-
-impl IntoInner<Vec<u8>> for Buf {
- fn into_inner(self) -> Vec<u8> {
- self.inner
- }
-}
-
-impl AsInner<[u8]> for Buf {
- fn as_inner(&self) -> &[u8] {
- &self.inner
- }
-}
-
-
-impl Buf {
- pub fn from_string(s: String) -> Buf {
- Buf { inner: s.into_bytes() }
- }
-
- #[inline]
- pub fn with_capacity(capacity: usize) -> Buf {
- Buf {
- inner: Vec::with_capacity(capacity)
- }
- }
-
- #[inline]
- pub fn clear(&mut self) {
- self.inner.clear()
- }
-
- #[inline]
- pub fn capacity(&self) -> usize {
- self.inner.capacity()
- }
-
- #[inline]
- pub fn reserve(&mut self, additional: usize) {
- self.inner.reserve(additional)
- }
-
- #[inline]
- pub fn reserve_exact(&mut self, additional: usize) {
- self.inner.reserve_exact(additional)
- }
-
- #[inline]
- pub fn shrink_to_fit(&mut self) {
- self.inner.shrink_to_fit()
- }
-
- #[inline]
- pub fn shrink_to(&mut self, min_capacity: usize) {
- self.inner.shrink_to(min_capacity)
- }
-
- pub fn as_slice(&self) -> &Slice {
- unsafe { mem::transmute(&*self.inner) }
- }
-
- pub fn into_string(self) -> Result<String, Buf> {
- String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() } )
- }
-
- pub fn push_slice(&mut self, s: &Slice) {
- self.inner.extend_from_slice(&s.inner)
- }
-
- #[inline]
- pub fn into_box(self) -> Box<Slice> {
- unsafe { mem::transmute(self.inner.into_boxed_slice()) }
- }
-
- #[inline]
- pub fn from_box(boxed: Box<Slice>) -> Buf {
- let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
- Buf { inner: inner.into_vec() }
- }
-
- #[inline]
- pub fn into_arc(&self) -> Arc<Slice> {
- self.as_slice().into_arc()
- }
-
- #[inline]
- pub fn into_rc(&self) -> Rc<Slice> {
- self.as_slice().into_rc()
- }
-}
-
-impl Slice {
- fn from_u8_slice(s: &[u8]) -> &Slice {
- unsafe { mem::transmute(s) }
- }
-
- pub fn from_str(s: &str) -> &Slice {
- Slice::from_u8_slice(s.as_bytes())
- }
-
- pub fn to_str(&self) -> Option<&str> {
- str::from_utf8(&self.inner).ok()
- }
-
- pub fn to_string_lossy(&self) -> Cow<str> {
- String::from_utf8_lossy(&self.inner)
- }
-
- pub fn to_owned(&self) -> Buf {
- Buf { inner: self.inner.to_vec() }
- }
-
- #[inline]
- pub fn into_box(&self) -> Box<Slice> {
- let boxed: Box<[u8]> = self.inner.into();
- unsafe { mem::transmute(boxed) }
- }
-
- pub fn empty_box() -> Box<Slice> {
- let boxed: Box<[u8]> = Default::default();
- unsafe { mem::transmute(boxed) }
- }
-
- #[inline]
- pub fn into_arc(&self) -> Arc<Slice> {
- let arc: Arc<[u8]> = Arc::from(&self.inner);
- unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
- }
-
- #[inline]
- pub fn into_rc(&self) -> Rc<Slice> {
- let rc: Rc<[u8]> = Rc::from(&self.inner);
- unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
- }
-}
diff --git a/ctr-std/src/sys/unix/path.rs b/ctr-std/src/sys/unix/path.rs
deleted file mode 100644
index bf9af7a..0000000
--- a/ctr-std/src/sys/unix/path.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use path::Prefix;
-use ffi::OsStr;
-
-#[inline]
-pub fn is_sep_byte(b: u8) -> bool {
- b == b'/'
-}
-
-#[inline]
-pub fn is_verbatim_sep(b: u8) -> bool {
- b == b'/'
-}
-
-pub fn parse_prefix(_: &OsStr) -> Option<Prefix> {
- None
-}
-
-pub const MAIN_SEP_STR: &'static str = "/";
-pub const MAIN_SEP: char = '/';
diff --git a/ctr-std/src/sys/unix/pipe.rs b/ctr-std/src/sys/unix/pipe.rs
deleted file mode 100644
index 0a5dccd..0000000
--- a/ctr-std/src/sys/unix/pipe.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use io;
-use libc::{self, c_int};
-use mem;
-use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
-use sys::fd::FileDesc;
-use sys::{cvt, cvt_r};
-
-////////////////////////////////////////////////////////////////////////////////
-// Anonymous pipes
-////////////////////////////////////////////////////////////////////////////////
-
-pub struct AnonPipe(FileDesc);
-
-pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
- weak! { fn pipe2(*mut c_int, c_int) -> c_int }
- static INVALID: AtomicBool = ATOMIC_BOOL_INIT;
-
- let mut fds = [0; 2];
-
- // Unfortunately the only known way right now to create atomically set the
- // CLOEXEC flag is to use the `pipe2` syscall on Linux. This was added in
- // 2.6.27, however, and because we support 2.6.18 we must detect this
- // support dynamically.
- if cfg!(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd")) &&
- !INVALID.load(Ordering::SeqCst)
- {
-
- if let Some(pipe) = pipe2.get() {
- // Note that despite calling a glibc function here we may still
- // get ENOSYS. Glibc has `pipe2` since 2.9 and doesn't try to
- // emulate on older kernels, so if you happen to be running on
- // an older kernel you may see `pipe2` as a symbol but still not
- // see the syscall.
- match cvt(unsafe { pipe(fds.as_mut_ptr(), libc::O_CLOEXEC) }) {
- Ok(_) => {
- return Ok((AnonPipe(FileDesc::new(fds[0])),
- AnonPipe(FileDesc::new(fds[1]))));
- }
- Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {
- INVALID.store(true, Ordering::SeqCst);
- }
- Err(e) => return Err(e),
- }
- }
- }
- cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?;
-
- let fd0 = FileDesc::new(fds[0]);
- let fd1 = FileDesc::new(fds[1]);
- fd0.set_cloexec()?;
- fd1.set_cloexec()?;
- Ok((AnonPipe(fd0), AnonPipe(fd1)))
-}
-
-impl AnonPipe {
- pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.0.read(buf)
- }
-
- pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
- self.0.write(buf)
- }
-
- pub fn fd(&self) -> &FileDesc { &self.0 }
- pub fn into_fd(self) -> FileDesc { self.0 }
-}
-
-pub fn read2(p1: AnonPipe,
- v1: &mut Vec<u8>,
- p2: AnonPipe,
- v2: &mut Vec<u8>) -> io::Result<()> {
-
- // Set both pipes into nonblocking mode as we're gonna be reading from both
- // in the `select` loop below, and we wouldn't want one to block the other!
- let p1 = p1.into_fd();
- let p2 = p2.into_fd();
- p1.set_nonblocking(true)?;
- p2.set_nonblocking(true)?;
-
- let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
- fds[0].fd = p1.raw();
- fds[0].events = libc::POLLIN;
- fds[1].fd = p2.raw();
- fds[1].events = libc::POLLIN;
- loop {
- // wait for either pipe to become readable using `poll`
- cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?;
-
- if fds[0].revents != 0 && read(&p1, v1)? {
- p2.set_nonblocking(false)?;
- return p2.read_to_end(v2).map(|_| ());
- }
- if fds[1].revents != 0 && read(&p2, v2)? {
- p1.set_nonblocking(false)?;
- return p1.read_to_end(v1).map(|_| ());
- }
- }
-
- // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
- // EAGAIN. If we hit EOF, then this will happen because the underlying
- // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
- // this case we flip the other fd back into blocking mode and read
- // whatever's leftover on that file descriptor.
- fn read(fd: &FileDesc, dst: &mut Vec<u8>) -> Result<bool, io::Error> {
- match fd.read_to_end(dst) {
- Ok(_) => Ok(true),
- Err(e) => {
- if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
- e.raw_os_error() == Some(libc::EAGAIN) {
- Ok(false)
- } else {
- Err(e)
- }
- }
- }
- }
-}
diff --git a/ctr-std/src/sys/unix/process/mod.rs b/ctr-std/src/sys/unix/process/mod.rs
deleted file mode 100644
index d8ac26c..0000000
--- a/ctr-std/src/sys/unix/process/mod.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub use self::process_common::{Command, ExitStatus, ExitCode, Stdio, StdioPipes};
-pub use self::process_inner::Process;
-
-mod process_common;
-#[cfg(not(target_os = "fuchsia"))]
-#[path = "process_unix.rs"]
-mod process_inner;
-#[cfg(target_os = "fuchsia")]
-#[path = "process_fuchsia.rs"]
-mod process_inner;
-#[cfg(target_os = "fuchsia")]
-mod zircon;
diff --git a/ctr-std/src/sys/unix/process/process_common.rs b/ctr-std/src/sys/unix/process/process_common.rs
deleted file mode 100644
index 77f125f..0000000
--- a/ctr-std/src/sys/unix/process/process_common.rs
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use os::unix::prelude::*;
-
-use ffi::{OsString, OsStr, CString, CStr};
-use fmt;
-use io;
-use libc::{self, c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
-use ptr;
-use sys::fd::FileDesc;
-use sys::fs::{File, OpenOptions};
-use sys::pipe::{self, AnonPipe};
-use sys_common::process::{CommandEnv, DefaultEnvKey};
-use collections::BTreeMap;
-
-////////////////////////////////////////////////////////////////////////////////
-// Command
-////////////////////////////////////////////////////////////////////////////////
-
-pub struct Command {
- // Currently we try hard to ensure that the call to `.exec()` doesn't
- // actually allocate any memory. While many platforms try to ensure that
- // memory allocation works after a fork in a multithreaded process, it's
- // been observed to be buggy and somewhat unreliable, so we do our best to
- // just not do it at all!
- //
- // Along those lines, the `argv` and `envp` raw pointers here are exactly
- // what's gonna get passed to `execvp`. The `argv` array starts with the
- // `program` and ends with a NULL, and the `envp` pointer, if present, is
- // also null-terminated.
- //
- // Right now we don't support removing arguments, so there's no much fancy
- // support there, but we support adding and removing environment variables,
- // so a side table is used to track where in the `envp` array each key is
- // located. Whenever we add a key we update it in place if it's already
- // present, and whenever we remove a key we update the locations of all
- // other keys.
- program: CString,
- args: Vec<CString>,
- argv: Argv,
- env: CommandEnv<DefaultEnvKey>,
-
- cwd: Option<CString>,
- uid: Option<uid_t>,
- gid: Option<gid_t>,
- saw_nul: bool,
- closures: Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>>,
- stdin: Option<Stdio>,
- stdout: Option<Stdio>,
- stderr: Option<Stdio>,
-}
-
-// Create a new type for argv, so that we can make it `Send`
-struct Argv(Vec<*const c_char>);
-
-// It is safe to make Argv Send, because it contains pointers to memory owned by `Command.args`
-unsafe impl Send for Argv {}
-
-// 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>,
-}
-
-// passed to do_exec() with configuration of what the child stdio should look
-// like
-pub struct ChildPipes {
- pub stdin: ChildStdio,
- pub stdout: ChildStdio,
- pub stderr: ChildStdio,
-}
-
-pub enum ChildStdio {
- Inherit,
- Explicit(c_int),
- Owned(FileDesc),
-}
-
-pub enum Stdio {
- Inherit,
- Null,
- MakePipe,
- Fd(FileDesc),
-}
-
-impl Command {
- pub fn new(program: &OsStr) -> Command {
- let mut saw_nul = false;
- let program = os2c(program, &mut saw_nul);
- Command {
- argv: Argv(vec![program.as_ptr(), ptr::null()]),
- program,
- args: Vec::new(),
- env: Default::default(),
- cwd: None,
- uid: None,
- gid: None,
- saw_nul,
- closures: Vec::new(),
- stdin: None,
- stdout: None,
- stderr: None,
- }
- }
-
- pub fn arg(&mut self, arg: &OsStr) {
- // Overwrite the trailing NULL pointer in `argv` and then add a new null
- // pointer.
- let arg = os2c(arg, &mut self.saw_nul);
- self.argv.0[self.args.len() + 1] = arg.as_ptr();
- self.argv.0.push(ptr::null());
-
- // Also make sure we keep track of the owned value to schedule a
- // destructor for this memory.
- self.args.push(arg);
- }
-
- pub fn cwd(&mut self, dir: &OsStr) {
- self.cwd = Some(os2c(dir, &mut self.saw_nul));
- }
- pub fn uid(&mut self, id: uid_t) {
- self.uid = Some(id);
- }
- pub fn gid(&mut self, id: gid_t) {
- self.gid = Some(id);
- }
-
- pub fn saw_nul(&self) -> bool {
- self.saw_nul
- }
- pub fn get_argv(&self) -> &Vec<*const c_char> {
- &self.argv.0
- }
-
- #[allow(dead_code)]
- pub fn get_cwd(&self) -> &Option<CString> {
- &self.cwd
- }
- #[allow(dead_code)]
- pub fn get_uid(&self) -> Option<uid_t> {
- self.uid
- }
- #[allow(dead_code)]
- pub fn get_gid(&self) -> Option<gid_t> {
- self.gid
- }
-
- pub fn get_closures(&mut self) -> &mut Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>> {
- &mut self.closures
- }
-
- pub fn before_exec(&mut self,
- f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) {
- self.closures.push(f);
- }
-
- pub fn stdin(&mut self, stdin: Stdio) {
- self.stdin = Some(stdin);
- }
-
- pub fn stdout(&mut self, stdout: Stdio) {
- self.stdout = Some(stdout);
- }
-
- pub fn stderr(&mut self, stderr: Stdio) {
- self.stderr = Some(stderr);
- }
-
- pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
- &mut self.env
- }
-
- pub fn capture_env(&mut self) -> Option<CStringArray> {
- let maybe_env = self.env.capture_if_changed();
- maybe_env.map(|env| construct_envp(env, &mut self.saw_nul))
- }
- #[allow(dead_code)]
- pub fn env_saw_path(&self) -> bool {
- self.env.have_changed_path()
- }
-
- pub fn setup_io(&self, default: Stdio, needs_stdin: bool)
- -> io::Result<(StdioPipes, ChildPipes)> {
- let null = Stdio::Null;
- let default_stdin = if needs_stdin {&default} else {&null};
- let stdin = self.stdin.as_ref().unwrap_or(default_stdin);
- let stdout = self.stdout.as_ref().unwrap_or(&default);
- let stderr = self.stderr.as_ref().unwrap_or(&default);
- let (their_stdin, our_stdin) = stdin.to_child_stdio(true)?;
- let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;
- let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;
- let ours = StdioPipes {
- stdin: our_stdin,
- stdout: our_stdout,
- stderr: our_stderr,
- };
- let theirs = ChildPipes {
- stdin: their_stdin,
- stdout: their_stdout,
- stderr: their_stderr,
- };
- Ok((ours, theirs))
- }
-}
-
-fn os2c(s: &OsStr, saw_nul: &mut bool) -> CString {
- CString::new(s.as_bytes()).unwrap_or_else(|_e| {
- *saw_nul = true;
- CString::new("<string-with-nul>").unwrap()
- })
-}
-
-// Helper type to manage ownership of the strings within a C-style array.
-pub struct CStringArray {
- items: Vec<CString>,
- ptrs: Vec<*const c_char>
-}
-
-impl CStringArray {
- pub fn with_capacity(capacity: usize) -> Self {
- let mut result = CStringArray {
- items: Vec::with_capacity(capacity),
- ptrs: Vec::with_capacity(capacity+1)
- };
- result.ptrs.push(ptr::null());
- result
- }
- pub fn push(&mut self, item: CString) {
- let l = self.ptrs.len();
- self.ptrs[l-1] = item.as_ptr();
- self.ptrs.push(ptr::null());
- self.items.push(item);
- }
- pub fn as_ptr(&self) -> *const *const c_char {
- self.ptrs.as_ptr()
- }
-}
-
-fn construct_envp(env: BTreeMap<DefaultEnvKey, OsString>, saw_nul: &mut bool) -> CStringArray {
- let mut result = CStringArray::with_capacity(env.len());
- for (k, v) in env {
- let mut k: OsString = k.into();
-
- // Reserve additional space for '=' and null terminator
- k.reserve_exact(v.len() + 2);
- k.push("=");
- k.push(&v);
-
- // Add the new entry into the array
- if let Ok(item) = CString::new(k.into_vec()) {
- result.push(item);
- } else {
- *saw_nul = true;
- }
- }
-
- result
-}
-
-impl Stdio {
- pub fn to_child_stdio(&self, readable: bool)
- -> io::Result<(ChildStdio, Option<AnonPipe>)> {
- match *self {
- Stdio::Inherit => {
- Ok((ChildStdio::Inherit, None))
- },
-
- // Make sure that the source descriptors are not an stdio
- // descriptor, otherwise the order which we set the child's
- // descriptors may blow away a descriptor which we are hoping to
- // save. For example, suppose we want the child's stderr to be the
- // parent's stdout, and the child's stdout to be the parent's
- // stderr. No matter which we dup first, the second will get
- // overwritten prematurely.
- Stdio::Fd(ref fd) => {
- if fd.raw() >= 0 && fd.raw() <= libc::STDERR_FILENO {
- Ok((ChildStdio::Owned(fd.duplicate()?), None))
- } else {
- Ok((ChildStdio::Explicit(fd.raw()), None))
- }
- }
-
- Stdio::MakePipe => {
- let (reader, writer) = pipe::anon_pipe()?;
- let (ours, theirs) = if readable {
- (writer, reader)
- } else {
- (reader, writer)
- };
- Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
- }
-
- Stdio::Null => {
- let mut opts = OpenOptions::new();
- opts.read(readable);
- opts.write(!readable);
- let path = unsafe {
- CStr::from_ptr("/dev/null\0".as_ptr() as *const _)
- };
- let fd = File::open_c(&path, &opts)?;
- Ok((ChildStdio::Owned(fd.into_fd()), None))
- }
- }
- }
-}
-
-impl From<AnonPipe> for Stdio {
- fn from(pipe: AnonPipe) -> Stdio {
- Stdio::Fd(pipe.into_fd())
- }
-}
-
-impl From<File> for Stdio {
- fn from(file: File) -> Stdio {
- Stdio::Fd(file.into_fd())
- }
-}
-
-impl ChildStdio {
- pub fn fd(&self) -> Option<c_int> {
- match *self {
- ChildStdio::Inherit => None,
- ChildStdio::Explicit(fd) => Some(fd),
- ChildStdio::Owned(ref fd) => Some(fd.raw()),
- }
- }
-}
-
-impl fmt::Debug for Command {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{:?}", self.program)?;
- for arg in &self.args {
- write!(f, " {:?}", arg)?;
- }
- Ok(())
- }
-}
-
-/// Unix exit statuses
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitStatus(c_int);
-
-impl ExitStatus {
- pub fn new(status: c_int) -> ExitStatus {
- ExitStatus(status)
- }
-
- fn exited(&self) -> bool {
- unsafe { libc::WIFEXITED(self.0) }
- }
-
- pub fn success(&self) -> bool {
- self.code() == Some(0)
- }
-
- pub fn code(&self) -> Option<i32> {
- if self.exited() {
- Some(unsafe { libc::WEXITSTATUS(self.0) })
- } else {
- None
- }
- }
-
- pub fn signal(&self) -> Option<i32> {
- if !self.exited() {
- Some(unsafe { libc::WTERMSIG(self.0) })
- } else {
- None
- }
- }
-}
-
-impl From<c_int> for ExitStatus {
- fn from(a: c_int) -> ExitStatus {
- ExitStatus(a)
- }
-}
-
-impl fmt::Display for ExitStatus {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- if let Some(code) = self.code() {
- write!(f, "exit code: {}", code)
- } else {
- let signal = self.signal().unwrap();
- write!(f, "signal: {}", signal)
- }
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitCode(u8);
-
-impl ExitCode {
- pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
- pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);
-
- #[inline]
- pub fn as_i32(&self) -> i32 {
- self.0 as i32
- }
-}
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod tests {
- use super::*;
-
- use ffi::OsStr;
- use mem;
- use ptr;
- use libc;
- use sys::cvt;
-
- macro_rules! t {
- ($e:expr) => {
- match $e {
- Ok(t) => t,
- Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
- }
- }
- }
-
- // Android with api less than 21 define sig* functions inline, so it is not
- // available for dynamic link. Implementing sigemptyset and sigaddset allow us
- // to support older Android version (independent of libc version).
- // The following implementations are based on https://git.io/vSkNf
-
- #[cfg(not(target_os = "android"))]
- extern {
- #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
- fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int;
-
- #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
- fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int;
- }
-
- #[cfg(target_os = "android")]
- unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
- libc::memset(set as *mut _, 0, mem::size_of::<libc::sigset_t>());
- return 0;
- }
-
- #[cfg(target_os = "android")]
- unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
- use slice;
-
- let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
- let bit = (signum - 1) as usize;
- raw[bit / 8] |= 1 << (bit % 8);
- return 0;
- }
-
- // See #14232 for more information, but it appears that signal delivery to a
- // newly spawned process may just be raced in the macOS, so to prevent this
- // test from being flaky we ignore it on macOS.
- #[test]
- #[cfg_attr(target_os = "macos", ignore)]
- // When run under our current QEMU emulation test suite this test fails,
- // although the reason isn't very clear as to why. For now this test is
- // ignored there.
- #[cfg_attr(target_arch = "arm", ignore)]
- #[cfg_attr(target_arch = "aarch64", ignore)]
- fn test_process_mask() {
- unsafe {
- // Test to make sure that a signal mask does not get inherited.
- let mut cmd = Command::new(OsStr::new("cat"));
-
- let mut set: libc::sigset_t = mem::uninitialized();
- let mut old_set: libc::sigset_t = mem::uninitialized();
- t!(cvt(sigemptyset(&mut set)));
- t!(cvt(sigaddset(&mut set, libc::SIGINT)));
- t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set)));
-
- cmd.stdin(Stdio::MakePipe);
- cmd.stdout(Stdio::MakePipe);
-
- let (mut cat, mut pipes) = t!(cmd.spawn(Stdio::Null, true));
- let stdin_write = pipes.stdin.take().unwrap();
- let stdout_read = pipes.stdout.take().unwrap();
-
- t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &old_set,
- ptr::null_mut())));
-
- t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
- // We need to wait until SIGINT is definitely delivered. The
- // easiest way is to write something to cat, and try to read it
- // back: if SIGINT is unmasked, it'll get delivered when cat is
- // next scheduled.
- let _ = stdin_write.write(b"Hello");
- drop(stdin_write);
-
- // Either EOF or failure (EPIPE) is okay.
- let mut buf = [0; 5];
- if let Ok(ret) = stdout_read.read(&mut buf) {
- assert_eq!(ret, 0);
- }
-
- t!(cat.wait());
- }
- }
-}
diff --git a/ctr-std/src/sys/unix/process/process_fuchsia.rs b/ctr-std/src/sys/unix/process/process_fuchsia.rs
deleted file mode 100644
index fa48001..0000000
--- a/ctr-std/src/sys/unix/process/process_fuchsia.rs
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use io;
-use libc::{self, size_t};
-use mem;
-use ptr;
-
-use sys::process::zircon::{Handle, zx_handle_t};
-use sys::process::process_common::*;
-
-////////////////////////////////////////////////////////////////////////////////
-// Command
-////////////////////////////////////////////////////////////////////////////////
-
-impl Command {
- pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
- -> io::Result<(Process, StdioPipes)> {
- let envp = self.capture_env();
-
- if self.saw_nul() {
- return Err(io::Error::new(io::ErrorKind::InvalidInput,
- "nul byte found in provided data"));
- }
-
- let (ours, theirs) = self.setup_io(default, needs_stdin)?;
-
- let process_handle = unsafe { self.do_exec(theirs, envp.as_ref())? };
-
- Ok((Process { handle: Handle::new(process_handle) }, ours))
- }
-
- pub fn exec(&mut self, default: Stdio) -> io::Error {
- if self.saw_nul() {
- return io::Error::new(io::ErrorKind::InvalidInput,
- "nul byte found in provided data")
- }
-
- match self.setup_io(default, true) {
- Ok((_, _)) => {
- // FIXME: This is tough because we don't support the exec syscalls
- unimplemented!();
- },
- Err(e) => e,
- }
- }
-
- unsafe fn do_exec(&mut self, stdio: ChildPipes, maybe_envp: Option<&CStringArray>)
- -> io::Result<zx_handle_t> {
- use sys::process::zircon::*;
-
- let envp = match maybe_envp {
- Some(envp) => envp.as_ptr(),
- None => ptr::null(),
- };
-
- let transfer_or_clone = |opt_fd, target_fd| if let Some(local_fd) = opt_fd {
- fdio_spawn_action_t {
- action: FDIO_SPAWN_ACTION_TRANSFER_FD,
- local_fd,
- target_fd,
- ..Default::default()
- }
- } else {
- fdio_spawn_action_t {
- action: FDIO_SPAWN_ACTION_CLONE_FD,
- local_fd: target_fd,
- target_fd,
- ..Default::default()
- }
- };
-
- // Clone stdin, stdout, and stderr
- let action1 = transfer_or_clone(stdio.stdin.fd(), 0);
- let action2 = transfer_or_clone(stdio.stdout.fd(), 1);
- let action3 = transfer_or_clone(stdio.stderr.fd(), 2);
- let actions = [action1, action2, action3];
-
- // We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc
- // always consumes transferred file descriptors.
- mem::forget(stdio);
-
- for callback in self.get_closures().iter_mut() {
- callback()?;
- }
-
- let mut process_handle: zx_handle_t = 0;
- zx_cvt(fdio_spawn_etc(
- 0,
- FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE,
- self.get_argv()[0], self.get_argv().as_ptr(), envp, 3, actions.as_ptr(),
- &mut process_handle,
- ptr::null_mut(),
- ))?;
- // FIXME: See if we want to do something with that err_msg
-
- Ok(process_handle)
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Processes
-////////////////////////////////////////////////////////////////////////////////
-
-pub struct Process {
- handle: Handle,
-}
-
-impl Process {
- pub fn id(&self) -> u32 {
- self.handle.raw() as u32
- }
-
- pub fn kill(&mut self) -> io::Result<()> {
- use sys::process::zircon::*;
-
- unsafe { zx_cvt(zx_task_kill(self.handle.raw()))?; }
-
- Ok(())
- }
-
- pub fn wait(&mut self) -> io::Result<ExitStatus> {
- use default::Default;
- use sys::process::zircon::*;
-
- let mut proc_info: zx_info_process_t = Default::default();
- let mut actual: size_t = 0;
- let mut avail: size_t = 0;
-
- unsafe {
- zx_cvt(zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED,
- ZX_TIME_INFINITE, ptr::null_mut()))?;
- zx_cvt(zx_object_get_info(self.handle.raw(), ZX_INFO_PROCESS,
- &mut proc_info as *mut _ as *mut libc::c_void,
- mem::size_of::<zx_info_process_t>(), &mut actual,
- &mut avail))?;
- }
- if actual != 1 {
- return Err(io::Error::new(io::ErrorKind::InvalidData,
- "Failed to get exit status of process"));
- }
- Ok(ExitStatus::new(proc_info.rec.return_code))
- }
-
- pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
- use default::Default;
- use sys::process::zircon::*;
-
- let mut proc_info: zx_info_process_t = Default::default();
- let mut actual: size_t = 0;
- let mut avail: size_t = 0;
-
- unsafe {
- let status = zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED,
- 0, ptr::null_mut());
- match status {
- 0 => { }, // Success
- x if x == ERR_TIMED_OUT => {
- return Ok(None);
- },
- _ => { panic!("Failed to wait on process handle: {}", status); },
- }
- zx_cvt(zx_object_get_info(self.handle.raw(), ZX_INFO_PROCESS,
- &mut proc_info as *mut _ as *mut libc::c_void,
- mem::size_of::<zx_info_process_t>(), &mut actual,
- &mut avail))?;
- }
- if actual != 1 {
- return Err(io::Error::new(io::ErrorKind::InvalidData,
- "Failed to get exit status of process"));
- }
- Ok(Some(ExitStatus::new(proc_info.rec.return_code)))
- }
-}
diff --git a/ctr-std/src/sys/unix/process/process_unix.rs b/ctr-std/src/sys/unix/process/process_unix.rs
deleted file mode 100644
index 9d6d607..0000000
--- a/ctr-std/src/sys/unix/process/process_unix.rs
+++ /dev/null
@@ -1,405 +0,0 @@
-// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use io::{self, Error, ErrorKind};
-use libc::{self, c_int, gid_t, pid_t, uid_t};
-use ptr;
-
-use sys::cvt;
-use sys::process::process_common::*;
-
-////////////////////////////////////////////////////////////////////////////////
-// Command
-////////////////////////////////////////////////////////////////////////////////
-
-impl Command {
- pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
- -> io::Result<(Process, StdioPipes)> {
- use sys;
-
- const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX";
-
- let envp = self.capture_env();
-
- if self.saw_nul() {
- return Err(io::Error::new(ErrorKind::InvalidInput,
- "nul byte found in provided data"));
- }
-
- let (ours, theirs) = self.setup_io(default, needs_stdin)?;
-
- if let Some(ret) = self.posix_spawn(&theirs, envp.as_ref())? {
- return Ok((ret, ours))
- }
-
- let (input, output) = sys::pipe::anon_pipe()?;
-
- let pid = unsafe {
- match cvt(libc::fork())? {
- 0 => {
- drop(input);
- let err = self.do_exec(theirs, envp.as_ref());
- let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
- let bytes = [
- (errno >> 24) as u8,
- (errno >> 16) as u8,
- (errno >> 8) as u8,
- (errno >> 0) as u8,
- CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1],
- CLOEXEC_MSG_FOOTER[2], CLOEXEC_MSG_FOOTER[3]
- ];
- // pipe I/O up to PIPE_BUF bytes should be atomic, and then
- // we want to be sure we *don't* run at_exit destructors as
- // we're being torn down regardless
- assert!(output.write(&bytes).is_ok());
- libc::_exit(1)
- }
- n => n,
- }
- };
-
- let mut p = Process { pid: pid, status: None };
- drop(output);
- let mut bytes = [0; 8];
-
- // loop to handle EINTR
- loop {
- match input.read(&mut bytes) {
- Ok(0) => return Ok((p, ours)),
- Ok(8) => {
- assert!(combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4.. 8]),
- "Validation on the CLOEXEC pipe failed: {:?}", bytes);
- let errno = combine(&bytes[0.. 4]);
- assert!(p.wait().is_ok(),
- "wait() should either return Ok or panic");
- return Err(Error::from_raw_os_error(errno))
- }
- Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
- Err(e) => {
- assert!(p.wait().is_ok(),
- "wait() should either return Ok or panic");
- panic!("the CLOEXEC pipe failed: {:?}", e)
- },
- Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic
- assert!(p.wait().is_ok(),
- "wait() should either return Ok or panic");
- panic!("short read on the CLOEXEC pipe")
- }
- }
- }
-
- fn combine(arr: &[u8]) -> i32 {
- let a = arr[0] as u32;
- let b = arr[1] as u32;
- let c = arr[2] as u32;
- let d = arr[3] as u32;
-
- ((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32
- }
- }
-
- pub fn exec(&mut self, default: Stdio) -> io::Error {
- let envp = self.capture_env();
-
- if self.saw_nul() {
- return io::Error::new(ErrorKind::InvalidInput,
- "nul byte found in provided data")
- }
-
- match self.setup_io(default, true) {
- Ok((_, theirs)) => unsafe { self.do_exec(theirs, envp.as_ref()) },
- Err(e) => e,
- }
- }
-
- // And at this point we've reached a special time in the life of the
- // child. The child must now be considered hamstrung and unable to
- // do anything other than syscalls really. Consider the following
- // scenario:
- //
- // 1. Thread A of process 1 grabs the malloc() mutex
- // 2. Thread B of process 1 forks(), creating thread C
- // 3. Thread C of process 2 then attempts to malloc()
- // 4. The memory of process 2 is the same as the memory of
- // process 1, so the mutex is locked.
- //
- // This situation looks a lot like deadlock, right? It turns out
- // that this is what pthread_atfork() takes care of, which is
- // presumably implemented across platforms. The first thing that
- // threads to *before* forking is to do things like grab the malloc
- // mutex, and then after the fork they unlock it.
- //
- // Despite this information, libnative's spawn has been witnessed to
- // deadlock on both macOS and FreeBSD. I'm not entirely sure why, but
- // all collected backtraces point at malloc/free traffic in the
- // child spawned process.
- //
- // For this reason, the block of code below should contain 0
- // invocations of either malloc of free (or their related friends).
- //
- // As an example of not having malloc/free traffic, we don't close
- // this file descriptor by dropping the FileDesc (which contains an
- // allocation). Instead we just close it manually. This will never
- // have the drop glue anyway because this code never returns (the
- // child will either exec() or invoke libc::exit)
- unsafe fn do_exec(
- &mut self,
- stdio: ChildPipes,
- maybe_envp: Option<&CStringArray>
- ) -> io::Error {
- use sys::{self, cvt_r};
-
- macro_rules! t {
- ($e:expr) => (match $e {
- Ok(e) => e,
- Err(e) => return e,
- })
- }
-
- if let Some(fd) = stdio.stdin.fd() {
- t!(cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO)));
- }
- if let Some(fd) = stdio.stdout.fd() {
- t!(cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO)));
- }
- if let Some(fd) = stdio.stderr.fd() {
- t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO)));
- }
-
- if cfg!(not(any(target_os = "l4re"))) {
- if let Some(u) = self.get_gid() {
- t!(cvt(libc::setgid(u as gid_t)));
- }
- if let Some(u) = self.get_uid() {
- // When dropping privileges from root, the `setgroups` call
- // will remove any extraneous groups. If we don't call this,
- // then even though our uid has dropped, we may still have
- // groups that enable us to do super-user things. This will
- // fail if we aren't root, so don't bother checking the
- // return value, this is just done as an optimistic
- // privilege dropping function.
- let _ = libc::setgroups(0, ptr::null());
-
- t!(cvt(libc::setuid(u as uid_t)));
- }
- }
- if let Some(ref cwd) = *self.get_cwd() {
- t!(cvt(libc::chdir(cwd.as_ptr())));
- }
- if let Some(envp) = maybe_envp {
- *sys::os::environ() = envp.as_ptr();
- }
-
- // emscripten has no signal support.
- #[cfg(not(any(target_os = "emscripten")))]
- {
- 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: libc::sigset_t = mem::uninitialized();
- if cfg!(target_os = "android") {
- // Implementing sigemptyset allow us to support older Android
- // versions. See the comment about Android and sig* functions in
- // process_common.rs
- libc::memset(&mut set as *mut _ as *mut _,
- 0,
- mem::size_of::<libc::sigset_t>());
- } else {
- t!(cvt(libc::sigemptyset(&mut set)));
- }
- t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
- ptr::null_mut())));
- let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
- if ret == libc::SIG_ERR {
- return io::Error::last_os_error()
- }
- }
-
- for callback in self.get_closures().iter_mut() {
- t!(callback());
- }
-
- libc::execvp(self.get_argv()[0], self.get_argv().as_ptr());
- io::Error::last_os_error()
- }
-
- #[cfg(not(any(target_os = "macos", target_os = "freebsd",
- all(target_os = "linux", target_env = "gnu"))))]
- fn posix_spawn(&mut self, _: &ChildPipes, _: Option<&CStringArray>)
- -> io::Result<Option<Process>>
- {
- Ok(None)
- }
-
- // Only support platforms for which posix_spawn() can return ENOENT
- // directly.
- #[cfg(any(target_os = "macos", target_os = "freebsd",
- all(target_os = "linux", target_env = "gnu")))]
- fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>)
- -> io::Result<Option<Process>>
- {
- use mem;
- use sys;
-
- if self.get_cwd().is_some() ||
- self.get_gid().is_some() ||
- self.get_uid().is_some() ||
- self.env_saw_path() ||
- self.get_closures().len() != 0 {
- return Ok(None)
- }
-
- // Only glibc 2.24+ posix_spawn() supports returning ENOENT directly.
- #[cfg(all(target_os = "linux", target_env = "gnu"))]
- {
- if let Some(version) = sys::os::glibc_version() {
- if version < (2, 24) {
- return Ok(None)
- }
- } else {
- return Ok(None)
- }
- }
-
- let mut p = Process { pid: 0, status: None };
-
- struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t);
-
- impl Drop for PosixSpawnFileActions {
- fn drop(&mut self) {
- unsafe {
- libc::posix_spawn_file_actions_destroy(&mut self.0);
- }
- }
- }
-
- struct PosixSpawnattr(libc::posix_spawnattr_t);
-
- impl Drop for PosixSpawnattr {
- fn drop(&mut self) {
- unsafe {
- libc::posix_spawnattr_destroy(&mut self.0);
- }
- }
- }
-
- unsafe {
- let mut file_actions = PosixSpawnFileActions(mem::uninitialized());
- let mut attrs = PosixSpawnattr(mem::uninitialized());
-
- libc::posix_spawnattr_init(&mut attrs.0);
- libc::posix_spawn_file_actions_init(&mut file_actions.0);
-
- if let Some(fd) = stdio.stdin.fd() {
- cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
- fd,
- libc::STDIN_FILENO))?;
- }
- if let Some(fd) = stdio.stdout.fd() {
- cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
- fd,
- libc::STDOUT_FILENO))?;
- }
- if let Some(fd) = stdio.stderr.fd() {
- cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
- fd,
- libc::STDERR_FILENO))?;
- }
-
- let mut set: libc::sigset_t = mem::uninitialized();
- cvt(libc::sigemptyset(&mut set))?;
- cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0,
- &set))?;
- cvt(libc::sigaddset(&mut set, libc::SIGPIPE))?;
- cvt(libc::posix_spawnattr_setsigdefault(&mut attrs.0,
- &set))?;
-
- let flags = libc::POSIX_SPAWN_SETSIGDEF |
- libc::POSIX_SPAWN_SETSIGMASK;
- cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?;
-
- let envp = envp.map(|c| c.as_ptr())
- .unwrap_or(*sys::os::environ() as *const _);
- let ret = libc::posix_spawnp(
- &mut p.pid,
- self.get_argv()[0],
- &file_actions.0,
- &attrs.0,
- self.get_argv().as_ptr() as *const _,
- envp as *const _,
- );
- if ret == 0 {
- Ok(Some(p))
- } else {
- Err(io::Error::from_raw_os_error(ret))
- }
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Processes
-////////////////////////////////////////////////////////////////////////////////
-
-/// The unique id of the process (this should never be negative).
-pub struct Process {
- pid: pid_t,
- status: Option<ExitStatus>,
-}
-
-impl Process {
- pub fn id(&self) -> u32 {
- self.pid as u32
- }
-
- pub fn kill(&mut self) -> io::Result<()> {
- // If we've already waited on this process then the pid can be recycled
- // and used for another process, and we probably shouldn't be killing
- // random processes, so just return an error.
- if self.status.is_some() {
- Err(Error::new(ErrorKind::InvalidInput,
- "invalid argument: can't kill an exited process"))
- } else {
- cvt(unsafe { libc::kill(self.pid, libc::SIGKILL) }).map(|_| ())
- }
- }
-
- pub fn wait(&mut self) -> io::Result<ExitStatus> {
- use sys::cvt_r;
- if let Some(status) = self.status {
- return Ok(status)
- }
- let mut status = 0 as c_int;
- cvt_r(|| unsafe { libc::waitpid(self.pid, &mut status, 0) })?;
- self.status = Some(ExitStatus::new(status));
- Ok(ExitStatus::new(status))
- }
-
- pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
- if let Some(status) = self.status {
- return Ok(Some(status))
- }
- let mut status = 0 as c_int;
- let pid = cvt(unsafe {
- libc::waitpid(self.pid, &mut status, libc::WNOHANG)
- })?;
- if pid == 0 {
- Ok(None)
- } else {
- self.status = Some(ExitStatus::new(status));
- Ok(Some(ExitStatus::new(status)))
- }
- }
-}
diff --git a/ctr-std/src/sys/unix/process/zircon.rs b/ctr-std/src/sys/unix/process/zircon.rs
deleted file mode 100644
index a06c73e..0000000
--- a/ctr-std/src/sys/unix/process/zircon.rs
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(non_camel_case_types, unused)]
-
-use convert::TryInto;
-use io;
-use os::raw::c_char;
-use u64;
-
-use libc::{c_int, c_void, size_t};
-
-pub type zx_handle_t = u32;
-pub type zx_vaddr_t = usize;
-pub type zx_rights_t = u32;
-pub type zx_status_t = i32;
-
-pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
-
-pub type zx_time_t = u64;
-pub const ZX_TIME_INFINITE : zx_time_t = u64::MAX;
-
-pub type zx_signals_t = u32;
-
-pub const ZX_OBJECT_SIGNAL_3 : zx_signals_t = 1 << 3;
-
-pub const ZX_TASK_TERMINATED : zx_signals_t = ZX_OBJECT_SIGNAL_3;
-
-pub const ZX_RIGHT_SAME_RIGHTS : zx_rights_t = 1 << 31;
-
-pub type zx_object_info_topic_t = u32;
-
-pub const ZX_INFO_PROCESS : zx_object_info_topic_t = 3;
-
-pub fn zx_cvt<T>(t: T) -> io::Result<T> where T: TryInto<zx_status_t>+Copy {
- if let Ok(status) = TryInto::try_into(t) {
- if status < 0 {
- Err(io::Error::from_raw_os_error(status))
- } else {
- Ok(t)
- }
- } else {
- Err(io::Error::last_os_error())
- }
-}
-
-// Safe wrapper around zx_handle_t
-pub struct Handle {
- raw: zx_handle_t,
-}
-
-impl Handle {
- pub fn new(raw: zx_handle_t) -> Handle {
- Handle {
- raw,
- }
- }
-
- pub fn raw(&self) -> zx_handle_t {
- self.raw
- }
-}
-
-impl Drop for Handle {
- fn drop(&mut self) {
- unsafe { zx_cvt(zx_handle_close(self.raw)).expect("Failed to close zx_handle_t"); }
- }
-}
-
-// Common ZX_INFO header
-#[derive(Default)]
-#[repr(C)]
-pub struct zx_info_header_t {
- pub topic: u32, // identifies the info struct
- pub avail_topic_size: u16, // “native” size of the struct
- pub topic_size: u16, // size of the returned struct (<=topic_size)
- pub avail_count: u32, // number of records the kernel has
- pub count: u32, // number of records returned (limited by buffer size)
-}
-
-#[derive(Default)]
-#[repr(C)]
-pub struct zx_record_process_t {
- pub return_code: c_int,
-}
-
-// Returned for topic ZX_INFO_PROCESS
-#[derive(Default)]
-#[repr(C)]
-pub struct zx_info_process_t {
- pub hdr: zx_info_header_t,
- pub rec: zx_record_process_t,
-}
-
-extern {
- pub fn zx_job_default() -> zx_handle_t;
-
- pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
-
- pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t;
-
- pub fn zx_handle_duplicate(handle: zx_handle_t, rights: zx_rights_t,
- out: *const zx_handle_t) -> zx_handle_t;
-
- pub fn zx_object_wait_one(handle: zx_handle_t, signals: zx_signals_t, timeout: zx_time_t,
- pending: *mut zx_signals_t) -> zx_status_t;
-
- pub fn zx_object_get_info(handle: zx_handle_t, topic: u32, buffer: *mut c_void,
- buffer_size: size_t, actual_size: *mut size_t,
- avail: *mut size_t) -> zx_status_t;
-}
-
-#[derive(Default)]
-#[repr(C)]
-pub struct fdio_spawn_action_t {
- pub action: u32,
- pub reserved0: u32,
- pub local_fd: i32,
- pub target_fd: i32,
- pub reserved1: u64,
-}
-
-extern {
- pub fn fdio_spawn_etc(job: zx_handle_t, flags: u32, path: *const c_char,
- argv: *const *const c_char, envp: *const *const c_char,
- action_count: u64, actions: *const fdio_spawn_action_t,
- process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t;
-}
-
-// fdio_spawn_etc flags
-
-pub const FDIO_SPAWN_CLONE_JOB: u32 = 0x0001;
-pub const FDIO_SPAWN_CLONE_LDSVC: u32 = 0x0002;
-pub const FDIO_SPAWN_CLONE_NAMESPACE: u32 = 0x0004;
-pub const FDIO_SPAWN_CLONE_STDIO: u32 = 0x0008;
-pub const FDIO_SPAWN_CLONE_ENVIRON: u32 = 0x0010;
-pub const FDIO_SPAWN_CLONE_ALL: u32 = 0xFFFF;
-
-// fdio_spawn_etc actions
-
-pub const FDIO_SPAWN_ACTION_CLONE_FD: u32 = 0x0001;
-pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002;
-
-// Errors
-
-#[allow(unused)] pub const ERR_INTERNAL: zx_status_t = -1;
-
-// ERR_NOT_SUPPORTED: The operation is not implemented, supported,
-// or enabled.
-#[allow(unused)] pub const ERR_NOT_SUPPORTED: zx_status_t = -2;
-
-// ERR_NO_RESOURCES: The system was not able to allocate some resource
-// needed for the operation.
-#[allow(unused)] pub const ERR_NO_RESOURCES: zx_status_t = -3;
-
-// ERR_NO_MEMORY: The system was not able to allocate memory needed
-// for the operation.
-#[allow(unused)] pub const ERR_NO_MEMORY: zx_status_t = -4;
-
-// ERR_CALL_FAILED: The second phase of zx_channel_call(; did not complete
-// successfully.
-#[allow(unused)] pub const ERR_CALL_FAILED: zx_status_t = -5;
-
-// ERR_INTERRUPTED_RETRY: The system call was interrupted, but should be
-// retried. This should not be seen outside of the VDSO.
-#[allow(unused)] pub const ERR_INTERRUPTED_RETRY: zx_status_t = -6;
-
-// ======= Parameter errors =======
-// ERR_INVALID_ARGS: an argument is invalid, ex. null pointer
-#[allow(unused)] pub const ERR_INVALID_ARGS: zx_status_t = -10;
-
-// ERR_BAD_HANDLE: A specified handle value does not refer to a handle.
-#[allow(unused)] pub const ERR_BAD_HANDLE: zx_status_t = -11;
-
-// ERR_WRONG_TYPE: The subject of the operation is the wrong type to
-// perform the operation.
-// Example: Attempting a message_read on a thread handle.
-#[allow(unused)] pub const ERR_WRONG_TYPE: zx_status_t = -12;
-
-// ERR_BAD_SYSCALL: The specified syscall number is invalid.
-#[allow(unused)] pub const ERR_BAD_SYSCALL: zx_status_t = -13;
-
-// ERR_OUT_OF_RANGE: An argument is outside the valid range for this
-// operation.
-#[allow(unused)] pub const ERR_OUT_OF_RANGE: zx_status_t = -14;
-
-// ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for
-// this operation.
-#[allow(unused)] pub const ERR_BUFFER_TOO_SMALL: zx_status_t = -15;
-
-// ======= Precondition or state errors =======
-// ERR_BAD_STATE: operation failed because the current state of the
-// object does not allow it, or a precondition of the operation is
-// not satisfied
-#[allow(unused)] pub const ERR_BAD_STATE: zx_status_t = -20;
-
-// ERR_TIMED_OUT: The time limit for the operation elapsed before
-// the operation completed.
-#[allow(unused)] pub const ERR_TIMED_OUT: zx_status_t = -21;
-
-// ERR_SHOULD_WAIT: The operation cannot be performed currently but
-// potentially could succeed if the caller waits for a prerequisite
-// to be satisfied, for example waiting for a handle to be readable
-// or writable.
-// Example: Attempting to read from a message pipe that has no
-// messages waiting but has an open remote will return ERR_SHOULD_WAIT.
-// Attempting to read from a message pipe that has no messages waiting
-// and has a closed remote end will return ERR_REMOTE_CLOSED.
-#[allow(unused)] pub const ERR_SHOULD_WAIT: zx_status_t = -22;
-
-// ERR_CANCELED: The in-progress operation (e.g. a wait) has been
-// // canceled.
-#[allow(unused)] pub const ERR_CANCELED: zx_status_t = -23;
-
-// ERR_PEER_CLOSED: The operation failed because the remote end
-// of the subject of the operation was closed.
-#[allow(unused)] pub const ERR_PEER_CLOSED: zx_status_t = -24;
-
-// ERR_NOT_FOUND: The requested entity is not found.
-#[allow(unused)] pub const ERR_NOT_FOUND: zx_status_t = -25;
-
-// ERR_ALREADY_EXISTS: An object with the specified identifier
-// already exists.
-// Example: Attempting to create a file when a file already exists
-// with that name.
-#[allow(unused)] pub const ERR_ALREADY_EXISTS: zx_status_t = -26;
-
-// ERR_ALREADY_BOUND: The operation failed because the named entity
-// is already owned or controlled by another entity. The operation
-// could succeed later if the current owner releases the entity.
-#[allow(unused)] pub const ERR_ALREADY_BOUND: zx_status_t = -27;
-
-// ERR_UNAVAILABLE: The subject of the operation is currently unable
-// to perform the operation.
-// Note: This is used when there's no direct way for the caller to
-// observe when the subject will be able to perform the operation
-// and should thus retry.
-#[allow(unused)] pub const ERR_UNAVAILABLE: zx_status_t = -28;
-
-// ======= Permission check errors =======
-// ERR_ACCESS_DENIED: The caller did not have permission to perform
-// the specified operation.
-#[allow(unused)] pub const ERR_ACCESS_DENIED: zx_status_t = -30;
-
-// ======= Input-output errors =======
-// ERR_IO: Otherwise unspecified error occurred during I/O.
-#[allow(unused)] pub const ERR_IO: zx_status_t = -40;
-
-// ERR_REFUSED: The entity the I/O operation is being performed on
-// rejected the operation.
-// Example: an I2C device NAK'ing a transaction or a disk controller
-// rejecting an invalid command.
-#[allow(unused)] pub const ERR_IO_REFUSED: zx_status_t = -41;
-
-// ERR_IO_DATA_INTEGRITY: The data in the operation failed an integrity
-// check and is possibly corrupted.
-// Example: CRC or Parity error.
-#[allow(unused)] pub const ERR_IO_DATA_INTEGRITY: zx_status_t = -42;
-
-// ERR_IO_DATA_LOSS: The data in the operation is currently unavailable
-// and may be permanently lost.
-// Example: A disk block is irrecoverably damaged.
-#[allow(unused)] pub const ERR_IO_DATA_LOSS: zx_status_t = -43;
-
-// Filesystem specific errors
-#[allow(unused)] pub const ERR_BAD_PATH: zx_status_t = -50;
-#[allow(unused)] pub const ERR_NOT_DIR: zx_status_t = -51;
-#[allow(unused)] pub const ERR_NOT_FILE: zx_status_t = -52;
-// ERR_FILE_BIG: A file exceeds a filesystem-specific size limit.
-#[allow(unused)] pub const ERR_FILE_BIG: zx_status_t = -53;
-// ERR_NO_SPACE: Filesystem or device space is exhausted.
-#[allow(unused)] pub const ERR_NO_SPACE: zx_status_t = -54;
diff --git a/ctr-std/src/sys/unix/rand.rs b/ctr-std/src/sys/unix/rand.rs
deleted file mode 100644
index 01c0ada..0000000
--- a/ctr-std/src/sys/unix/rand.rs
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use mem;
-use slice;
-
-pub fn hashmap_random_keys() -> (u64, u64) {
- let mut v = (0, 0);
- unsafe {
- let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8,
- mem::size_of_val(&v));
- imp::fill_bytes(view);
- }
- return v
-}
-
-#[cfg(all(unix,
- not(target_os = "ios"),
- not(target_os = "openbsd"),
- not(target_os = "freebsd"),
- not(target_os = "fuchsia")))]
-mod imp {
- use fs::File;
- use io::Read;
- use libc;
- use sys::os::errno;
-
- #[cfg(any(target_os = "linux", target_os = "android"))]
- fn getrandom(buf: &mut [u8]) -> libc::c_long {
- unsafe {
- libc::syscall(libc::SYS_getrandom, buf.as_mut_ptr(), buf.len(), libc::GRND_NONBLOCK)
- }
- }
-
- #[cfg(not(any(target_os = "linux", target_os = "android")))]
- fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }
-
- fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
- let mut read = 0;
- while read < v.len() {
- let result = getrandom(&mut v[read..]);
- if result == -1 {
- let err = errno() as libc::c_int;
- if err == libc::EINTR {
- continue;
- } else if err == libc::EAGAIN {
- return false
- } else {
- panic!("unexpected getrandom error: {}", err);
- }
- } else {
- read += result as usize;
- }
- }
-
- return true
- }
-
- #[cfg(any(target_os = "linux", target_os = "android"))]
- fn is_getrandom_available() -> bool {
- use io;
- use sync::atomic::{AtomicBool, Ordering};
- use sync::Once;
-
- static CHECKER: Once = Once::new();
- static AVAILABLE: AtomicBool = AtomicBool::new(false);
-
- CHECKER.call_once(|| {
- let mut buf: [u8; 0] = [];
- let result = getrandom(&mut buf);
- let available = if result == -1 {
- let err = io::Error::last_os_error().raw_os_error();
- err != Some(libc::ENOSYS)
- } else {
- true
- };
- AVAILABLE.store(available, Ordering::Relaxed);
- });
-
- AVAILABLE.load(Ordering::Relaxed)
- }
-
- #[cfg(not(any(target_os = "linux", target_os = "android")))]
- fn is_getrandom_available() -> bool { false }
-
- pub fn fill_bytes(v: &mut [u8]) {
- // getrandom_fill_bytes here can fail if getrandom() returns EAGAIN,
- // meaning it would have blocked because the non-blocking pool (urandom)
- // has not initialized in the kernel yet due to a lack of entropy the
- // fallback we do here is to avoid blocking applications which could
- // depend on this call without ever knowing they do and don't have a
- // work around. The PRNG of /dev/urandom will still be used but not
- // over a completely full entropy pool
- if is_getrandom_available() && getrandom_fill_bytes(v) {
- return
- }
-
- let mut file = File::open("/dev/urandom")
- .expect("failed to open /dev/urandom");
- file.read_exact(v).expect("failed to read /dev/urandom");
- }
-}
-
-#[cfg(target_os = "openbsd")]
-mod imp {
- use libc;
- use sys::os::errno;
-
- pub fn fill_bytes(v: &mut [u8]) {
- // getentropy(2) permits a maximum buffer size of 256 bytes
- for s in v.chunks_mut(256) {
- let ret = unsafe {
- libc::getentropy(s.as_mut_ptr() as *mut libc::c_void, s.len())
- };
- if ret == -1 {
- panic!("unexpected getentropy error: {}", errno());
- }
- }
- }
-}
-
-#[cfg(target_os = "ios")]
-mod imp {
- use io;
- use libc::{c_int, size_t};
- use ptr;
-
- enum SecRandom {}
-
- #[allow(non_upper_case_globals)]
- const kSecRandomDefault: *const SecRandom = ptr::null();
-
- extern {
- fn SecRandomCopyBytes(rnd: *const SecRandom,
- count: size_t,
- bytes: *mut u8) -> c_int;
- }
-
- pub fn fill_bytes(v: &mut [u8]) {
- let ret = unsafe {
- SecRandomCopyBytes(kSecRandomDefault,
- v.len(),
- v.as_mut_ptr())
- };
- if ret == -1 {
- panic!("couldn't generate random bytes: {}",
- io::Error::last_os_error());
- }
- }
-}
-
-#[cfg(target_os = "freebsd")]
-mod imp {
- use libc;
- use ptr;
-
- pub fn fill_bytes(v: &mut [u8]) {
- let mib = [libc::CTL_KERN, libc::KERN_ARND];
- // kern.arandom permits a maximum buffer size of 256 bytes
- for s in v.chunks_mut(256) {
- let mut s_len = s.len();
- let ret = unsafe {
- libc::sysctl(mib.as_ptr(), mib.len() as libc::c_uint,
- s.as_mut_ptr() as *mut _, &mut s_len,
- ptr::null(), 0)
- };
- if ret == -1 || s_len != s.len() {
- panic!("kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})",
- ret, s.len(), s_len);
- }
- }
- }
-}
-
-#[cfg(target_os = "fuchsia")]
-mod imp {
- #[link(name = "zircon")]
- extern {
- fn zx_cprng_draw(buffer: *mut u8, len: usize);
- }
-
- pub fn fill_bytes(v: &mut [u8]) {
- unsafe { zx_cprng_draw(v.as_mut_ptr(), v.len()) }
- }
-}
diff --git a/ctr-std/src/sys/unix/rwlock.rs b/ctr-std/src/sys/unix/rwlock.rs
deleted file mode 100644
index c754d5b..0000000
--- a/ctr-std/src/sys/unix/rwlock.rs
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use libc;
-use cell::UnsafeCell;
-use sync::atomic::{AtomicUsize, Ordering};
-
-pub struct RWLock {
- inner: UnsafeCell<libc::pthread_rwlock_t>,
- write_locked: UnsafeCell<bool>,
- num_readers: AtomicUsize,
-}
-
-unsafe impl Send for RWLock {}
-unsafe impl Sync for RWLock {}
-
-impl RWLock {
- pub const fn new() -> RWLock {
- RWLock {
- inner: UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER),
- write_locked: UnsafeCell::new(false),
- num_readers: AtomicUsize::new(0),
- }
- }
- #[inline]
- pub unsafe fn read(&self) {
- let r = libc::pthread_rwlock_rdlock(self.inner.get());
-
- // According to the pthread_rwlock_rdlock spec, this function **may**
- // fail with EDEADLK if a deadlock is detected. On the other hand
- // pthread mutexes will *never* return EDEADLK if they are initialized
- // as the "fast" kind (which ours always are). As a result, a deadlock
- // situation may actually return from the call to pthread_rwlock_rdlock
- // instead of blocking forever (as mutexes and Windows rwlocks do). Note
- // that not all unix implementations, however, will return EDEADLK for
- // their rwlocks.
- //
- // We roughly maintain the deadlocking behavior by panicking to ensure
- // that this lock acquisition does not succeed.
- //
- // We also check whether this lock is already write locked. This
- // is only possible if it was write locked by the current thread and
- // the implementation allows recursive locking. The POSIX standard
- // doesn't require recursively locking a rwlock to deadlock, but we can't
- // allow that because it could lead to aliasing issues.
- if r == libc::EAGAIN {
- panic!("rwlock maximum reader count exceeded");
- } else if r == libc::EDEADLK || *self.write_locked.get() {
- if r == 0 {
- self.raw_unlock();
- }
- panic!("rwlock read lock would result in deadlock");
- } else {
- debug_assert_eq!(r, 0);
- self.num_readers.fetch_add(1, Ordering::Relaxed);
- }
- }
- #[inline]
- pub unsafe fn try_read(&self) -> bool {
- let r = libc::pthread_rwlock_tryrdlock(self.inner.get());
- if r == 0 {
- if *self.write_locked.get() {
- self.raw_unlock();
- false
- } else {
- self.num_readers.fetch_add(1, Ordering::Relaxed);
- true
- }
- } else {
- false
- }
- }
- #[inline]
- pub unsafe fn write(&self) {
- let r = libc::pthread_rwlock_wrlock(self.inner.get());
- // See comments above for why we check for EDEADLK and write_locked. We
- // also need to check that num_readers is 0.
- if r == libc::EDEADLK || *self.write_locked.get() ||
- self.num_readers.load(Ordering::Relaxed) != 0 {
- if r == 0 {
- self.raw_unlock();
- }
- panic!("rwlock write lock would result in deadlock");
- } else {
- debug_assert_eq!(r, 0);
- }
- *self.write_locked.get() = true;
- }
- #[inline]
- pub unsafe fn try_write(&self) -> bool {
- let r = libc::pthread_rwlock_trywrlock(self.inner.get());
- if r == 0 {
- if *self.write_locked.get() || self.num_readers.load(Ordering::Relaxed) != 0 {
- self.raw_unlock();
- false
- } else {
- *self.write_locked.get() = true;
- true
- }
- } else {
- false
- }
- }
- #[inline]
- unsafe fn raw_unlock(&self) {
- let r = libc::pthread_rwlock_unlock(self.inner.get());
- debug_assert_eq!(r, 0);
- }
- #[inline]
- pub unsafe fn read_unlock(&self) {
- debug_assert!(!*self.write_locked.get());
- self.num_readers.fetch_sub(1, Ordering::Relaxed);
- self.raw_unlock();
- }
- #[inline]
- pub unsafe fn write_unlock(&self) {
- debug_assert_eq!(self.num_readers.load(Ordering::Relaxed), 0);
- debug_assert!(*self.write_locked.get());
- *self.write_locked.get() = false;
- self.raw_unlock();
- }
- #[inline]
- pub unsafe fn destroy(&self) {
- let r = libc::pthread_rwlock_destroy(self.inner.get());
- // On DragonFly pthread_rwlock_destroy() returns EINVAL if called on a
- // rwlock that was just initialized with
- // libc::PTHREAD_RWLOCK_INITIALIZER. Once it is used (locked/unlocked)
- // or pthread_rwlock_init() is called, this behaviour no longer occurs.
- if cfg!(target_os = "dragonfly") {
- debug_assert!(r == 0 || r == libc::EINVAL);
- } else {
- debug_assert_eq!(r, 0);
- }
- }
-}
diff --git a/ctr-std/src/sys/unix/stack_overflow.rs b/ctr-std/src/sys/unix/stack_overflow.rs
deleted file mode 100644
index 40453f9..0000000
--- a/ctr-std/src/sys/unix/stack_overflow.rs
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![cfg_attr(test, allow(dead_code))]
-
-use libc;
-use self::imp::{make_handler, drop_handler};
-
-pub use self::imp::cleanup;
-pub use self::imp::init;
-
-pub struct Handler {
- _data: *mut libc::c_void
-}
-
-impl Handler {
- pub unsafe fn new() -> Handler {
- make_handler()
- }
-}
-
-impl Drop for Handler {
- fn drop(&mut self) {
- unsafe {
- drop_handler(self);
- }
- }
-}
-
-#[cfg(any(target_os = "linux",
- target_os = "macos",
- target_os = "bitrig",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "solaris",
- all(target_os = "netbsd", not(target_vendor = "rumprun")),
- target_os = "openbsd"))]
-mod imp {
- use super::Handler;
- use mem;
- use ptr;
- use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
- use libc::{sigaction, SIGBUS, SIG_DFL,
- SA_SIGINFO, SA_ONSTACK, sighandler_t};
- use libc;
- use libc::{mmap, munmap};
- use libc::{SIGSEGV, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON};
- use libc::MAP_FAILED;
-
- use sys_common::thread_info;
-
-
- #[cfg(any(target_os = "linux", target_os = "android"))]
- unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
- #[repr(C)]
- struct siginfo_t {
- a: [libc::c_int; 3], // si_signo, si_errno, si_code
- si_addr: *mut libc::c_void,
- }
-
- (*(info as *const siginfo_t)).si_addr as usize
- }
-
- #[cfg(not(any(target_os = "linux", target_os = "android")))]
- unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
- (*info).si_addr as usize
- }
-
- // Signal handler for the SIGSEGV and SIGBUS handlers. We've got guard pages
- // (unmapped pages) at the end of every thread's stack, so if a thread ends
- // up running into the guard page it'll trigger this handler. We want to
- // detect these cases and print out a helpful error saying that the stack
- // has overflowed. All other signals, however, should go back to what they
- // were originally supposed to do.
- //
- // This handler currently exists purely to print an informative message
- // whenever a thread overflows its stack. We then abort to exit and
- // indicate a crash, but to avoid a misleading SIGSEGV that might lead
- // users to believe that unsafe code has accessed an invalid pointer; the
- // SIGSEGV encountered when overflowing the stack is expected and
- // well-defined.
- //
- // If this is not a stack overflow, the handler un-registers itself and
- // then returns (to allow the original signal to be delivered again).
- // Returning from this kind of signal handler is technically not defined
- // to work when reading the POSIX spec strictly, but in practice it turns
- // out many large systems and all implementations allow returning from a
- // signal handler to work. For a more detailed explanation see the
- // comments on #26458.
- unsafe extern fn signal_handler(signum: libc::c_int,
- info: *mut libc::siginfo_t,
- _data: *mut libc::c_void) {
- use sys_common::util::report_overflow;
-
- let guard = thread_info::stack_guard().unwrap_or(0..0);
- let addr = siginfo_si_addr(info);
-
- // If the faulting address is within the guard page, then we print a
- // message saying so and abort.
- if guard.start <= addr && addr < guard.end {
- report_overflow();
- rtabort!("stack overflow");
- } else {
- // Unregister ourselves by reverting back to the default behavior.
- let mut action: sigaction = mem::zeroed();
- action.sa_sigaction = SIG_DFL;
- sigaction(signum, &action, ptr::null_mut());
-
- // See comment above for why this function returns.
- }
- }
-
- static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();
-
- pub unsafe fn init() {
- let mut action: sigaction = mem::zeroed();
- action.sa_flags = SA_SIGINFO | SA_ONSTACK;
- action.sa_sigaction = signal_handler as sighandler_t;
- sigaction(SIGSEGV, &action, ptr::null_mut());
- sigaction(SIGBUS, &action, ptr::null_mut());
-
- let handler = make_handler();
- MAIN_ALTSTACK = handler._data;
- mem::forget(handler);
- }
-
- pub unsafe fn cleanup() {
- Handler { _data: MAIN_ALTSTACK };
- }
-
- unsafe fn get_stackp() -> *mut libc::c_void {
- let stackp = mmap(ptr::null_mut(),
- SIGSTKSZ,
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON,
- -1,
- 0);
- if stackp == MAP_FAILED {
- panic!("failed to allocate an alternative stack");
- }
- stackp
- }
-
- #[cfg(any(target_os = "linux",
- target_os = "macos",
- target_os = "bitrig",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
- unsafe fn get_stack() -> libc::stack_t {
- libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ }
- }
-
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly"))]
- unsafe fn get_stack() -> libc::stack_t {
- libc::stack_t { ss_sp: get_stackp() as *mut i8, ss_flags: 0, ss_size: SIGSTKSZ }
- }
-
- pub unsafe fn make_handler() -> Handler {
- let mut stack = mem::zeroed();
- sigaltstack(ptr::null(), &mut stack);
- // Configure alternate signal stack, if one is not already set.
- if stack.ss_flags & SS_DISABLE != 0 {
- stack = get_stack();
- sigaltstack(&stack, ptr::null_mut());
- Handler { _data: stack.ss_sp as *mut libc::c_void }
- } else {
- Handler { _data: ptr::null_mut() }
- }
- }
-
- pub unsafe fn drop_handler(handler: &mut Handler) {
- if !handler._data.is_null() {
- let stack = libc::stack_t {
- ss_sp: ptr::null_mut(),
- ss_flags: SS_DISABLE,
- // Workaround for bug in macOS implementation of sigaltstack
- // UNIX2003 which returns ENOMEM when disabling a stack while
- // passing ss_size smaller than MINSIGSTKSZ. According to POSIX
- // both ss_sp and ss_size should be ignored in this case.
- ss_size: SIGSTKSZ,
- };
- sigaltstack(&stack, ptr::null_mut());
- munmap(handler._data, SIGSTKSZ);
- }
- }
-}
-
-#[cfg(not(any(target_os = "linux",
- target_os = "macos",
- target_os = "bitrig",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "solaris",
- all(target_os = "netbsd", not(target_vendor = "rumprun")),
- target_os = "openbsd")))]
-mod imp {
- use ptr;
-
- pub unsafe fn init() {
- }
-
- pub unsafe fn cleanup() {
- }
-
- pub unsafe fn make_handler() -> super::Handler {
- super::Handler { _data: ptr::null_mut() }
- }
-
- pub unsafe fn drop_handler(_handler: &mut super::Handler) {
- }
-}
diff --git a/ctr-std/src/sys/unix/stdio.rs b/ctr-std/src/sys/unix/stdio.rs
deleted file mode 100644
index 87ba2ae..0000000
--- a/ctr-std/src/sys/unix/stdio.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use io;
-use libc;
-use sys::fd::FileDesc;
-
-pub struct Stdin(());
-pub struct Stdout(());
-pub struct Stderr(());
-
-impl Stdin {
- pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }
-
- pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
- let fd = FileDesc::new(libc::STDIN_FILENO);
- let ret = fd.read(data);
- fd.into_raw();
- ret
- }
-}
-
-impl Stdout {
- pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }
-
- pub fn write(&self, data: &[u8]) -> io::Result<usize> {
- let fd = FileDesc::new(libc::STDOUT_FILENO);
- let ret = fd.write(data);
- fd.into_raw();
- ret
- }
-
- pub fn flush(&self) -> io::Result<()> {
- Ok(())
- }
-}
-
-impl Stderr {
- pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }
-
- pub fn write(&self, data: &[u8]) -> io::Result<usize> {
- let fd = FileDesc::new(libc::STDERR_FILENO);
- let ret = fd.write(data);
- fd.into_raw();
- ret
- }
-
- pub fn flush(&self) -> io::Result<()> {
- Ok(())
- }
-}
-
-// FIXME: right now this raw stderr handle is used in a few places because
-// std::io::stderr_raw isn't exposed, but once that's exposed this impl
-// should go away
-impl io::Write for Stderr {
- fn write(&mut self, data: &[u8]) -> io::Result<usize> {
- Stderr::write(self, data)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- Stderr::flush(self)
- }
-}
-
-pub fn is_ebadf(err: &io::Error) -> bool {
- err.raw_os_error() == Some(libc::EBADF as i32)
-}
-
-pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;
-
-pub fn stderr_prints_nothing() -> bool {
- false
-}
diff --git a/ctr-std/src/sys/unix/thread.rs b/ctr-std/src/sys/unix/thread.rs
deleted file mode 100644
index f3a45d2..0000000
--- a/ctr-std/src/sys/unix/thread.rs
+++ /dev/null
@@ -1,458 +0,0 @@
-// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use boxed::FnBox;
-use cmp;
-use ffi::CStr;
-use io;
-use libc;
-use mem;
-use ptr;
-use sys::os;
-use time::Duration;
-
-use sys_common::thread::*;
-
-#[cfg(not(target_os = "l4re"))]
-pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
-#[cfg(target_os = "l4re")]
-pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
-
-pub struct Thread {
- id: libc::pthread_t,
-}
-
-// Some platforms may have 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 {}
-
-// The pthread_attr_setstacksize symbol doesn't exist in the emscripten libc,
-// so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS.
-#[cfg(not(target_os = "emscripten"))]
-unsafe fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
- stack_size: libc::size_t) -> libc::c_int {
- libc::pthread_attr_setstacksize(attr, stack_size)
-}
-
-#[cfg(target_os = "emscripten")]
-unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
- _stack_size: libc::size_t) -> libc::c_int {
- panic!()
-}
-
-impl Thread {
- pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>)
- -> io::Result<Thread> {
- let p = 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));
-
- match pthread_attr_setstacksize(&mut attr,
- stack_size) {
- 0 => {}
- n => {
- assert_eq!(n, libc::EINVAL);
- // EINVAL means |stack_size| is either too small or not a
- // multiple of the system page size. Because it's definitely
- // >= PTHREAD_STACK_MIN, it must be an alignment issue.
- // Round up to the nearest page and try again.
- let page_size = os::page_size();
- let stack_size = (stack_size + page_size - 1) &
- (-(page_size as isize - 1) as usize - 1);
- assert_eq!(libc::pthread_attr_setstacksize(&mut attr,
- stack_size), 0);
- }
- };
-
- let ret = libc::pthread_create(&mut native, &attr, thread_start,
- &*p as *const _ as *mut _);
- assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
-
- return if ret != 0 {
- Err(io::Error::from_raw_os_error(ret))
- } else {
- mem::forget(p); // ownership passed to pthread_create
- Ok(Thread { id: native })
- };
-
- extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
- unsafe { start_thread(main as *mut u8); }
- ptr::null_mut()
- }
- }
-
- pub fn yield_now() {
- let ret = unsafe { libc::sched_yield() };
- debug_assert_eq!(ret, 0);
- }
-
- #[cfg(any(target_os = "linux",
- target_os = "android"))]
- pub fn set_name(name: &CStr) {
- const PR_SET_NAME: libc::c_int = 15;
- // pthread wrapper only appeared in glibc 2.12, so we use syscall
- // directly.
- unsafe {
- libc::prctl(PR_SET_NAME, name.as_ptr() as libc::c_ulong, 0, 0, 0);
- }
- }
-
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "bitrig",
- target_os = "openbsd"))]
- pub fn set_name(name: &CStr) {
- unsafe {
- libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr());
- }
- }
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- pub fn set_name(name: &CStr) {
- unsafe {
- libc::pthread_setname_np(name.as_ptr());
- }
- }
-
- #[cfg(target_os = "netbsd")]
- pub fn set_name(name: &CStr) {
- use ffi::CString;
- let cname = CString::new(&b"%s"[..]).unwrap();
- unsafe {
- libc::pthread_setname_np(libc::pthread_self(), cname.as_ptr(),
- name.as_ptr() as *mut libc::c_void);
- }
- }
- #[cfg(any(target_env = "newlib",
- target_os = "solaris",
- target_os = "haiku",
- target_os = "l4re",
- target_os = "emscripten",
- target_os = "hermit"))]
- pub fn set_name(_name: &CStr) {
- // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name.
- }
- #[cfg(target_os = "fuchsia")]
- pub fn set_name(_name: &CStr) {
- // FIXME: determine whether Fuchsia has a way to set a thread name.
- }
-
- pub fn sleep(dur: Duration) {
- let mut secs = dur.as_secs();
- let mut nsecs = dur.subsec_nanos() as _;
-
- // If we're awoken with a signal then the return value will be -1 and
- // nanosleep will fill in `ts` with the remaining time.
- unsafe {
- while secs > 0 || nsecs > 0 {
- let mut ts = libc::timespec {
- tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t,
- tv_nsec: nsecs,
- };
- secs -= ts.tv_sec as u64;
- if libc::nanosleep(&ts, &mut ts) == -1 {
- assert_eq!(os::errno(), libc::EINTR);
- secs += ts.tv_sec as u64;
- nsecs = ts.tv_nsec;
- } else {
- nsecs = 0;
- }
- }
- }
- }
-
- 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));
- }
- }
-
- pub fn id(&self) -> libc::pthread_t { self.id }
-
- pub fn into_id(self) -> libc::pthread_t {
- let id = self.id;
- mem::forget(self);
- id
- }
-}
-
-impl Drop for Thread {
- fn drop(&mut self) {
- let ret = unsafe { libc::pthread_detach(self.id) };
- debug_assert_eq!(ret, 0);
- }
-}
-
-#[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))),
- not(target_os = "freebsd"),
- not(target_os = "macos"),
- not(target_os = "bitrig"),
- not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
- not(target_os = "openbsd"),
- not(target_os = "solaris")))]
-#[cfg_attr(test, allow(dead_code))]
-pub mod guard {
- use ops::Range;
- pub type Guard = Range<usize>;
- pub unsafe fn current() -> Option<Guard> { None }
- pub unsafe fn init() -> Option<Guard> { None }
- pub unsafe fn deinit() {}
-}
-
-
-#[cfg(any(all(target_os = "linux", not(target_env = "musl")),
- target_os = "freebsd",
- target_os = "macos",
- target_os = "bitrig",
- all(target_os = "netbsd", not(target_vendor = "rumprun")),
- target_os = "openbsd",
- target_os = "solaris"))]
-#[cfg_attr(test, allow(dead_code))]
-pub mod guard {
- use libc;
- use libc::{mmap, mprotect};
- use libc::{PROT_NONE, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
- use ops::Range;
- use sys::os;
-
- // This is initialized in init() and only read from after
- static mut PAGE_SIZE: usize = 0;
-
- pub type Guard = Range<usize>;
-
- #[cfg(target_os = "solaris")]
- unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
- let mut current_stack: libc::stack_t = ::mem::zeroed();
- assert_eq!(libc::stack_getbounds(&mut current_stack), 0);
- Some(current_stack.ss_sp)
- }
-
- #[cfg(target_os = "macos")]
- unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
- let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize -
- libc::pthread_get_stacksize_np(libc::pthread_self());
- Some(stackaddr as *mut libc::c_void)
- }
-
- #[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
- unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
- let mut current_stack: libc::stack_t = ::mem::zeroed();
- assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(),
- &mut current_stack), 0);
-
- let extra = if cfg!(target_os = "bitrig") {3} else {1} * PAGE_SIZE;
- let stackaddr = if libc::pthread_main_np() == 1 {
- // main thread
- current_stack.ss_sp as usize - current_stack.ss_size + extra
- } else {
- // new thread
- current_stack.ss_sp as usize - current_stack.ss_size
- };
- Some(stackaddr as *mut libc::c_void)
- }
-
- #[cfg(any(target_os = "android", target_os = "freebsd",
- target_os = "linux", target_os = "netbsd", target_os = "l4re"))]
- unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
- let mut ret = None;
- let mut attr: libc::pthread_attr_t = ::mem::zeroed();
- assert_eq!(libc::pthread_attr_init(&mut attr), 0);
- #[cfg(target_os = "freebsd")]
- let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr);
- #[cfg(not(target_os = "freebsd"))]
- let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr);
- if e == 0 {
- let mut stackaddr = ::ptr::null_mut();
- let mut stacksize = 0;
- assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
- &mut stacksize), 0);
- ret = Some(stackaddr);
- }
- assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
- ret
- }
-
- // Precondition: PAGE_SIZE is initialized.
- unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> {
- assert!(PAGE_SIZE != 0);
- let stackaddr = get_stack_start()?;
-
- // Ensure stackaddr is page aligned! A parent process might
- // have reset RLIMIT_STACK to be non-page aligned. The
- // pthread_attr_getstack() reports the usable stack area
- // stackaddr < stackaddr + stacksize, so if stackaddr is not
- // page-aligned, calculate the fix such that stackaddr <
- // new_page_aligned_stackaddr < stackaddr + stacksize
- let remainder = (stackaddr as usize) % PAGE_SIZE;
- Some(if remainder == 0 {
- stackaddr
- } else {
- ((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void
- })
- }
-
- pub unsafe fn init() -> Option<Guard> {
- PAGE_SIZE = os::page_size();
-
- let stackaddr = get_stack_start_aligned()?;
-
- if cfg!(target_os = "linux") {
- // Linux doesn't allocate the whole stack right away, and
- // the kernel has its own stack-guard mechanism to fault
- // when growing too close to an existing mapping. If we map
- // our own guard, then the kernel starts enforcing a rather
- // large gap above that, rendering much of the possible
- // stack space useless. See #43052.
- //
- // Instead, we'll just note where we expect rlimit to start
- // faulting, so our handler can report "stack overflow", and
- // trust that the kernel's own stack guard will work.
- let stackaddr = stackaddr as usize;
- Some(stackaddr - PAGE_SIZE..stackaddr)
- } else {
- // Reallocate the last page of the stack.
- // This ensures SIGBUS will be raised on
- // stack overflow.
- // Systems which enforce strict PAX MPROTECT do not allow
- // to mprotect() a mapping with less restrictive permissions
- // than the initial mmap() used, so we mmap() here with
- // read/write permissions and only then mprotect() it to
- // no permissions at all. See issue #50313.
- let result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
- if result != stackaddr || result == MAP_FAILED {
- panic!("failed to allocate a guard page");
- }
-
- let result = mprotect(stackaddr, PAGE_SIZE, PROT_NONE);
- if result != 0 {
- panic!("failed to protect the guard page");
- }
-
- let guardaddr = stackaddr as usize;
- let offset = if cfg!(target_os = "freebsd") {
- 2
- } else {
- 1
- };
-
- Some(guardaddr..guardaddr + offset * PAGE_SIZE)
- }
- }
-
- pub unsafe fn deinit() {
- if !cfg!(target_os = "linux") {
- if let Some(stackaddr) = get_stack_start_aligned() {
- // Remove the protection on the guard page.
- // FIXME: we cannot unmap the page, because when we mmap()
- // above it may be already mapped by the OS, which we can't
- // detect from mmap()'s return value. If we unmap this page,
- // it will lead to failure growing stack size on platforms like
- // macOS. Instead, just restore the page to a writable state.
- // This ain't Linux, so we probably don't need to care about
- // execstack.
- let result = mprotect(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE);
-
- if result != 0 {
- panic!("unable to reset the guard page");
- }
- }
- }
- }
-
- #[cfg(any(target_os = "macos",
- target_os = "bitrig",
- target_os = "openbsd",
- target_os = "solaris"))]
- pub unsafe fn current() -> Option<Guard> {
- let stackaddr = get_stack_start()? as usize;
- Some(stackaddr - PAGE_SIZE..stackaddr)
- }
-
- #[cfg(any(target_os = "android", target_os = "freebsd",
- target_os = "linux", target_os = "netbsd", target_os = "l4re"))]
- pub unsafe fn current() -> Option<Guard> {
- let mut ret = None;
- let mut attr: libc::pthread_attr_t = ::mem::zeroed();
- assert_eq!(libc::pthread_attr_init(&mut attr), 0);
- #[cfg(target_os = "freebsd")]
- let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr);
- #[cfg(not(target_os = "freebsd"))]
- let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr);
- if e == 0 {
- let mut guardsize = 0;
- assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0);
- if guardsize == 0 {
- panic!("there is no guard page");
- }
- let mut stackaddr = ::ptr::null_mut();
- let mut size = 0;
- assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
- &mut size), 0);
-
- let stackaddr = stackaddr as usize;
- ret = if cfg!(target_os = "freebsd") {
- // FIXME does freebsd really fault *below* the guard addr?
- let guardaddr = stackaddr - guardsize;
- Some(guardaddr - PAGE_SIZE..guardaddr)
- } else if cfg!(target_os = "netbsd") {
- Some(stackaddr - guardsize..stackaddr)
- } else if cfg!(all(target_os = "linux", target_env = "gnu")) {
- // glibc used to include the guard area within the stack, as noted in the BUGS
- // section of `man pthread_attr_getguardsize`. This has been corrected starting
- // with glibc 2.27, and in some distro backports, so the guard is now placed at the
- // end (below) the stack. There's no easy way for us to know which we have at
- // runtime, so we'll just match any fault in the range right above or below the
- // stack base to call that fault a stack overflow.
- Some(stackaddr - guardsize..stackaddr + guardsize)
- } else {
- Some(stackaddr..stackaddr + guardsize)
- };
- }
- assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
- ret
- }
-}
-
-// glibc >= 2.15 has a __pthread_get_minstack() function that returns
-// PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
-// storage. We need that information to avoid blowing up when a small stack
-// is created in an application with big thread-local storage requirements.
-// See #6233 for rationale and details.
-#[cfg(target_os = "linux")]
-#[allow(deprecated)]
-fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
- weak!(fn __pthread_get_minstack(*const libc::pthread_attr_t) -> libc::size_t);
-
- match __pthread_get_minstack.get() {
- None => libc::PTHREAD_STACK_MIN,
- Some(f) => unsafe { f(attr) },
- }
-}
-
-// No point in looking up __pthread_get_minstack() on non-glibc
-// platforms.
-#[cfg(all(not(target_os = "linux"),
- not(target_os = "netbsd")))]
-fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
- libc::PTHREAD_STACK_MIN
-}
-
-#[cfg(target_os = "netbsd")]
-fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
- 2048 // just a guess
-}
diff --git a/ctr-std/src/sys/unix/thread_local.rs b/ctr-std/src/sys/unix/thread_local.rs
deleted file mode 100644
index 2487f6b..0000000
--- a/ctr-std/src/sys/unix/thread_local.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(dead_code)] // not used on all platforms
-
-use mem;
-use libc;
-
-pub type Key = libc::pthread_key_t;
-
-#[inline]
-pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
- let mut key = 0;
- assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0);
- key
-}
-
-#[inline]
-pub unsafe fn set(key: Key, value: *mut u8) {
- let r = libc::pthread_setspecific(key, value as *mut _);
- debug_assert_eq!(r, 0);
-}
-
-#[inline]
-pub unsafe fn get(key: Key) -> *mut u8 {
- libc::pthread_getspecific(key) as *mut u8
-}
-
-#[inline]
-pub unsafe fn destroy(key: Key) {
- let r = libc::pthread_key_delete(key);
- debug_assert_eq!(r, 0);
-}
-
-#[inline]
-pub fn requires_synchronized_create() -> bool {
- false
-}
diff --git a/ctr-std/src/sys/unix/time.rs b/ctr-std/src/sys/unix/time.rs
deleted file mode 100644
index 0b1fb72..0000000
--- a/ctr-std/src/sys/unix/time.rs
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use cmp::Ordering;
-use libc;
-use time::Duration;
-use core::hash::{Hash, Hasher};
-
-pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
-use convert::TryInto;
-
-const NSEC_PER_SEC: u64 = 1_000_000_000;
-
-#[derive(Copy, Clone)]
-struct Timespec {
- t: libc::timespec,
-}
-
-impl Timespec {
- fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
- if self >= other {
- Ok(if self.t.tv_nsec >= other.t.tv_nsec {
- Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
- (self.t.tv_nsec - other.t.tv_nsec) as u32)
- } else {
- Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
- self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
- other.t.tv_nsec as u32)
- })
- } else {
- match other.sub_timespec(self) {
- Ok(d) => Err(d),
- Err(d) => Ok(d),
- }
- }
- }
-
- fn add_duration(&self, other: &Duration) -> Timespec {
- let mut secs = other
- .as_secs()
- .try_into() // <- target type would be `libc::time_t`
- .ok()
- .and_then(|secs| self.t.tv_sec.checked_add(secs))
- .expect("overflow when adding duration to time");
-
- // Nano calculations can't overflow because nanos are <1B which fit
- // in a u32.
- let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
- if nsec >= NSEC_PER_SEC as u32 {
- nsec -= NSEC_PER_SEC as u32;
- secs = secs.checked_add(1).expect("overflow when adding \
- duration to time");
- }
- Timespec {
- t: libc::timespec {
- tv_sec: secs,
- tv_nsec: nsec as _,
- },
- }
- }
-
- fn sub_duration(&self, other: &Duration) -> Timespec {
- let mut secs = other
- .as_secs()
- .try_into() // <- target type would be `libc::time_t`
- .ok()
- .and_then(|secs| self.t.tv_sec.checked_sub(secs))
- .expect("overflow when subtracting duration from time");
-
- // Similar to above, nanos can't overflow.
- let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
- if nsec < 0 {
- nsec += NSEC_PER_SEC as i32;
- secs = secs.checked_sub(1).expect("overflow when subtracting \
- duration from time");
- }
- Timespec {
- t: libc::timespec {
- tv_sec: secs,
- tv_nsec: nsec as _,
- },
- }
- }
-}
-
-impl PartialEq for Timespec {
- fn eq(&self, other: &Timespec) -> bool {
- self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
- }
-}
-
-impl Eq for Timespec {}
-
-impl PartialOrd for Timespec {
- fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl Ord for Timespec {
- fn cmp(&self, other: &Timespec) -> Ordering {
- let me = (self.t.tv_sec, self.t.tv_nsec);
- let other = (other.t.tv_sec, other.t.tv_nsec);
- me.cmp(&other)
- }
-}
-
-impl Hash for Timespec {
- fn hash<H : Hasher>(&self, state: &mut H) {
- self.t.tv_sec.hash(state);
- self.t.tv_nsec.hash(state);
- }
-}
-
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-mod inner {
- use fmt;
- use libc;
- use sync::Once;
- use sys::cvt;
- use sys_common::mul_div_u64;
- use time::Duration;
-
- use super::NSEC_PER_SEC;
- use super::Timespec;
-
- #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
- pub struct Instant {
- t: u64
- }
-
- #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- pub struct SystemTime {
- t: Timespec,
- }
-
- pub const UNIX_EPOCH: SystemTime = SystemTime {
- t: Timespec {
- t: libc::timespec {
- tv_sec: 0,
- tv_nsec: 0,
- },
- },
- };
-
- impl Instant {
- pub fn now() -> Instant {
- Instant { t: unsafe { libc::mach_absolute_time() } }
- }
-
- pub fn sub_instant(&self, other: &Instant) -> Duration {
- let info = info();
- let diff = self.t.checked_sub(other.t)
- .expect("second instant is later than self");
- let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
- Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
- }
-
- pub fn add_duration(&self, other: &Duration) -> Instant {
- Instant {
- t: self.t.checked_add(dur2intervals(other))
- .expect("overflow when adding duration to instant"),
- }
- }
-
- pub fn sub_duration(&self, other: &Duration) -> Instant {
- Instant {
- t: self.t.checked_sub(dur2intervals(other))
- .expect("overflow when subtracting duration from instant"),
- }
- }
- }
-
- impl SystemTime {
- pub fn now() -> SystemTime {
- use ptr;
-
- let mut s = libc::timeval {
- tv_sec: 0,
- tv_usec: 0,
- };
- cvt(unsafe {
- libc::gettimeofday(&mut s, ptr::null_mut())
- }).unwrap();
- return SystemTime::from(s)
- }
-
- pub fn sub_time(&self, other: &SystemTime)
- -> Result<Duration, Duration> {
- self.t.sub_timespec(&other.t)
- }
-
- pub fn add_duration(&self, other: &Duration) -> SystemTime {
- SystemTime { t: self.t.add_duration(other) }
- }
-
- pub fn sub_duration(&self, other: &Duration) -> SystemTime {
- SystemTime { t: self.t.sub_duration(other) }
- }
- }
-
- impl From<libc::timeval> for SystemTime {
- fn from(t: libc::timeval) -> SystemTime {
- SystemTime::from(libc::timespec {
- tv_sec: t.tv_sec,
- tv_nsec: (t.tv_usec * 1000) as libc::c_long,
- })
- }
- }
-
- impl From<libc::timespec> for SystemTime {
- fn from(t: libc::timespec) -> SystemTime {
- SystemTime { t: Timespec { t: t } }
- }
- }
-
- impl fmt::Debug for SystemTime {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("SystemTime")
- .field("tv_sec", &self.t.t.tv_sec)
- .field("tv_nsec", &self.t.t.tv_nsec)
- .finish()
- }
- }
-
- fn dur2intervals(dur: &Duration) -> u64 {
- let info = info();
- let nanos = dur.as_secs().checked_mul(NSEC_PER_SEC).and_then(|nanos| {
- nanos.checked_add(dur.subsec_nanos() as u64)
- }).expect("overflow converting duration to nanoseconds");
- mul_div_u64(nanos, info.denom as u64, info.numer as u64)
- }
-
- fn info() -> &'static libc::mach_timebase_info {
- static mut INFO: libc::mach_timebase_info = libc::mach_timebase_info {
- numer: 0,
- denom: 0,
- };
- static ONCE: Once = Once::new();
-
- unsafe {
- ONCE.call_once(|| {
- libc::mach_timebase_info(&mut INFO);
- });
- &INFO
- }
- }
-}
-
-#[cfg(not(any(target_os = "macos", target_os = "ios")))]
-mod inner {
- use fmt;
- use libc;
- use sys::cvt;
- use time::Duration;
-
- use super::Timespec;
-
- #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- pub struct Instant {
- t: Timespec,
- }
-
- #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- pub struct SystemTime {
- t: Timespec,
- }
-
- pub const UNIX_EPOCH: SystemTime = SystemTime {
- t: Timespec {
- t: libc::timespec {
- tv_sec: 0,
- tv_nsec: 0,
- },
- },
- };
-
- impl Instant {
- pub fn now() -> Instant {
- Instant { t: now(libc::CLOCK_MONOTONIC) }
- }
-
- pub fn sub_instant(&self, other: &Instant) -> Duration {
- self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
- panic!("specified instant was later than self")
- })
- }
-
- pub fn add_duration(&self, other: &Duration) -> Instant {
- Instant { t: self.t.add_duration(other) }
- }
-
- pub fn sub_duration(&self, other: &Duration) -> Instant {
- Instant { t: self.t.sub_duration(other) }
- }
- }
-
- impl fmt::Debug for Instant {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("Instant")
- .field("tv_sec", &self.t.t.tv_sec)
- .field("tv_nsec", &self.t.t.tv_nsec)
- .finish()
- }
- }
-
- impl SystemTime {
- pub fn now() -> SystemTime {
- SystemTime { t: now(libc::CLOCK_REALTIME) }
- }
-
- pub fn sub_time(&self, other: &SystemTime)
- -> Result<Duration, Duration> {
- self.t.sub_timespec(&other.t)
- }
-
- pub fn add_duration(&self, other: &Duration) -> SystemTime {
- SystemTime { t: self.t.add_duration(other) }
- }
-
- pub fn sub_duration(&self, other: &Duration) -> SystemTime {
- SystemTime { t: self.t.sub_duration(other) }
- }
- }
-
- impl From<libc::timespec> for SystemTime {
- fn from(t: libc::timespec) -> SystemTime {
- SystemTime { t: Timespec { t: t } }
- }
- }
-
- impl fmt::Debug for SystemTime {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("SystemTime")
- .field("tv_sec", &self.t.t.tv_sec)
- .field("tv_nsec", &self.t.t.tv_nsec)
- .finish()
- }
- }
-
- #[cfg(not(any(target_os = "dragonfly", target_os = "hermit")))]
- pub type clock_t = libc::c_int;
- #[cfg(any(target_os = "dragonfly", target_os = "hermit"))]
- pub type clock_t = libc::c_ulong;
-
- fn now(clock: clock_t) -> Timespec {
- let mut t = Timespec {
- t: libc::timespec {
- tv_sec: 0,
- tv_nsec: 0,
- }
- };
- cvt(unsafe {
- libc::clock_gettime(clock, &mut t.t)
- }).unwrap();
- t
- }
-}
diff --git a/ctr-std/src/sys/unix/weak.rs b/ctr-std/src/sys/unix/weak.rs
deleted file mode 100644
index 18944be..0000000
--- a/ctr-std/src/sys/unix/weak.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Support for "weak linkage" to symbols on Unix
-//!
-//! Some I/O operations we do in libstd require newer versions of OSes but we
-//! need to maintain binary compatibility with older releases for now. In order
-//! to use the new functionality when available we use this module for
-//! detection.
-//!
-//! One option to use here is weak linkage, but that is unfortunately only
-//! really workable on Linux. Hence, use dlsym to get the symbol value at
-//! runtime. This is also done for compatibility with older versions of glibc,
-//! and to avoid creating dependencies on GLIBC_PRIVATE symbols. It assumes that
-//! we've been dynamically linked to the library the symbol comes from, but that
-//! is currently always the case for things like libpthread/libc.
-//!
-//! A long time ago this used weak linkage for the __pthread_get_minstack
-//! symbol, but that caused Debian to detect an unnecessarily strict versioned
-//! dependency on libc6 (#23628).
-
-use libc;
-
-use ffi::CString;
-use marker;
-use mem;
-use sync::atomic::{AtomicUsize, Ordering};
-
-macro_rules! weak {
- (fn $name:ident($($t:ty),*) -> $ret:ty) => (
- static $name: ::sys::weak::Weak<unsafe extern fn($($t),*) -> $ret> =
- ::sys::weak::Weak::new(stringify!($name));
- )
-}
-
-pub struct Weak<F> {
- name: &'static str,
- addr: AtomicUsize,
- _marker: marker::PhantomData<F>,
-}
-
-impl<F> Weak<F> {
- pub const fn new(name: &'static str) -> Weak<F> {
- Weak {
- name,
- addr: AtomicUsize::new(1),
- _marker: marker::PhantomData,
- }
- }
-
- pub fn get(&self) -> Option<&F> {
- assert_eq!(mem::size_of::<F>(), mem::size_of::<usize>());
- unsafe {
- if self.addr.load(Ordering::SeqCst) == 1 {
- self.addr.store(fetch(self.name), Ordering::SeqCst);
- }
- if self.addr.load(Ordering::SeqCst) == 0 {
- None
- } else {
- mem::transmute::<&AtomicUsize, Option<&F>>(&self.addr)
- }
- }
- }
-}
-
-unsafe fn fetch(name: &str) -> usize {
- let name = match CString::new(name) {
- Ok(cstr) => cstr,
- Err(..) => return 0,
- };
- libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) as usize
-}