From 0498da9a3dc061f604fcfb9b56bd889e07f2b7e2 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 7 Apr 2019 08:39:54 -0600 Subject: [PATCH 1/2] redox: convert to target_family unix --- .../unstable-book/src/library-features/n16.md | 5 - src/libpanic_abort/lib.rs | 3 +- .../spec/aarch64_unknown_redox.rs | 20 + src/librustc_target/spec/mod.rs | 1 + src/librustc_target/spec/redox_base.rs | 15 +- .../spec/x86_64_unknown_redox.rs | 2 +- src/libstd/os/mod.rs | 1 + src/libstd/os/redox/fs.rs | 383 +++++++++ src/libstd/os/redox/mod.rs | 6 + src/libstd/os/redox/raw.rs | 67 ++ src/libstd/path.rs | 2 +- src/libstd/sys/mod.rs | 5 +- src/libstd/sys/redox/args.rs | 96 --- src/libstd/sys/redox/cmath.rs | 33 - src/libstd/sys/redox/condvar.rs | 111 --- src/libstd/sys/redox/env.rs | 9 - src/libstd/sys/redox/ext/ffi.rs | 38 - src/libstd/sys/redox/ext/fs.rs | 339 -------- src/libstd/sys/redox/ext/io.rs | 172 ---- src/libstd/sys/redox/ext/mod.rs | 45 -- src/libstd/sys/redox/ext/net.rs | 759 ------------------ src/libstd/sys/redox/ext/process.rs | 197 ----- src/libstd/sys/redox/ext/thread.rs | 39 - src/libstd/sys/redox/fast_thread_local.rs | 4 - src/libstd/sys/redox/fd.rs | 88 -- src/libstd/sys/redox/fs.rs | 447 ----------- src/libstd/sys/redox/io.rs | 46 -- src/libstd/sys/redox/memchr.rs | 4 - src/libstd/sys/redox/mod.rs | 96 --- src/libstd/sys/redox/mutex.rs | 169 ---- src/libstd/sys/redox/net/dns/answer.rs | 12 - src/libstd/sys/redox/net/dns/mod.rs | 205 ----- src/libstd/sys/redox/net/dns/query.rs | 8 - src/libstd/sys/redox/net/mod.rs | 140 ---- src/libstd/sys/redox/net/netc.rs | 47 -- src/libstd/sys/redox/net/tcp.rs | 251 ------ src/libstd/sys/redox/net/udp.rs | 237 ------ src/libstd/sys/redox/os.rs | 241 ------ src/libstd/sys/redox/path.rs | 29 - src/libstd/sys/redox/pipe.rs | 101 --- src/libstd/sys/redox/process.rs | 609 -------------- src/libstd/sys/redox/rand.rs | 3 - src/libstd/sys/redox/rwlock.rs | 51 -- src/libstd/sys/redox/stack_overflow.rs | 17 - src/libstd/sys/redox/stdio.rs | 64 -- src/libstd/sys/redox/syscall/arch/arm.rs | 73 -- src/libstd/sys/redox/syscall/arch/x86.rs | 73 -- src/libstd/sys/redox/syscall/arch/x86_64.rs | 74 -- src/libstd/sys/redox/syscall/call.rs | 348 -------- src/libstd/sys/redox/syscall/data.rs | 191 ----- src/libstd/sys/redox/syscall/error.rs | 315 -------- src/libstd/sys/redox/syscall/flag.rs | 148 ---- src/libstd/sys/redox/syscall/mod.rs | 33 - src/libstd/sys/redox/syscall/number.rs | 73 -- src/libstd/sys/redox/thread.rs | 84 -- src/libstd/sys/redox/thread_local.rs | 61 -- src/libstd/sys/redox/time.rs | 207 ----- src/libstd/sys/unix/args.rs | 3 +- src/libstd/sys/unix/condvar.rs | 6 +- src/libstd/sys/unix/env.rs | 11 + src/libstd/sys/unix/fast_thread_local.rs | 2 +- src/libstd/sys/unix/fd.rs | 6 +- src/libstd/sys/unix/fs.rs | 15 +- src/libstd/sys/unix/mod.rs | 1 + src/libstd/sys/unix/os.rs | 30 +- src/libstd/sys/unix/pipe.rs | 3 +- src/libstd/sys/unix/process/process_common.rs | 10 +- src/libstd/sys/unix/process/process_unix.rs | 19 +- src/libstd/sys/unix/rand.rs | 15 +- src/libstd/sys/unix/thread.rs | 3 +- src/libstd/sys_common/mod.rs | 1 - src/libunwind/build.rs | 2 +- src/libunwind/lib.rs | 5 + src/tools/build-manifest/src/main.rs | 1 + 74 files changed, 590 insertions(+), 6440 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/n16.md create mode 100644 src/librustc_target/spec/aarch64_unknown_redox.rs create mode 100644 src/libstd/os/redox/fs.rs create mode 100644 src/libstd/os/redox/mod.rs create mode 100644 src/libstd/os/redox/raw.rs delete mode 100644 src/libstd/sys/redox/args.rs delete mode 100644 src/libstd/sys/redox/cmath.rs delete mode 100644 src/libstd/sys/redox/condvar.rs delete mode 100644 src/libstd/sys/redox/env.rs delete mode 100644 src/libstd/sys/redox/ext/ffi.rs delete mode 100644 src/libstd/sys/redox/ext/fs.rs delete mode 100644 src/libstd/sys/redox/ext/io.rs delete mode 100644 src/libstd/sys/redox/ext/mod.rs delete mode 100644 src/libstd/sys/redox/ext/net.rs delete mode 100644 src/libstd/sys/redox/ext/process.rs delete mode 100644 src/libstd/sys/redox/ext/thread.rs delete mode 100644 src/libstd/sys/redox/fast_thread_local.rs delete mode 100644 src/libstd/sys/redox/fd.rs delete mode 100644 src/libstd/sys/redox/fs.rs delete mode 100644 src/libstd/sys/redox/io.rs delete mode 100644 src/libstd/sys/redox/memchr.rs delete mode 100644 src/libstd/sys/redox/mod.rs delete mode 100644 src/libstd/sys/redox/mutex.rs delete mode 100644 src/libstd/sys/redox/net/dns/answer.rs delete mode 100644 src/libstd/sys/redox/net/dns/mod.rs delete mode 100644 src/libstd/sys/redox/net/dns/query.rs delete mode 100644 src/libstd/sys/redox/net/mod.rs delete mode 100644 src/libstd/sys/redox/net/netc.rs delete mode 100644 src/libstd/sys/redox/net/tcp.rs delete mode 100644 src/libstd/sys/redox/net/udp.rs delete mode 100644 src/libstd/sys/redox/os.rs delete mode 100644 src/libstd/sys/redox/path.rs delete mode 100644 src/libstd/sys/redox/pipe.rs delete mode 100644 src/libstd/sys/redox/process.rs delete mode 100644 src/libstd/sys/redox/rand.rs delete mode 100644 src/libstd/sys/redox/rwlock.rs delete mode 100644 src/libstd/sys/redox/stack_overflow.rs delete mode 100644 src/libstd/sys/redox/stdio.rs delete mode 100644 src/libstd/sys/redox/syscall/arch/arm.rs delete mode 100644 src/libstd/sys/redox/syscall/arch/x86.rs delete mode 100644 src/libstd/sys/redox/syscall/arch/x86_64.rs delete mode 100644 src/libstd/sys/redox/syscall/call.rs delete mode 100644 src/libstd/sys/redox/syscall/data.rs delete mode 100644 src/libstd/sys/redox/syscall/error.rs delete mode 100644 src/libstd/sys/redox/syscall/flag.rs delete mode 100644 src/libstd/sys/redox/syscall/mod.rs delete mode 100644 src/libstd/sys/redox/syscall/number.rs delete mode 100644 src/libstd/sys/redox/thread.rs delete mode 100644 src/libstd/sys/redox/thread_local.rs delete mode 100644 src/libstd/sys/redox/time.rs diff --git a/src/doc/unstable-book/src/library-features/n16.md b/src/doc/unstable-book/src/library-features/n16.md deleted file mode 100644 index e556adaa13ea7..0000000000000 --- a/src/doc/unstable-book/src/library-features/n16.md +++ /dev/null @@ -1,5 +0,0 @@ -# `n16` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index ee9dd858ef45f..fd144d6b67e75 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -48,8 +48,7 @@ pub unsafe extern fn __rust_start_panic(_payload: usize) -> u32 { libc::abort(); } - #[cfg(any(target_os = "redox", - windows, + #[cfg(any(windows, all(target_arch = "wasm32", not(target_os = "emscripten"))))] unsafe fn abort() -> ! { core::intrinsics::abort(); diff --git a/src/librustc_target/spec/aarch64_unknown_redox.rs b/src/librustc_target/spec/aarch64_unknown_redox.rs new file mode 100644 index 0000000000000..f347a2dba53f3 --- /dev/null +++ b/src/librustc_target/spec/aarch64_unknown_redox.rs @@ -0,0 +1,20 @@ +use crate::spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::redox_base::opts(); + base.max_atomic_width = Some(128); + + Ok(Target { + llvm_target: "aarch64-unknown-redox".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), + arch: "aarch64".to_string(), + target_os: "redox".to_string(), + target_env: "relibc".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: base, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index b7b6627bbd8ab..ec72c00c28f61 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -417,6 +417,7 @@ supported_targets! { ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc), + ("aarch64-unknown-redox", aarch64_unknown_redox), ("x86_64-unknown-redox", x86_64_unknown_redox), ("i386-apple-ios", i386_apple_ios), diff --git a/src/librustc_target/spec/redox_base.rs b/src/librustc_target/spec/redox_base.rs index dc51aeb58391f..7226ad1582819 100644 --- a/src/librustc_target/spec/redox_base.rs +++ b/src/librustc_target/spec/redox_base.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel}; use std::default::Default; pub fn opts() -> TargetOptions { @@ -18,14 +18,17 @@ pub fn opts() -> TargetOptions { ]); TargetOptions { - pre_link_args: args, + dynamic_linking: true, executables: true, - relocation_model: "static".to_string(), - disable_redzone: true, - eliminate_frame_pointer: false, - target_family: None, + target_family: Some("unix".to_string()), linker_is_gnu: true, + has_rpath: true, + pre_link_args: args, + position_independent_executables: true, + relro_level: RelroLevel::Full, has_elf_tls: true, + crt_static_default: true, + crt_static_respected: true, .. Default::default() } } diff --git a/src/librustc_target/spec/x86_64_unknown_redox.rs b/src/librustc_target/spec/x86_64_unknown_redox.rs index f0a4519f59548..8a5af27f13aac 100644 --- a/src/librustc_target/spec/x86_64_unknown_redox.rs +++ b/src/librustc_target/spec/x86_64_unknown_redox.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(), arch: "x86_64".to_string(), target_os: "redox".to_string(), - target_env: String::new(), + target_env: "relibc".to_string(), target_vendor: "unknown".to_string(), linker_flavor: LinkerFlavor::Gcc, options: base, diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index c9aa5f4de9553..fcd81f0a1b2de 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -50,6 +50,7 @@ cfg_if::cfg_if! { #[cfg(target_os = "emscripten")] pub mod emscripten; #[cfg(target_os = "fuchsia")] pub mod fuchsia; #[cfg(target_os = "hermit")] pub mod hermit; +#[cfg(target_os = "redox")] pub mod redox; #[cfg(target_os = "wasi")] pub mod wasi; #[cfg(target_os = "vxworks")] pub mod vxworks; #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] pub mod fortanix_sgx; diff --git a/src/libstd/os/redox/fs.rs b/src/libstd/os/redox/fs.rs new file mode 100644 index 0000000000000..80a1290761984 --- /dev/null +++ b/src/libstd/os/redox/fs.rs @@ -0,0 +1,383 @@ +#![stable(feature = "metadata_ext", since = "1.1.0")] + +use crate::fs::Metadata; +use crate::sys_common::AsInner; + +#[allow(deprecated)] +use crate::os::redox::raw; + +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +#[stable(feature = "metadata_ext", since = "1.1.0")] +pub trait MetadataExt { + /// Gain a reference to the underlying `stat` structure which contains + /// the raw information returned by the OS. + /// + /// The contents of the returned [`stat`] are **not** consistent across + /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the + /// cross-Unix abstractions contained within the raw stat. + /// + /// [`stat`]: ../../../../std/os/redox/raw/struct.stat.html + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let stat = meta.as_raw_stat(); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext", since = "1.1.0")] + #[rustc_deprecated(since = "1.8.0", + reason = "deprecated in favor of the accessor \ + methods of this trait")] + #[allow(deprecated)] + fn as_raw_stat(&self) -> &raw::stat; + + /// Returns the device ID on which this file resides. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_dev()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_dev(&self) -> u64; + /// Returns the inode number. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_ino()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ino(&self) -> u64; + /// Returns the file type and mode. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_mode()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mode(&self) -> u32; + /// Returns the number of hard links to file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_nlink()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_nlink(&self) -> u64; + /// Returns the user ID of the file owner. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_uid()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_uid(&self) -> u32; + /// Returns the group ID of the file owner. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_gid()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_gid(&self) -> u32; + /// Returns the device ID that this file represents. Only relevant for special file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_rdev()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_rdev(&self) -> u64; + /// Returns the size of the file (if it is a regular file or a symbolic link) in bytes. + /// + /// The size of a symbolic link is the length of the pathname it contains, + /// without a terminating null byte. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_size()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_size(&self) -> u64; + /// Returns the last access time of the file, in seconds since Unix Epoch. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_atime()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime(&self) -> i64; + /// Returns the last access time of the file, in nanoseconds since [`st_atime`]. + /// + /// [`st_atime`]: #tymethod.st_atime + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_atime_nsec()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime_nsec(&self) -> i64; + /// Returns the last modification time of the file, in seconds since Unix Epoch. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_mtime()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime(&self) -> i64; + /// Returns the last modification time of the file, in nanoseconds since [`st_mtime`]. + /// + /// [`st_mtime`]: #tymethod.st_mtime + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_mtime_nsec()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime_nsec(&self) -> i64; + /// Returns the last status change time of the file, in seconds since Unix Epoch. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_ctime()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime(&self) -> i64; + /// Returns the last status change time of the file, in nanoseconds since [`st_ctime`]. + /// + /// [`st_ctime`]: #tymethod.st_ctime + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_ctime_nsec()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime_nsec(&self) -> i64; + /// Returns the "preferred" blocksize for efficient filesystem I/O. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_blksize()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blksize(&self) -> u64; + /// Returns the number of blocks allocated to the file, 512-byte units. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::io; + /// use std::os::redox::fs::MetadataExt; + /// + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_blocks()); + /// Ok(()) + /// } + /// ``` + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blocks(&self) -> u64; +} + +#[stable(feature = "metadata_ext", since = "1.1.0")] +impl MetadataExt for Metadata { + #[allow(deprecated)] + fn as_raw_stat(&self) -> &raw::stat { + unsafe { + &*(self.as_inner().as_inner() as *const libc::stat + as *const raw::stat) + } + } + fn st_dev(&self) -> u64 { + self.as_inner().as_inner().st_dev as u64 + } + fn st_ino(&self) -> u64 { + self.as_inner().as_inner().st_ino as u64 + } + fn st_mode(&self) -> u32 { + self.as_inner().as_inner().st_mode as u32 + } + fn st_nlink(&self) -> u64 { + self.as_inner().as_inner().st_nlink as u64 + } + fn st_uid(&self) -> u32 { + self.as_inner().as_inner().st_uid as u32 + } + fn st_gid(&self) -> u32 { + self.as_inner().as_inner().st_gid as u32 + } + fn st_rdev(&self) -> u64 { + self.as_inner().as_inner().st_rdev as u64 + } + fn st_size(&self) -> u64 { + self.as_inner().as_inner().st_size as u64 + } + fn st_atime(&self) -> i64 { + self.as_inner().as_inner().st_atime as i64 + } + fn st_atime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_atime_nsec as i64 + } + fn st_mtime(&self) -> i64 { + self.as_inner().as_inner().st_mtime as i64 + } + fn st_mtime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_mtime_nsec as i64 + } + fn st_ctime(&self) -> i64 { + self.as_inner().as_inner().st_ctime as i64 + } + fn st_ctime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_ctime_nsec as i64 + } + fn st_blksize(&self) -> u64 { + self.as_inner().as_inner().st_blksize as u64 + } + fn st_blocks(&self) -> u64 { + self.as_inner().as_inner().st_blocks as u64 + } +} diff --git a/src/libstd/os/redox/mod.rs b/src/libstd/os/redox/mod.rs new file mode 100644 index 0000000000000..c60da5926da6e --- /dev/null +++ b/src/libstd/os/redox/mod.rs @@ -0,0 +1,6 @@ +//! Redox-specific definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] + +pub mod raw; +pub mod fs; diff --git a/src/libstd/os/redox/raw.rs b/src/libstd/os/redox/raw.rs new file mode 100644 index 0000000000000..23d8ff7694bc5 --- /dev/null +++ b/src/libstd/os/redox/raw.rs @@ -0,0 +1,67 @@ +//! Redox-specific raw type definitions + +#![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)] +#![allow(missing_debug_implementations)] + +use crate::os::raw::{c_char, c_int, c_long, c_ulong, c_void}; + +#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = c_long; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type gid_t = c_int; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = c_int; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type uid_t = c_int; + +#[stable(feature = "pthread_t", since = "1.8.0")] +pub type pthread_t = *mut c_void; + +#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = c_ulong; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = c_ulong; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = c_ulong; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = c_ulong; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = c_long; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = c_long; + +#[repr(C)] +#[derive(Clone)] +#[stable(feature = "raw_ext", since = "1.1.0")] +pub struct stat { + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_dev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ino: ino_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_nlink: nlink_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mode: mode_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_uid: uid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_gid: gid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_rdev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_size: off_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blksize: blksize_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blocks: blkcnt_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub _pad: [c_char; 24], +} diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 56fde77daac58..87c071b512ac7 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -317,7 +317,7 @@ unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr { // Detect scheme on Redox fn has_redox_scheme(s: &[u8]) -> bool { - cfg!(target_os = "redox") && s.split(|b| *b == b'/').next().unwrap_or(b"").contains(&b':') + cfg!(target_os = "redox") && s.contains(&b':') } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index 35972b54e39d2..5a5859a6ad873 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -35,9 +35,6 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "cloudabi")] { mod cloudabi; pub use self::cloudabi::*; - } else if #[cfg(target_os = "redox")] { - mod redox; - pub use self::redox::*; } else if #[cfg(target_os = "wasi")] { mod wasi; pub use self::wasi::*; @@ -58,7 +55,7 @@ cfg_if::cfg_if! { #[cfg(rustdoc)] cfg_if::cfg_if! { - if #[cfg(any(unix, target_os = "redox"))] { + if #[cfg(unix)] { // On unix we'll document what's already available #[stable(feature = "rust1", since = "1.0.0")] pub use self::ext as unix_ext; diff --git a/src/libstd/sys/redox/args.rs b/src/libstd/sys/redox/args.rs deleted file mode 100644 index f9e2f5ba311a0..0000000000000 --- a/src/libstd/sys/redox/args.rs +++ /dev/null @@ -1,96 +0,0 @@ -//! 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 crate::ffi::OsString; -use crate::marker::PhantomData; -use crate::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, - _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 { self.iter.next() } - fn size_hint(&self) -> (usize, Option) { 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 { self.iter.next_back() } -} - -mod imp { - use crate::os::unix::prelude::*; - use crate::mem; - use crate::ffi::{CStr, OsString}; - use crate::marker::PhantomData; - use super::Args; - - use crate::sys_common::mutex::Mutex; - - static mut GLOBAL_ARGS_PTR: usize = 0; - static LOCK: Mutex = Mutex::new(); - - pub unsafe fn init(argc: isize, argv: *const *const u8) { - let args = (0..argc).map(|i| { - CStr::from_ptr(*argv.offset(i) as *const libc::c_char).to_bytes().to_vec() - }).collect(); - - let _guard = LOCK.lock(); - let ptr = get_global_ptr(); - assert!((*ptr).is_none()); - (*ptr) = Some(box args); - } - - pub unsafe fn cleanup() { - let _guard = LOCK.lock(); - *get_global_ptr() = None; - } - - pub fn args() -> Args { - let bytes = clone().unwrap_or_default(); - let v: Vec = bytes.into_iter().map(|v| { - OsStringExt::from_vec(v) - }).collect(); - Args { iter: v.into_iter(), _dont_send_or_sync_me: PhantomData } - } - - fn clone() -> Option>> { - unsafe { - let _guard = LOCK.lock(); - let ptr = get_global_ptr(); - (*ptr).as_ref().map(|s| (**s).clone()) - } - } - - unsafe fn get_global_ptr() -> *mut Option>>> { - mem::transmute(&GLOBAL_ARGS_PTR) - } - -} diff --git a/src/libstd/sys/redox/cmath.rs b/src/libstd/sys/redox/cmath.rs deleted file mode 100644 index f6bb58934fc05..0000000000000 --- a/src/libstd/sys/redox/cmath.rs +++ /dev/null @@ -1,33 +0,0 @@ -#![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/src/libstd/sys/redox/condvar.rs b/src/libstd/sys/redox/condvar.rs deleted file mode 100644 index a6365cac23ea7..0000000000000 --- a/src/libstd/sys/redox/condvar.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::cell::UnsafeCell; -use crate::intrinsics::{atomic_cxchg, atomic_load, atomic_xadd, atomic_xchg}; -use crate::ptr; -use crate::time::Duration; - -use crate::sys::mutex::{mutex_unlock, Mutex}; -use crate::sys::syscall::{futex, TimeSpec, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE}; - -pub struct Condvar { - lock: UnsafeCell<*mut i32>, - seq: UnsafeCell -} - -impl Condvar { - pub const fn new() -> Condvar { - Condvar { - lock: UnsafeCell::new(ptr::null_mut()), - seq: UnsafeCell::new(0) - } - } - - #[inline] - pub unsafe fn init(&self) { - *self.lock.get() = ptr::null_mut(); - *self.seq.get() = 0; - } - - #[inline] - pub fn notify_one(&self) { - unsafe { - let seq = self.seq.get(); - - atomic_xadd(seq, 1); - - let _ = futex(seq, FUTEX_WAKE, 1, 0, ptr::null_mut()); - } - } - - #[inline] - pub fn notify_all(&self) { - unsafe { - let lock = self.lock.get(); - let seq = self.seq.get(); - - if *lock == ptr::null_mut() { - return; - } - - atomic_xadd(seq, 1); - - let _ = futex(seq, FUTEX_REQUEUE, 1, crate::usize::MAX, *lock); - } - } - - #[inline] - unsafe fn wait_inner(&self, mutex: &Mutex, timeout_ptr: *const TimeSpec) -> bool { - let lock = self.lock.get(); - let seq = self.seq.get(); - - if *lock != mutex.lock.get() { - if *lock != ptr::null_mut() { - panic!("Condvar used with more than one Mutex"); - } - - atomic_cxchg(lock as *mut usize, 0, mutex.lock.get() as usize); - } - - mutex_unlock(*lock); - - let seq_before = atomic_load(seq); - - let _ = futex(seq, FUTEX_WAIT, seq_before, timeout_ptr as usize, ptr::null_mut()); - - let seq_after = atomic_load(seq); - - while atomic_xchg(*lock, 2) != 0 { - let _ = futex(*lock, FUTEX_WAIT, 2, 0, ptr::null_mut()); - } - - seq_before != seq_after - } - - #[inline] - pub fn wait(&self, mutex: &Mutex) { - unsafe { - assert!(self.wait_inner(mutex, ptr::null())); - } - } - - #[inline] - pub fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { - unsafe { - let timeout = TimeSpec { - tv_sec: dur.as_secs() as i64, - tv_nsec: dur.subsec_nanos() as i32 - }; - - self.wait_inner(mutex, &timeout as *const TimeSpec) - } - } - - #[inline] - pub unsafe fn destroy(&self) { - *self.lock.get() = ptr::null_mut(); - *self.seq.get() = 0; - } -} - -unsafe impl Send for Condvar {} - -unsafe impl Sync for Condvar {} diff --git a/src/libstd/sys/redox/env.rs b/src/libstd/sys/redox/env.rs deleted file mode 100644 index bcc0e126b9dd3..0000000000000 --- a/src/libstd/sys/redox/env.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod os { - pub const FAMILY: &str = "redox"; - pub const OS: &str = "redox"; - pub const DLL_PREFIX: &str = "lib"; - pub const DLL_SUFFIX: &str = ".so"; - pub const DLL_EXTENSION: &str = "so"; - pub const EXE_SUFFIX: &str = ""; - pub const EXE_EXTENSION: &str = ""; -} diff --git a/src/libstd/sys/redox/ext/ffi.rs b/src/libstd/sys/redox/ext/ffi.rs deleted file mode 100644 index 974d7b82c125f..0000000000000 --- a/src/libstd/sys/redox/ext/ffi.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! Redox-specific extension to the primitives in the `std::ffi` module. -//! -//! # Examples -//! -//! ``` -//! use std::ffi::OsString; -//! use std::os::redox::ffi::OsStringExt; -//! -//! let bytes = b"foo".to_vec(); -//! -//! // OsStringExt::from_vec -//! let os_string = OsString::from_vec(bytes); -//! assert_eq!(os_string.to_str(), Some("foo")); -//! -//! // OsStringExt::into_vec -//! let bytes = os_string.into_vec(); -//! assert_eq!(bytes, b"foo"); -//! ``` -//! -//! ``` -//! use std::ffi::OsStr; -//! use std::os::redox::ffi::OsStrExt; -//! -//! let bytes = b"foo"; -//! -//! // OsStrExt::from_bytes -//! let os_str = OsStr::from_bytes(bytes); -//! assert_eq!(os_str.to_str(), Some("foo")); -//! -//! // OsStrExt::as_bytes -//! let bytes = os_str.as_bytes(); -//! assert_eq!(bytes, b"foo"); -//! ``` - -#![stable(feature = "rust1", since = "1.0.0")] - -#[stable(feature = "rust1", since = "1.0.0")] -pub use crate::sys_common::os_str_bytes::*; diff --git a/src/libstd/sys/redox/ext/fs.rs b/src/libstd/sys/redox/ext/fs.rs deleted file mode 100644 index 4ddc1f09a319b..0000000000000 --- a/src/libstd/sys/redox/ext/fs.rs +++ /dev/null @@ -1,339 +0,0 @@ -//! Redox-specific extensions to primitives in the `std::fs` module. - -#![stable(feature = "rust1", since = "1.0.0")] - -use crate::fs::{self, Permissions, OpenOptions}; -use crate::io; -use crate::path::Path; -use crate::sys; -use crate::sys_common::{FromInner, AsInner, AsInnerMut}; - -/// Redox-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 `mode_t` bits that are the standard Redox - /// permissions for this file. - /// - /// # Examples - /// - /// ```no_run - /// use std::fs::File; - /// use std::os::redox::fs::PermissionsExt; - /// - /// fn main() -> std::io::Result<()> { - /// let f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; - /// let permissions = metadata.permissions(); - /// - /// println!("permissions: {:o}", 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::redox::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 Redox - /// permission bits. - /// - /// # Examples - /// - /// ``` - /// use std::fs::Permissions; - /// use std::os::redox::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)) - } -} - -/// Redox-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 - /// # #![feature(libc)] - /// extern crate libc; - /// use std::fs::OpenOptions; - /// use std::os::redox::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; - - /// Passes 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::redox::fs::OpenOptionsExt; - /// - /// # fn main() { - /// let mut options = OpenOptions::new(); - /// options.write(true); - /// if cfg!(target_os = "redox") { - /// 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 - } -} - -/// Redox-specific extensions to [`fs::Metadata`]. -/// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html -#[stable(feature = "metadata_ext", since = "1.1.0")] -pub trait MetadataExt { - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn dev(&self) -> u64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn ino(&self) -> u64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn mode(&self) -> u32; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn nlink(&self) -> u64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn uid(&self) -> u32; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn gid(&self) -> u32; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn size(&self) -> u64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn atime(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn atime_nsec(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn mtime(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn mtime_nsec(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn ctime(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn ctime_nsec(&self) -> i64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn blksize(&self) -> u64; - #[stable(feature = "metadata_ext", since = "1.1.0")] - fn blocks(&self) -> u64; -} - -// Hm, why are there casts here to the returned type, shouldn't the types always -// be the same? Right you are! Turns out, however, on android at least the types -// in the raw `stat` structure are not the same as the types being returned. Who -// knew! -// -// As a result to make sure this compiles for all platforms we do the manual -// casts and rely on manual lowering to `stat` if the raw type is desired. -#[stable(feature = "metadata_ext", since = "1.1.0")] -impl MetadataExt for fs::Metadata { - fn dev(&self) -> u64 { - self.as_inner().as_inner().st_dev as u64 - } - fn ino(&self) -> u64 { - self.as_inner().as_inner().st_ino as u64 - } - fn mode(&self) -> u32 { - self.as_inner().as_inner().st_mode as u32 - } - fn nlink(&self) -> u64 { - self.as_inner().as_inner().st_nlink as u64 - } - fn uid(&self) -> u32 { - self.as_inner().as_inner().st_uid as u32 - } - fn gid(&self) -> u32 { - self.as_inner().as_inner().st_gid as u32 - } - fn size(&self) -> u64 { - self.as_inner().as_inner().st_size as u64 - } - fn atime(&self) -> i64 { - self.as_inner().as_inner().st_atime as i64 - } - fn atime_nsec(&self) -> i64 { - self.as_inner().as_inner().st_atime_nsec as i64 - } - fn mtime(&self) -> i64 { - self.as_inner().as_inner().st_mtime as i64 - } - fn mtime_nsec(&self) -> i64 { - self.as_inner().as_inner().st_mtime_nsec as i64 - } - fn ctime(&self) -> i64 { - self.as_inner().as_inner().st_ctime as i64 - } - fn ctime_nsec(&self) -> i64 { - self.as_inner().as_inner().st_ctime_nsec as i64 - } - fn blksize(&self) -> u64 { - self.as_inner().as_inner().st_blksize as u64 - } - fn blocks(&self) -> u64 { - self.as_inner().as_inner().st_blocks as u64 - } -} - -/// Redox-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. - #[stable(feature = "file_type_ext", since = "1.5.0")] - fn is_block_device(&self) -> bool; - /// Returns whether this file type is a char device. - #[stable(feature = "file_type_ext", since = "1.5.0")] - fn is_char_device(&self) -> bool; - /// Returns whether this file type is a fifo. - #[stable(feature = "file_type_ext", since = "1.5.0")] - fn is_fifo(&self) -> bool; - /// Returns whether this file type is a socket. - #[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 { false /*FIXME: Implement block device mode*/ } - fn is_char_device(&self) -> bool { false /*FIXME: Implement char device mode*/ } - fn is_fifo(&self) -> bool { false /*FIXME: Implement fifo mode*/ } - fn is_socket(&self) -> bool { false /*FIXME: Implement socket mode*/ } -} - -/// 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::redox::fs; -/// -/// fn main() -> std::io::Result<()> { -/// fs::symlink("a.txt", "b.txt")?; -/// Ok(()) -/// } -/// ``` -#[stable(feature = "symlink", since = "1.1.0")] -pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> -{ - sys::fs::symlink(src.as_ref(), dst.as_ref()) -} - -/// Redox-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::redox::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/src/libstd/sys/redox/ext/io.rs b/src/libstd/sys/redox/ext/io.rs deleted file mode 100644 index c21d216478fb7..0000000000000 --- a/src/libstd/sys/redox/ext/io.rs +++ /dev/null @@ -1,172 +0,0 @@ -//! Unix-specific extensions to general I/O primitives - -#![stable(feature = "rust1", since = "1.0.0")] - -use crate::fs; -use crate::net; -use crate::sys; -use crate::io; -use crate::sys_common::{self, AsInner, FromInner, IntoInner}; - -/// Raw file descriptors. -#[stable(feature = "rust1", since = "1.0.0")] -pub type RawFd = usize; - -/// 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 instances 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 = "rust1", since = "1.0.0")] -impl AsRawFd for net::TcpStream { - fn as_raw_fd(&self) -> RawFd { - self.as_inner().as_inner().fd().raw() - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl AsRawFd for net::TcpListener { - fn as_raw_fd(&self) -> RawFd { - self.as_inner().as_inner().fd().raw() - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl AsRawFd for net::UdpSocket { - fn as_raw_fd(&self) -> RawFd { - self.as_inner().as_inner().fd().raw() - } -} - -#[stable(feature = "asraw_stdio", since = "1.21.0")] -impl AsRawFd for io::Stdin { - fn as_raw_fd(&self) -> RawFd { 0 } -} - -#[stable(feature = "asraw_stdio", since = "1.21.0")] -impl AsRawFd for io::Stdout { - fn as_raw_fd(&self) -> RawFd { 1 } -} - -#[stable(feature = "asraw_stdio", since = "1.21.0")] -impl AsRawFd for io::Stderr { - fn as_raw_fd(&self) -> RawFd { 2 } -} - -#[stable(feature = "asraw_stdio_locks", since = "1.35.0")] -impl<'a> AsRawFd for io::StdinLock<'a> { - fn as_raw_fd(&self) -> RawFd { 0 } -} - -#[stable(feature = "asraw_stdio_locks", since = "1.35.0")] -impl<'a> AsRawFd for io::StdoutLock<'a> { - fn as_raw_fd(&self) -> RawFd { 1 } -} - -#[stable(feature = "asraw_stdio_locks", since = "1.35.0")] -impl<'a> AsRawFd for io::StderrLock<'a> { - fn as_raw_fd(&self) -> RawFd { 2 } -} - -#[stable(feature = "from_raw_os", since = "1.1.0")] -impl FromRawFd for net::TcpStream { - unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream { - let file = sys::fs::File::from_inner(fd); - net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(file)) - } -} -#[stable(feature = "from_raw_os", since = "1.1.0")] -impl FromRawFd for net::TcpListener { - unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener { - let file = sys::fs::File::from_inner(fd); - net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(file)) - } -} -#[stable(feature = "from_raw_os", since = "1.1.0")] -impl FromRawFd for net::UdpSocket { - unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket { - let file = sys::fs::File::from_inner(fd); - net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(file)) - } -} - -#[stable(feature = "into_raw_os", since = "1.4.0")] -impl IntoRawFd for net::TcpStream { - fn into_raw_fd(self) -> RawFd { - self.into_inner().into_inner().into_fd().into_raw() - } -} -#[stable(feature = "into_raw_os", since = "1.4.0")] -impl IntoRawFd for net::TcpListener { - fn into_raw_fd(self) -> RawFd { - self.into_inner().into_inner().into_fd().into_raw() - } -} -#[stable(feature = "into_raw_os", since = "1.4.0")] -impl IntoRawFd for net::UdpSocket { - fn into_raw_fd(self) -> RawFd { - self.into_inner().into_inner().into_fd().into_raw() - } -} diff --git a/src/libstd/sys/redox/ext/mod.rs b/src/libstd/sys/redox/ext/mod.rs deleted file mode 100644 index 8a2d243c7ff62..0000000000000 --- a/src/libstd/sys/redox/ext/mod.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! Experimental extensions to `std` for Unix platforms. -//! -//! For now, this module is limited to extracting file descriptors, -//! but its functionality will grow over time. -//! -//! # 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(target_os = "redox"))] - -pub mod ffi; -pub mod fs; -pub mod io; -pub mod net; -pub mod process; -pub mod thread; - -/// 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::{FileTypeExt, PermissionsExt, OpenOptionsExt, MetadataExt}; - #[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/src/libstd/sys/redox/ext/net.rs b/src/libstd/sys/redox/ext/net.rs deleted file mode 100644 index 1f5c785f41907..0000000000000 --- a/src/libstd/sys/redox/ext/net.rs +++ /dev/null @@ -1,759 +0,0 @@ -#![stable(feature = "unix_socket_redox", since = "1.29.0")] - -//! Unix-specific networking functionality - -use crate::fmt; -use crate::io::{self, Error, ErrorKind, Initializer}; -use crate::net::Shutdown; -use crate::os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd}; -use crate::path::Path; -use crate::time::Duration; -use crate::sys::{cvt, fd::FileDesc, syscall}; - -/// 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_redox", since = "1.29.0")] -pub struct SocketAddr(()); - -impl SocketAddr { - /// 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_redox", since = "1.29.0")] - pub fn as_pathname(&self) -> Option<&Path> { - None - } - - /// Returns `true` 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_redox", since = "1.29.0")] - pub fn is_unnamed(&self) -> bool { - false - } -} -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl fmt::Debug for SocketAddr { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(fmt, "SocketAddr") - } -} - -/// 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_redox", since = "1.29.0")] -pub struct UnixStream(FileDesc); - -#[stable(feature = "unix_socket_redox", since = "1.29.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.raw()); - 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_redox", since = "1.29.0")] - pub fn connect>(path: P) -> io::Result { - if let Some(s) = path.as_ref().to_str() { - cvt(syscall::open(format!("chan:{}", s), syscall::O_CLOEXEC)) - .map(FileDesc::new) - .map(UnixStream) - } else { - Err(Error::new( - ErrorKind::Other, - "UnixStream::connect: non-utf8 paths not supported on redox" - )) - } - } - - /// 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_redox", since = "1.29.0")] - pub fn pair() -> io::Result<(UnixStream, UnixStream)> { - let server = cvt(syscall::open("chan:", syscall::O_CREAT | syscall::O_CLOEXEC)) - .map(FileDesc::new)?; - let client = server.duplicate_path(b"connect")?; - let stream = server.duplicate_path(b"listen")?; - Ok((UnixStream(client), UnixStream(stream))) - } - - /// 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_redox", since = "1.29.0")] - pub fn try_clone(&self) -> io::Result { - 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_redox", since = "1.29.0")] - pub fn local_addr(&self) -> io::Result { - Err(Error::new(ErrorKind::Other, "UnixStream::local_addr unimplemented on redox")) - } - - /// 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_redox", since = "1.29.0")] - pub fn peer_addr(&self) -> io::Result { - Err(Error::new(ErrorKind::Other, "UnixStream::peer_addr unimplemented on redox")) - } - - /// 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_redox", since = "1.29.0")] - pub fn set_read_timeout(&self, _timeout: Option) -> io::Result<()> { - Err(Error::new(ErrorKind::Other, "UnixStream::set_read_timeout unimplemented on redox")) - } - - /// 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_redox", since = "1.29.0")] - pub fn set_write_timeout(&self, _timeout: Option) -> io::Result<()> { - Err(Error::new(ErrorKind::Other, "UnixStream::set_write_timeout unimplemented on redox")) - } - - /// 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_redox", since = "1.29.0")] - pub fn read_timeout(&self) -> io::Result> { - Err(Error::new(ErrorKind::Other, "UnixStream::read_timeout unimplemented on redox")) - } - - /// 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_redox", since = "1.29.0")] - pub fn write_timeout(&self) -> io::Result> { - Err(Error::new(ErrorKind::Other, "UnixStream::write_timeout unimplemented on redox")) - } - - /// 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_redox", since = "1.29.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_redox", since = "1.29.0")] - pub fn take_error(&self) -> io::Result> { - Ok(None) - } - - /// 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_redox", since = "1.29.0")] - pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> { - Err(Error::new(ErrorKind::Other, "UnixStream::shutdown unimplemented on redox")) - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl io::Read for UnixStream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - io::Read::read(&mut &*self, buf) - } - - #[inline] - unsafe fn initializer(&self) -> Initializer { - Initializer::nop() - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl<'a> io::Read for &'a UnixStream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) - } - - #[inline] - unsafe fn initializer(&self) -> Initializer { - Initializer::nop() - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl io::Write for UnixStream { - fn write(&mut self, buf: &[u8]) -> io::Result { - io::Write::write(&mut &*self, buf) - } - - fn flush(&mut self) -> io::Result<()> { - io::Write::flush(&mut &*self) - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl<'a> io::Write for &'a UnixStream { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.0.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl AsRawFd for UnixStream { - fn as_raw_fd(&self) -> RawFd { - self.0.raw() - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl FromRawFd for UnixStream { - unsafe fn from_raw_fd(fd: RawFd) -> UnixStream { - UnixStream(FileDesc::new(fd)) - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl IntoRawFd for UnixStream { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw() - } -} - -/// 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_redox", since = "1.29.0")] -pub struct UnixListener(FileDesc); - -#[stable(feature = "unix_socket_redox", since = "1.29.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.raw()); - 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_redox", since = "1.29.0")] - pub fn bind>(path: P) -> io::Result { - if let Some(s) = path.as_ref().to_str() { - cvt(syscall::open(format!("chan:{}", s), syscall::O_CREAT | syscall::O_CLOEXEC)) - .map(FileDesc::new) - .map(UnixListener) - } else { - Err(Error::new( - ErrorKind::Other, - "UnixListener::bind: non-utf8 paths not supported on redox" - )) - } - } - - /// 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_redox", since = "1.29.0")] - pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> { - self.0.duplicate_path(b"listen").map(|fd| (UnixStream(fd), SocketAddr(()))) - } - - /// 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_redox", since = "1.29.0")] - pub fn try_clone(&self) -> io::Result { - 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_redox", since = "1.29.0")] - pub fn local_addr(&self) -> io::Result { - Err(Error::new(ErrorKind::Other, "UnixListener::local_addr unimplemented on redox")) - } - - /// 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_redox", since = "1.29.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_redox", since = "1.29.0")] - pub fn take_error(&self) -> io::Result> { - Ok(None) - } - - /// 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_redox", since = "1.29.0")] - pub fn incoming(&self) -> Incoming<'_> { - Incoming { listener: self } - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl AsRawFd for UnixListener { - fn as_raw_fd(&self) -> RawFd { - self.0.raw() - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl FromRawFd for UnixListener { - unsafe fn from_raw_fd(fd: RawFd) -> UnixListener { - UnixListener(FileDesc::new(fd)) - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl IntoRawFd for UnixListener { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw() - } -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl<'a> IntoIterator for &'a UnixListener { - type Item = io::Result; - 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_redox", since = "1.29.0")] -pub struct Incoming<'a> { - listener: &'a UnixListener, -} - -#[stable(feature = "unix_socket_redox", since = "1.29.0")] -impl<'a> Iterator for Incoming<'a> { - type Item = io::Result; - - fn next(&mut self) -> Option> { - Some(self.listener.accept().map(|s| s.0)) - } - - fn size_hint(&self) -> (usize, Option) { - (usize::max_value(), None) - } -} diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs deleted file mode 100644 index e981cb93d441f..0000000000000 --- a/src/libstd/sys/redox/ext/process.rs +++ /dev/null @@ -1,197 +0,0 @@ -//! Redox-specific extensions to primitives in the `std::process` module. - -#![stable(feature = "rust1", since = "1.0.0")] - -use crate::io; -use crate::os::unix::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd}; -use crate::process; -use crate::sys; -use crate::sys_common::{AsInnerMut, AsInner, FromInner, IntoInner}; - -/// Redox-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 and Safety - /// - /// 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). - /// - /// This also means that all resources such as file descriptors and - /// memory-mapped regions got duplicated. It is your responsibility to make - /// sure that the closure does not violate library invariants by making - /// invalid use of these duplicates. - /// - /// 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_pre_exec", since = "1.34.0")] - unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command - where F: FnMut() -> io::Result<()> + Send + Sync + 'static; - - /// Schedules a closure to be run just before the `exec` function is - /// invoked. - /// - /// This method is stable and usable, but it should be unsafe. To fix - /// that, it got deprecated in favor of the unsafe [`pre_exec`]. - /// - /// [`pre_exec`]: #tymethod.pre_exec - #[stable(feature = "process_exec", since = "1.15.0")] - #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")] - fn before_exec(&mut self, f: F) -> &mut process::Command - where F: FnMut() -> io::Result<()> + Send + Sync + 'static - { - unsafe { self.pre_exec(f) } - } - - /// 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. - /// - /// 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. - /// - /// # 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 - } - - unsafe fn pre_exec(&mut self, f: F) -> &mut process::Command - where F: FnMut() -> io::Result<()> + Send + Sync + 'static - { - self.as_inner_mut().pre_exec(Box::new(f)); - self - } - - fn exec(&mut self) -> io::Error { - self.as_inner_mut().exec(sys::process::Stdio::Inherit) - } -} - -/// Redox-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; -} - -#[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 { - 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() - } -} diff --git a/src/libstd/sys/redox/ext/thread.rs b/src/libstd/sys/redox/ext/thread.rs deleted file mode 100644 index 629eaef04ce36..0000000000000 --- a/src/libstd/sys/redox/ext/thread.rs +++ /dev/null @@ -1,39 +0,0 @@ -//! Redox-specific extensions to primitives in the `std::thread` module. - -#![stable(feature = "thread_extensions", since = "1.9.0")] - -use crate::sys_common::{AsInner, IntoInner}; -use crate::thread::JoinHandle; - -#[stable(feature = "thread_extensions", since = "1.9.0")] -#[allow(deprecated)] -pub type RawPthread = usize; - -/// Redox-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 JoinHandleExt for JoinHandle { - 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/src/libstd/sys/redox/fast_thread_local.rs b/src/libstd/sys/redox/fast_thread_local.rs deleted file mode 100644 index 05464787a05d3..0000000000000 --- a/src/libstd/sys/redox/fast_thread_local.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![cfg(target_thread_local)] -#![unstable(feature = "thread_local_internals", issue = "0")] - -pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor; diff --git a/src/libstd/sys/redox/fd.rs b/src/libstd/sys/redox/fd.rs deleted file mode 100644 index a42e486db2239..0000000000000 --- a/src/libstd/sys/redox/fd.rs +++ /dev/null @@ -1,88 +0,0 @@ -#![unstable(reason = "not public", issue = "0", feature = "fd")] - -use crate::io::{self, Read}; -use crate::mem; -use crate::sys::{cvt, syscall}; -use crate::sys_common::AsInner; - -pub struct FileDesc { - fd: usize, -} - -impl FileDesc { - pub fn new(fd: usize) -> FileDesc { - FileDesc { fd } - } - - pub fn raw(&self) -> usize { self.fd } - - /// Extracts the actual file descriptor without closing it. - pub fn into_raw(self) -> usize { - let fd = self.fd; - mem::forget(self); - fd - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result { - cvt(syscall::read(self.fd, buf)) - } - - pub fn read_to_end(&self, buf: &mut Vec) -> io::Result { - let mut me = self; - (&mut me).read_to_end(buf) - } - - pub fn write(&self, buf: &[u8]) -> io::Result { - cvt(syscall::write(self.fd, buf)) - } - - pub fn duplicate(&self) -> io::Result { - self.duplicate_path(&[]) - } - pub fn duplicate_path(&self, path: &[u8]) -> io::Result { - let new_fd = cvt(syscall::dup(self.fd, path))?; - Ok(FileDesc::new(new_fd)) - } - - pub fn nonblocking(&self) -> io::Result { - let flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFL, 0))?; - Ok(flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK) - } - - pub fn set_cloexec(&self) -> io::Result<()> { - let mut flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFD, 0))?; - flags |= syscall::O_CLOEXEC; - cvt(syscall::fcntl(self.fd, syscall::F_SETFD, flags)).and(Ok(())) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let mut flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFL, 0))?; - if nonblocking { - flags |= syscall::O_NONBLOCK; - } else { - flags &= !syscall::O_NONBLOCK; - } - cvt(syscall::fcntl(self.fd, syscall::F_SETFL, flags)).and(Ok(())) - } -} - -impl<'a> Read for &'a FileDesc { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - (**self).read(buf) - } -} - -impl AsInner for FileDesc { - fn as_inner(&self) -> &usize { &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 _ = syscall::close(self.fd); - } -} diff --git a/src/libstd/sys/redox/fs.rs b/src/libstd/sys/redox/fs.rs deleted file mode 100644 index b80a1a349e338..0000000000000 --- a/src/libstd/sys/redox/fs.rs +++ /dev/null @@ -1,447 +0,0 @@ -use crate::os::unix::prelude::*; - -use crate::ffi::{OsString, OsStr}; -use crate::fmt; -use crate::io::{self, Error, SeekFrom, IoSlice, IoSliceMut}; -use crate::path::{Path, PathBuf}; -use crate::sync::Arc; -use crate::sys::fd::FileDesc; -use crate::sys::time::SystemTime; -use crate::sys::{cvt, syscall}; -use crate::sys_common::{AsInner, FromInner}; - -pub use crate::sys_common::fs::copy; -pub use crate::sys_common::fs::remove_dir_all; - -pub struct File(FileDesc); - -#[derive(Clone)] -pub struct FileAttr { - stat: syscall::Stat, -} - -pub struct ReadDir { - data: Vec, - i: usize, - root: Arc, -} - -struct Dir(FileDesc); - -unsafe impl Send for Dir {} -unsafe impl Sync for Dir {} - -pub struct DirEntry { - root: Arc, - 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: u16, -} - -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct FilePermissions { mode: u16 } - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct FileType { mode: u16 } - -#[derive(Debug)] -pub struct DirBuilder { mode: u16 } - -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 u16) & 0o777 } - } - - pub fn file_type(&self) -> FileType { - FileType { mode: self.stat.st_mode as u16 } - } -} - -impl FileAttr { - pub fn modified(&self) -> io::Result { - Ok(SystemTime::from(syscall::TimeSpec { - tv_sec: self.stat.st_mtime as i64, - tv_nsec: self.stat.st_mtime_nsec as i32, - })) - } - - pub fn accessed(&self) -> io::Result { - Ok(SystemTime::from(syscall::TimeSpec { - tv_sec: self.stat.st_atime as i64, - tv_nsec: self.stat.st_atime_nsec as i32, - })) - } - - pub fn created(&self) -> io::Result { - Ok(SystemTime::from(syscall::TimeSpec { - tv_sec: self.stat.st_ctime as i64, - tv_nsec: self.stat.st_ctime_nsec as i32, - })) - } -} - -impl AsInner for FileAttr { - fn as_inner(&self) -> &syscall::Stat { &self.stat } -} - -impl FilePermissions { - pub fn readonly(&self) -> bool { self.mode & 0o222 == 0 } - pub fn set_readonly(&mut self, readonly: bool) { - if readonly { - self.mode &= !0o222; - } else { - self.mode |= 0o222; - } - } - pub fn mode(&self) -> u32 { self.mode as u32 } -} - -impl FileType { - pub fn is_dir(&self) -> bool { self.is(syscall::MODE_DIR) } - pub fn is_file(&self) -> bool { self.is(syscall::MODE_FILE) } - pub fn is_symlink(&self) -> bool { self.is(syscall::MODE_SYMLINK) } - - pub fn is(&self, mode: u16) -> bool { - self.mode & syscall::MODE_TYPE == mode - } -} - -impl FromInner for FilePermissions { - fn from_inner(mode: u32) -> FilePermissions { - FilePermissions { mode: mode as u16 } - } -} - -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.root, f) - } -} - -impl Iterator for ReadDir { - type Item = io::Result; - - fn next(&mut self) -> Option> { - loop { - let start = self.i; - let mut i = self.i; - while i < self.data.len() { - self.i += 1; - if self.data[i] == b'\n' { - break; - } - i += 1; - } - if start < self.i { - let ret = DirEntry { - name: self.data[start .. i].to_owned().into_boxed_slice(), - root: self.root.clone() - }; - if ret.name_bytes() != b"." && ret.name_bytes() != b".." { - return Some(Ok(ret)) - } - } else { - return None; - } - } - } -} - -impl DirEntry { - pub fn path(&self) -> PathBuf { - self.root.join(OsStr::from_bytes(self.name_bytes())) - } - - pub fn file_name(&self) -> OsString { - OsStr::from_bytes(self.name_bytes()).to_os_string() - } - - pub fn metadata(&self) -> io::Result { - lstat(&self.path()) - } - - pub fn file_type(&self) -> io::Result { - lstat(&self.path()).map(|m| m.file_type()) - } - - 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 u16; } - - fn get_access_mode(&self) -> io::Result { - match (self.read, self.write, self.append) { - (true, false, false) => Ok(syscall::O_RDONLY), - (false, true, false) => Ok(syscall::O_WRONLY), - (true, true, false) => Ok(syscall::O_RDWR), - (false, _, true) => Ok(syscall::O_WRONLY | syscall::O_APPEND), - (true, _, true) => Ok(syscall::O_RDWR | syscall::O_APPEND), - (false, false, false) => Err(Error::from_raw_os_error(syscall::EINVAL)), - } - } - - fn get_creation_mode(&self) -> io::Result { - match (self.write, self.append) { - (true, false) => {} - (false, false) => - if self.truncate || self.create || self.create_new { - return Err(Error::from_raw_os_error(syscall::EINVAL)); - }, - (_, true) => - if self.truncate && !self.create_new { - return Err(Error::from_raw_os_error(syscall::EINVAL)); - }, - } - - Ok(match (self.create, self.truncate, self.create_new) { - (false, false, false) => 0, - (true, false, false) => syscall::O_CREAT, - (false, true, false) => syscall::O_TRUNC, - (true, true, false) => syscall::O_CREAT | syscall::O_TRUNC, - (_, _, true) => syscall::O_CREAT | syscall::O_EXCL, - }) - } -} - -impl File { - pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { - let flags = syscall::O_CLOEXEC | - opts.get_access_mode()? as usize | - opts.get_creation_mode()? as usize | - (opts.custom_flags as usize & !syscall::O_ACCMODE); - let fd = cvt(syscall::open(path.to_str().unwrap(), flags | opts.mode as usize))?; - Ok(File(FileDesc::new(fd))) - } - - pub fn file_attr(&self) -> io::Result { - let mut stat = syscall::Stat::default(); - cvt(syscall::fstat(self.0.raw(), &mut stat))?; - Ok(FileAttr { stat }) - } - - pub fn fsync(&self) -> io::Result<()> { - cvt(syscall::fsync(self.0.raw()))?; - Ok(()) - } - - pub fn datasync(&self) -> io::Result<()> { - self.fsync() - } - - pub fn truncate(&self, size: u64) -> io::Result<()> { - cvt(syscall::ftruncate(self.0.raw(), size as usize))?; - Ok(()) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - crate::io::default_read_vectored(|buf| self.read(buf), bufs) - } - - pub fn write(&self, buf: &[u8]) -> io::Result { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - crate::io::default_write_vectored(|buf| self.write(buf), bufs) - } - - pub fn flush(&self) -> io::Result<()> { Ok(()) } - - pub fn seek(&self, pos: SeekFrom) -> io::Result { - 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) => (syscall::SEEK_SET, off as i64), - SeekFrom::End(off) => (syscall::SEEK_END, off), - SeekFrom::Current(off) => (syscall::SEEK_CUR, off), - }; - let n = cvt(syscall::lseek(self.0.raw(), pos as isize, whence))?; - Ok(n as u64) - } - - pub fn duplicate(&self) -> io::Result { - self.0.duplicate().map(File) - } - - pub fn dup(&self, buf: &[u8]) -> io::Result { - let fd = cvt(syscall::dup(*self.fd().as_inner() as usize, buf))?; - Ok(File(FileDesc::new(fd))) - } - - pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> { - set_perm(&self.path()?, perm) - } - - pub fn path(&self) -> io::Result { - let mut buf: [u8; 4096] = [0; 4096]; - let count = cvt(syscall::fpath(*self.fd().as_inner() as usize, &mut buf))?; - Ok(PathBuf::from(unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) })) - } - - pub fn fd(&self) -> &FileDesc { &self.0 } - - pub fn into_fd(self) -> FileDesc { self.0 } -} - -impl DirBuilder { - pub fn new() -> DirBuilder { - DirBuilder { mode: 0o777 } - } - - pub fn mkdir(&self, p: &Path) -> io::Result<()> { - let flags = syscall::O_CREAT | syscall::O_CLOEXEC | syscall::O_DIRECTORY | syscall::O_EXCL; - let fd = cvt(syscall::open(p.to_str().unwrap(), flags | (self.mode as usize & 0o777)))?; - let _ = syscall::close(fd); - Ok(()) - } - - pub fn set_mode(&mut self, mode: u32) { - self.mode = mode as u16; - } -} - -impl FromInner for File { - fn from_inner(fd: usize) -> File { - File(FileDesc::new(fd)) - } -} - -impl fmt::Debug for File { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut b = f.debug_struct("File"); - b.field("fd", &self.0.raw()); - if let Ok(path) = self.path() { - 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 { - let root = Arc::new(p.to_path_buf()); - - let flags = syscall::O_CLOEXEC | syscall::O_RDONLY | syscall::O_DIRECTORY; - let fd = cvt(syscall::open(p.to_str().unwrap(), flags))?; - let file = FileDesc::new(fd); - let mut data = Vec::new(); - file.read_to_end(&mut data)?; - - Ok(ReadDir { data: data, i: 0, root: root }) -} - -pub fn unlink(p: &Path) -> io::Result<()> { - cvt(syscall::unlink(p.to_str().unwrap()))?; - Ok(()) -} - -pub fn rename(old: &Path, new: &Path) -> io::Result<()> { - let fd = cvt(syscall::open(old.to_str().unwrap(), - syscall::O_CLOEXEC | syscall::O_STAT | syscall::O_NOFOLLOW))?; - let res = cvt(syscall::frename(fd, new.to_str().unwrap())); - cvt(syscall::close(fd))?; - res?; - Ok(()) -} - -pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { - cvt(syscall::chmod(p.to_str().unwrap(), perm.mode as usize))?; - Ok(()) -} - -pub fn rmdir(p: &Path) -> io::Result<()> { - cvt(syscall::rmdir(p.to_str().unwrap()))?; - Ok(()) -} - -pub fn readlink(p: &Path) -> io::Result { - let fd = cvt(syscall::open(p.to_str().unwrap(), - syscall::O_CLOEXEC | syscall::O_SYMLINK | syscall::O_RDONLY))?; - let mut buf: [u8; 4096] = [0; 4096]; - let res = cvt(syscall::read(fd, &mut buf)); - cvt(syscall::close(fd))?; - let count = res?; - Ok(PathBuf::from(unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) })) -} - -pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { - let fd = cvt(syscall::open(dst.to_str().unwrap(), - syscall::O_CLOEXEC | syscall::O_SYMLINK | - syscall::O_CREAT | syscall::O_WRONLY | 0o777))?; - let res = cvt(syscall::write(fd, src.to_str().unwrap().as_bytes())); - cvt(syscall::close(fd))?; - res?; - Ok(()) -} - -pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { - Err(Error::from_raw_os_error(syscall::ENOSYS)) -} - -pub fn stat(p: &Path) -> io::Result { - let fd = cvt(syscall::open(p.to_str().unwrap(), syscall::O_CLOEXEC | syscall::O_STAT))?; - let file = File(FileDesc::new(fd)); - file.file_attr() -} - -pub fn lstat(p: &Path) -> io::Result { - let fd = cvt(syscall::open(p.to_str().unwrap(), - syscall::O_CLOEXEC | syscall::O_STAT | syscall::O_NOFOLLOW))?; - let file = File(FileDesc::new(fd)); - file.file_attr() -} - -pub fn canonicalize(p: &Path) -> io::Result { - let fd = cvt(syscall::open(p.to_str().unwrap(), syscall::O_CLOEXEC | syscall::O_STAT))?; - let file = File(FileDesc::new(fd)); - file.path() -} diff --git a/src/libstd/sys/redox/io.rs b/src/libstd/sys/redox/io.rs deleted file mode 100644 index 976e122463d1b..0000000000000 --- a/src/libstd/sys/redox/io.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::mem; - -pub struct IoSlice<'a>(&'a [u8]); - -impl<'a> IoSlice<'a> { - #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { - IoSlice(buf) - } - - #[inline] - pub fn advance(&mut self, n: usize) { - self.0 = &self.0[n..] - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - self.0 - } -} - -pub struct IoSliceMut<'a>(&'a mut [u8]); - -impl<'a> IoSliceMut<'a> { - #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { - IoSliceMut(buf) - } - - #[inline] - pub fn advance(&mut self, n: usize) { - let slice = mem::replace(&mut self.0, &mut []); - let (_, remaining) = slice.split_at_mut(n); - self.0 = remaining; - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - self.0 - } - - #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { - self.0 - } -} diff --git a/src/libstd/sys/redox/memchr.rs b/src/libstd/sys/redox/memchr.rs deleted file mode 100644 index d2bfcce86f414..0000000000000 --- a/src/libstd/sys/redox/memchr.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Original implementation taken from rust-memchr. -// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch - -pub use core::slice::memchr::{memchr, memrchr}; diff --git a/src/libstd/sys/redox/mod.rs b/src/libstd/sys/redox/mod.rs deleted file mode 100644 index 354184f8af6e7..0000000000000 --- a/src/libstd/sys/redox/mod.rs +++ /dev/null @@ -1,96 +0,0 @@ -#![allow(dead_code, missing_docs, nonstandard_style)] - -use crate::io::ErrorKind; - -pub use libc::strlen; -pub use self::rand::hashmap_random_keys; - -#[path = "../unix/alloc.rs"] -pub mod alloc; -pub mod args; -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 io; -pub mod memchr; -pub mod mutex; -pub mod net; -pub mod os; -pub mod path; -pub mod pipe; -pub mod process; -pub mod rand; -pub mod rwlock; -pub mod stack_overflow; -pub mod stdio; -pub mod syscall; -pub mod thread; -pub mod thread_local; -pub mod time; - -pub use crate::sys_common::os_str_bytes as os_str; - -#[cfg(not(test))] -pub fn init() {} - -pub fn decode_error_kind(errno: i32) -> ErrorKind { - match errno { - syscall::ECONNREFUSED => ErrorKind::ConnectionRefused, - syscall::ECONNRESET => ErrorKind::ConnectionReset, - syscall::EPERM | syscall::EACCES => ErrorKind::PermissionDenied, - syscall::EPIPE => ErrorKind::BrokenPipe, - syscall::ENOTCONN => ErrorKind::NotConnected, - syscall::ECONNABORTED => ErrorKind::ConnectionAborted, - syscall::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable, - syscall::EADDRINUSE => ErrorKind::AddrInUse, - syscall::ENOENT => ErrorKind::NotFound, - syscall::EINTR => ErrorKind::Interrupted, - syscall::EINVAL => ErrorKind::InvalidInput, - syscall::ETIMEDOUT => ErrorKind::TimedOut, - syscall::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 == syscall::EAGAIN || x == syscall::EWOULDBLOCK => - ErrorKind::WouldBlock, - - _ => ErrorKind::Other, - } -} - -pub fn cvt(result: Result) -> crate::io::Result { - result.map_err(|err| crate::io::Error::from_raw_os_error(err.errno)) -} - -#[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_libc(t: T) -> crate::io::Result { - if t.is_minus_one() { - Err(crate::io::Error::last_os_error()) - } else { - Ok(t) - } -} - -/// On Redox, use an illegal instruction to abort -pub unsafe fn abort_internal() -> ! { - core::intrinsics::abort(); -} diff --git a/src/libstd/sys/redox/mutex.rs b/src/libstd/sys/redox/mutex.rs deleted file mode 100644 index 59399df0294c8..0000000000000 --- a/src/libstd/sys/redox/mutex.rs +++ /dev/null @@ -1,169 +0,0 @@ -use crate::cell::UnsafeCell; -use crate::intrinsics::{atomic_cxchg, atomic_xchg}; -use crate::ptr; - -use crate::sys::syscall::{futex, getpid, FUTEX_WAIT, FUTEX_WAKE}; - -pub unsafe fn mutex_try_lock(m: *mut i32) -> bool { - atomic_cxchg(m, 0, 1).0 == 0 -} - -pub unsafe fn mutex_lock(m: *mut i32) { - let mut c = 0; - //Set to larger value for longer spin test - for _i in 0..100 { - c = atomic_cxchg(m, 0, 1).0; - if c == 0 { - break; - } - //cpu_relax() - } - if c == 1 { - c = atomic_xchg(m, 2); - } - while c != 0 { - let _ = futex(m, FUTEX_WAIT, 2, 0, ptr::null_mut()); - c = atomic_xchg(m, 2); - } -} - -pub unsafe fn mutex_unlock(m: *mut i32) { - if *m == 2 { - *m = 0; - } else if atomic_xchg(m, 0) == 1 { - return; - } - //Set to larger value for longer spin test - for _i in 0..100 { - if *m != 0 { - if atomic_cxchg(m, 1, 2).0 != 0 { - return; - } - } - //cpu_relax() - } - let _ = futex(m, FUTEX_WAKE, 1, 0, ptr::null_mut()); -} - -pub struct Mutex { - pub lock: UnsafeCell, -} - -impl Mutex { - /// Creates a new mutex. - pub const fn new() -> Self { - Mutex { - lock: UnsafeCell::new(0), - } - } - - #[inline] - pub unsafe fn init(&self) { - *self.lock.get() = 0; - } - - /// Try to lock the mutex - #[inline] - pub unsafe fn try_lock(&self) -> bool { - mutex_try_lock(self.lock.get()) - } - - /// Lock the mutex - #[inline] - pub unsafe fn lock(&self) { - mutex_lock(self.lock.get()); - } - - /// Unlock the mutex - #[inline] - pub unsafe fn unlock(&self) { - mutex_unlock(self.lock.get()); - } - - #[inline] - pub unsafe fn destroy(&self) { - *self.lock.get() = 0; - } -} - -unsafe impl Send for Mutex {} - -unsafe impl Sync for Mutex {} - -pub struct ReentrantMutex { - pub lock: UnsafeCell, - pub owner: UnsafeCell, - pub own_count: UnsafeCell, -} - -impl ReentrantMutex { - pub const fn uninitialized() -> Self { - ReentrantMutex { - lock: UnsafeCell::new(0), - owner: UnsafeCell::new(0), - own_count: UnsafeCell::new(0), - } - } - - #[inline] - pub unsafe fn init(&mut self) { - *self.lock.get() = 0; - *self.owner.get() = 0; - *self.own_count.get() = 0; - } - - /// Try to lock the mutex - #[inline] - pub unsafe fn try_lock(&self) -> bool { - let pid = getpid().unwrap(); - if *self.own_count.get() > 0 && *self.owner.get() == pid { - *self.own_count.get() += 1; - true - } else { - if mutex_try_lock(self.lock.get()) { - *self.owner.get() = pid; - *self.own_count.get() = 1; - true - } else { - false - } - } - } - - /// Lock the mutex - #[inline] - pub unsafe fn lock(&self) { - let pid = getpid().unwrap(); - if *self.own_count.get() > 0 && *self.owner.get() == pid { - *self.own_count.get() += 1; - } else { - mutex_lock(self.lock.get()); - *self.owner.get() = pid; - *self.own_count.get() = 1; - } - } - - /// Unlock the mutex - #[inline] - pub unsafe fn unlock(&self) { - let pid = getpid().unwrap(); - if *self.own_count.get() > 0 && *self.owner.get() == pid { - *self.own_count.get() -= 1; - if *self.own_count.get() == 0 { - *self.owner.get() = 0; - mutex_unlock(self.lock.get()); - } - } - } - - #[inline] - pub unsafe fn destroy(&self) { - *self.lock.get() = 0; - *self.owner.get() = 0; - *self.own_count.get() = 0; - } -} - -unsafe impl Send for ReentrantMutex {} - -unsafe impl Sync for ReentrantMutex {} diff --git a/src/libstd/sys/redox/net/dns/answer.rs b/src/libstd/sys/redox/net/dns/answer.rs deleted file mode 100644 index e9b406bc685a1..0000000000000 --- a/src/libstd/sys/redox/net/dns/answer.rs +++ /dev/null @@ -1,12 +0,0 @@ -use crate::string::String; -use crate::vec::Vec; - -#[derive(Clone, Debug)] -pub struct DnsAnswer { - pub name: String, - pub a_type: u16, - pub a_class: u16, - pub ttl_a: u16, - pub ttl_b: u16, - pub data: Vec -} diff --git a/src/libstd/sys/redox/net/dns/mod.rs b/src/libstd/sys/redox/net/dns/mod.rs deleted file mode 100644 index 6533e0d5efb77..0000000000000 --- a/src/libstd/sys/redox/net/dns/mod.rs +++ /dev/null @@ -1,205 +0,0 @@ -pub use self::answer::DnsAnswer; -pub use self::query::DnsQuery; - -use crate::slice; -use crate::u16; -use crate::string::String; -use crate::vec::Vec; - -mod answer; -mod query; - -#[unstable(feature = "n16", issue="0")] -#[allow(non_camel_case_types)] -#[derive(Copy, Clone, Debug, Default)] -#[repr(packed)] -pub struct n16 { - inner: u16 -} - -impl n16 { - #[unstable(feature = "n16", issue="0")] - pub fn as_bytes(&self) -> &[u8] { - unsafe { slice::from_raw_parts((&self.inner as *const u16) as *const u8, 2) } - } - - #[unstable(feature = "n16", issue="0")] - pub fn from_bytes(bytes: &[u8]) -> Self { - n16 { - inner: unsafe { slice::from_raw_parts(bytes.as_ptr() as *const u16, bytes.len()/2)[0] } - } - } -} - -#[unstable(feature = "n16", issue="0")] -impl From for n16 { - fn from(value: u16) -> Self { - n16 { - inner: value.to_be() - } - } -} - -#[unstable(feature = "n16", issue="0")] -impl From for u16 { - fn from(value: n16) -> Self { - u16::from_be(value.inner) - } -} - -#[derive(Clone, Debug)] -pub struct Dns { - pub transaction_id: u16, - pub flags: u16, - pub queries: Vec, - pub answers: Vec -} - -impl Dns { - pub fn compile(&self) -> Vec { - let mut data = Vec::new(); - - macro_rules! push_u8 { - ($value:expr) => { - data.push($value); - }; - }; - - macro_rules! push_n16 { - ($value:expr) => { - data.extend_from_slice(n16::from($value).as_bytes()); - }; - }; - - push_n16!(self.transaction_id); - push_n16!(self.flags); - push_n16!(self.queries.len() as u16); - push_n16!(self.answers.len() as u16); - push_n16!(0); - push_n16!(0); - - for query in self.queries.iter() { - for part in query.name.split('.') { - push_u8!(part.len() as u8); - data.extend_from_slice(part.as_bytes()); - } - push_u8!(0); - push_n16!(query.q_type); - push_n16!(query.q_class); - } - - data - } - - pub fn parse(data: &[u8]) -> Result { - let name_ind = 0b11000000; - let mut i = 0; - - macro_rules! pop_u8 { - () => { - { - i += 1; - if i > data.len() { - return Err(format!("{}: {}: pop_u8", file!(), line!())); - } - data[i - 1] - } - }; - }; - - macro_rules! pop_n16 { - () => { - { - i += 2; - if i > data.len() { - return Err(format!("{}: {}: pop_n16", file!(), line!())); - } - u16::from(n16::from_bytes(&data[i - 2 .. i])) - } - }; - }; - - macro_rules! pop_data { - () => { - { - let mut data = Vec::new(); - - let data_len = pop_n16!(); - for _data_i in 0..data_len { - data.push(pop_u8!()); - } - - data - } - }; - }; - - macro_rules! pop_name { - () => { - { - let mut name = String::new(); - let old_i = i; - - loop { - let name_len = pop_u8!(); - if name_len & name_ind == name_ind { - i -= 1; - i = (pop_n16!() - ((name_ind as u16) << 8)) as usize; - continue; - } - if name_len == 0 { - break; - } - if ! name.is_empty() { - name.push('.'); - } - for _name_i in 0..name_len { - name.push(pop_u8!() as char); - } - } - - if i <= old_i { - i = old_i + 2; - } - - name - } - }; - }; - - let transaction_id = pop_n16!(); - let flags = pop_n16!(); - let queries_len = pop_n16!(); - let answers_len = pop_n16!(); - pop_n16!(); - pop_n16!(); - - let mut queries = Vec::new(); - for _query_i in 0..queries_len { - queries.push(DnsQuery { - name: pop_name!(), - q_type: pop_n16!(), - q_class: pop_n16!() - }); - } - - let mut answers = Vec::new(); - for _answer_i in 0..answers_len { - answers.push(DnsAnswer { - name: pop_name!(), - a_type: pop_n16!(), - a_class: pop_n16!(), - ttl_a: pop_n16!(), - ttl_b: pop_n16!(), - data: pop_data!() - }); - } - - Ok(Dns { - transaction_id, - flags, - queries, - answers, - }) - } -} diff --git a/src/libstd/sys/redox/net/dns/query.rs b/src/libstd/sys/redox/net/dns/query.rs deleted file mode 100644 index 65fb241b03737..0000000000000 --- a/src/libstd/sys/redox/net/dns/query.rs +++ /dev/null @@ -1,8 +0,0 @@ -use crate::string::String; - -#[derive(Clone, Debug)] -pub struct DnsQuery { - pub name: String, - pub q_type: u16, - pub q_class: u16 -} diff --git a/src/libstd/sys/redox/net/mod.rs b/src/libstd/sys/redox/net/mod.rs deleted file mode 100644 index dbaa140ed8a0f..0000000000000 --- a/src/libstd/sys/redox/net/mod.rs +++ /dev/null @@ -1,140 +0,0 @@ -use crate::fs::File; -use crate::io::{Error, Read, self}; -use crate::iter::Iterator; -use crate::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; -use crate::str::FromStr; -use crate::string::{String, ToString}; -use crate::sys::syscall::EINVAL; -use crate::time::{self, Duration}; -use crate::vec::{IntoIter, Vec}; -use crate::convert::{TryFrom, TryInto}; - -use self::dns::{Dns, DnsQuery}; - -pub use self::tcp::{TcpStream, TcpListener}; -pub use self::udp::UdpSocket; - -pub mod netc; - -mod dns; -mod tcp; -mod udp; - -pub struct LookupHost(IntoIter, u16); - -impl LookupHost { - pub fn port(&self) -> u16 { - self.1 - } -} - -impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option { - self.0.next() - } -} - -impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(s: &str) -> io::Result { - macro_rules! try_opt { - ($e:expr, $msg:expr) => ( - match $e { - Some(r) => r, - None => return Err(io::Error::new(io::ErrorKind::InvalidInput, - $msg)), - } - ) - } - - // split the string by ':' and convert the second part to u16 - let mut parts_iter = s.rsplitn(2, ':'); - let port_str = try_opt!(parts_iter.next(), "invalid socket address"); - let host = try_opt!(parts_iter.next(), "invalid socket address"); - let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value"); - - (host, port).try_into() - } -} - -impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from((host, port): (&'a str, u16)) -> io::Result { - let mut ip_string = String::new(); - File::open("/etc/net/ip")?.read_to_string(&mut ip_string)?; - let ip: Vec = ip_string.trim().split('.').map(|part| part.parse::() - .unwrap_or(0)).collect(); - - let mut dns_string = String::new(); - File::open("/etc/net/dns")?.read_to_string(&mut dns_string)?; - let dns: Vec = dns_string.trim().split('.').map(|part| part.parse::() - .unwrap_or(0)).collect(); - - if ip.len() == 4 && dns.len() == 4 { - let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap(); - let tid = (time.subsec_nanos() >> 16) as u16; - - let packet = Dns { - transaction_id: tid, - flags: 0x0100, - queries: vec![DnsQuery { - name: host.to_string(), - q_type: 0x0001, - q_class: 0x0001, - }], - answers: vec![] - }; - - let packet_data = packet.compile(); - - let my_ip = Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]); - let dns_ip = Ipv4Addr::new(dns[0], dns[1], dns[2], dns[3]); - let socket = UdpSocket::bind(Ok(&SocketAddr::V4(SocketAddrV4::new(my_ip, 0))))?; - socket.set_read_timeout(Some(Duration::new(5, 0)))?; - socket.set_write_timeout(Some(Duration::new(5, 0)))?; - socket.connect(Ok(&SocketAddr::V4(SocketAddrV4::new(dns_ip, 53))))?; - socket.send(&packet_data)?; - - let mut buf = [0; 65536]; - let count = socket.recv(&mut buf)?; - - match Dns::parse(&buf[.. count]) { - Ok(response) => { - let mut addrs = vec![]; - for answer in response.answers.iter() { - if answer.a_type == 0x0001 && answer.a_class == 0x0001 - && answer.data.len() == 4 - { - let answer_ip = Ipv4Addr::new(answer.data[0], - answer.data[1], - answer.data[2], - answer.data[3]); - addrs.push(SocketAddr::V4(SocketAddrV4::new(answer_ip, 0))); - } - } - Ok(LookupHost(addrs.into_iter(), port)) - }, - Err(_err) => Err(Error::from_raw_os_error(EINVAL)) - } - } else { - Err(Error::from_raw_os_error(EINVAL)) - } - } -} - -fn path_to_peer_addr(path_str: &str) -> SocketAddr { - let mut parts = path_str.split('/').next().unwrap_or("").split(':').skip(1); - let host = Ipv4Addr::from_str(parts.next().unwrap_or("")).unwrap_or(Ipv4Addr::new(0, 0, 0, 0)); - let port = parts.next().unwrap_or("").parse::().unwrap_or(0); - SocketAddr::V4(SocketAddrV4::new(host, port)) -} - -fn path_to_local_addr(path_str: &str) -> SocketAddr { - let mut parts = path_str.split('/').nth(1).unwrap_or("").split(':'); - let host = Ipv4Addr::from_str(parts.next().unwrap_or("")).unwrap_or(Ipv4Addr::new(0, 0, 0, 0)); - let port = parts.next().unwrap_or("").parse::().unwrap_or(0); - SocketAddr::V4(SocketAddrV4::new(host, port)) -} diff --git a/src/libstd/sys/redox/net/netc.rs b/src/libstd/sys/redox/net/netc.rs deleted file mode 100644 index 420a15a4063f3..0000000000000 --- a/src/libstd/sys/redox/net/netc.rs +++ /dev/null @@ -1,47 +0,0 @@ -pub type in_addr_t = u32; -pub type in_port_t = u16; - -pub type socklen_t = u32; -pub type sa_family_t = u16; - -pub const AF_INET: sa_family_t = 2; -pub const AF_INET6: sa_family_t = 23; - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct in_addr { - pub s_addr: in_addr_t, -} - -#[derive(Copy, Clone)] -#[repr(align(4))] -#[repr(C)] -pub struct in6_addr { - pub s6_addr: [u8; 16], -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct sockaddr { - pub sa_family: sa_family_t, - pub sa_data: [u8; 14], -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct sockaddr_in { - pub sin_family: sa_family_t, - pub sin_port: in_port_t, - pub sin_addr: in_addr, - pub sin_zero: [u8; 8], -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct sockaddr_in6 { - pub sin6_family: sa_family_t, - pub sin6_port: in_port_t, - pub sin6_flowinfo: u32, - pub sin6_addr: in6_addr, - pub sin6_scope_id: u32, -} diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs deleted file mode 100644 index 494f943c96b53..0000000000000 --- a/src/libstd/sys/redox/net/tcp.rs +++ /dev/null @@ -1,251 +0,0 @@ -use crate::cmp; -use crate::io::{self, Error, ErrorKind, Result, IoSlice, IoSliceMut}; -use crate::mem; -use crate::net::{SocketAddr, Shutdown}; -use crate::path::Path; -use crate::sys::fs::{File, OpenOptions}; -use crate::sys::syscall::TimeSpec; -use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::time::Duration; - -use super::{path_to_peer_addr, path_to_local_addr}; - -#[derive(Debug)] -pub struct TcpStream(File); - -impl TcpStream { - pub fn connect(addr: Result<&SocketAddr>) -> Result { - let path = format!("tcp:{}", addr?); - let mut options = OpenOptions::new(); - options.read(true); - options.write(true); - Ok(TcpStream(File::open(Path::new(path.as_str()), &options)?)) - } - - pub fn connect_timeout(_addr: &SocketAddr, _timeout: Duration) -> Result { - Err(Error::new(ErrorKind::Other, "TcpStream::connect_timeout not implemented")) - } - - pub fn duplicate(&self) -> Result { - Ok(TcpStream(self.0.dup(&[])?)) - } - - pub fn read(&self, buf: &mut [u8]) -> Result { - self.0.read(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - io::default_read_vectored(|b| self.read(b), bufs) - } - - pub fn write(&self, buf: &[u8]) -> Result { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - io::default_write_vectored(|b| self.write(b), bufs) - } - - pub fn take_error(&self) -> Result> { - Ok(None) - } - - pub fn peer_addr(&self) -> Result { - let path = self.0.path()?; - Ok(path_to_peer_addr(path.to_str().unwrap_or(""))) - } - - pub fn socket_addr(&self) -> Result { - let path = self.0.path()?; - Ok(path_to_local_addr(path.to_str().unwrap_or(""))) - } - - pub fn peek(&self, _buf: &mut [u8]) -> Result { - Err(Error::new(ErrorKind::Other, "TcpStream::peek not implemented")) - } - - pub fn shutdown(&self, _how: Shutdown) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpStream::shutdown not implemented")) - } - - pub fn nodelay(&self) -> Result { - Err(Error::new(ErrorKind::Other, "TcpStream::nodelay not implemented")) - } - - pub fn nonblocking(&self) -> Result { - self.0.fd().nonblocking() - } - - pub fn only_v6(&self) -> Result { - Err(Error::new(ErrorKind::Other, "TcpStream::only_v6 not implemented")) - } - - pub fn ttl(&self) -> Result { - let mut ttl = [0]; - let file = self.0.dup(b"ttl")?; - file.read(&mut ttl)?; - Ok(ttl[0] as u32) - } - - pub fn read_timeout(&self) -> Result> { - let mut time = TimeSpec::default(); - let file = self.0.dup(b"read_timeout")?; - if file.read(&mut time)? >= mem::size_of::() { - Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) - } else { - Ok(None) - } - } - - pub fn write_timeout(&self) -> Result> { - let mut time = TimeSpec::default(); - let file = self.0.dup(b"write_timeout")?; - if file.read(&mut time)? >= mem::size_of::() { - Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) - } else { - Ok(None) - } - } - - pub fn set_nodelay(&self, _nodelay: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpStream::set_nodelay not implemented")) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()> { - self.0.fd().set_nonblocking(nonblocking) - } - - pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpStream::set_only_v6 not implemented")) - } - - pub fn set_ttl(&self, ttl: u32) -> Result<()> { - let file = self.0.dup(b"ttl")?; - file.write(&[cmp::min(ttl, 255) as u8])?; - Ok(()) - } - - pub fn set_read_timeout(&self, duration_option: Option) -> Result<()> { - let file = self.0.dup(b"read_timeout")?; - if let Some(duration) = duration_option { - if duration.as_secs() == 0 && duration.subsec_nanos() == 0 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout")); - } - file.write(&TimeSpec { - tv_sec: duration.as_secs() as i64, - tv_nsec: duration.subsec_nanos() as i32 - })?; - } else { - file.write(&[])?; - } - Ok(()) - } - - pub fn set_write_timeout(&self, duration_option: Option) -> Result<()> { - let file = self.0.dup(b"write_timeout")?; - if let Some(duration) = duration_option { - if duration.as_secs() == 0 && duration.subsec_nanos() == 0 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout")); - } - file.write(&TimeSpec { - tv_sec: duration.as_secs() as i64, - tv_nsec: duration.subsec_nanos() as i32 - })?; - } else { - file.write(&[])?; - } - Ok(()) - } -} - -impl AsInner for TcpStream { - fn as_inner(&self) -> &File { &self.0 } -} - -impl FromInner for TcpStream { - fn from_inner(file: File) -> TcpStream { - TcpStream(file) - } -} - -impl IntoInner for TcpStream { - fn into_inner(self) -> File { self.0 } -} - -#[derive(Debug)] -pub struct TcpListener(File); - -impl TcpListener { - pub fn bind(addr: Result<&SocketAddr>) -> Result { - let path = format!("tcp:/{}", addr?); - let mut options = OpenOptions::new(); - options.read(true); - options.write(true); - Ok(TcpListener(File::open(Path::new(path.as_str()), &options)?)) - } - - pub fn accept(&self) -> Result<(TcpStream, SocketAddr)> { - let file = self.0.dup(b"listen")?; - let path = file.path()?; - let peer_addr = path_to_peer_addr(path.to_str().unwrap_or("")); - Ok((TcpStream(file), peer_addr)) - } - - pub fn duplicate(&self) -> Result { - Ok(TcpListener(self.0.dup(&[])?)) - } - - pub fn take_error(&self) -> Result> { - Ok(None) - } - - pub fn socket_addr(&self) -> Result { - let path = self.0.path()?; - Ok(path_to_local_addr(path.to_str().unwrap_or(""))) - } - - pub fn nonblocking(&self) -> Result { - Err(Error::new(ErrorKind::Other, "TcpListener::nonblocking not implemented")) - } - - pub fn only_v6(&self) -> Result { - Err(Error::new(ErrorKind::Other, "TcpListener::only_v6 not implemented")) - } - - pub fn ttl(&self) -> Result { - let mut ttl = [0]; - let file = self.0.dup(b"ttl")?; - file.read(&mut ttl)?; - Ok(ttl[0] as u32) - } - - pub fn set_nonblocking(&self, _nonblocking: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpListener::set_nonblocking not implemented")) - } - - pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "TcpListener::set_only_v6 not implemented")) - } - - pub fn set_ttl(&self, ttl: u32) -> Result<()> { - let file = self.0.dup(b"ttl")?; - file.write(&[cmp::min(ttl, 255) as u8])?; - Ok(()) - } -} - -impl AsInner for TcpListener { - fn as_inner(&self) -> &File { &self.0 } -} - -impl FromInner for TcpListener { - fn from_inner(file: File) -> TcpListener { - TcpListener(file) - } -} - -impl IntoInner for TcpListener { - fn into_inner(self) -> File { self.0 } -} diff --git a/src/libstd/sys/redox/net/udp.rs b/src/libstd/sys/redox/net/udp.rs deleted file mode 100644 index 274123dce4b58..0000000000000 --- a/src/libstd/sys/redox/net/udp.rs +++ /dev/null @@ -1,237 +0,0 @@ -use crate::cell::UnsafeCell; -use crate::cmp; -use crate::io::{self, Error, ErrorKind, Result}; -use crate::mem; -use crate::net::{SocketAddr, Ipv4Addr, Ipv6Addr}; -use crate::path::Path; -use crate::sys::fs::{File, OpenOptions}; -use crate::sys::syscall::TimeSpec; -use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::time::Duration; - -use super::{path_to_peer_addr, path_to_local_addr}; - -#[derive(Debug)] -pub struct UdpSocket(File, UnsafeCell>); - -impl UdpSocket { - pub fn bind(addr: Result<&SocketAddr>) -> Result { - let path = format!("udp:/{}", addr?); - let mut options = OpenOptions::new(); - options.read(true); - options.write(true); - Ok(UdpSocket(File::open(Path::new(path.as_str()), &options)?, UnsafeCell::new(None))) - } - - fn get_conn(&self) -> &mut Option { - unsafe { &mut *(self.1.get()) } - } - - pub fn connect(&self, addr: Result<&SocketAddr>) -> Result<()> { - unsafe { *self.1.get() = Some(*addr?) }; - Ok(()) - } - - pub fn duplicate(&self) -> Result { - let new_bind = self.0.dup(&[])?; - let new_conn = *self.get_conn(); - Ok(UdpSocket(new_bind, UnsafeCell::new(new_conn))) - } - - pub fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> { - let from = self.0.dup(b"listen")?; - let path = from.path()?; - let peer_addr = path_to_peer_addr(path.to_str().unwrap_or("")); - let count = from.read(buf)?; - Ok((count, peer_addr)) - } - - pub fn recv(&self, buf: &mut [u8]) -> Result { - if let Some(addr) = *self.get_conn() { - let from = self.0.dup(addr.to_string().as_bytes())?; - from.read(buf) - } else { - Err(Error::new(ErrorKind::Other, "UdpSocket::recv not connected")) - } - } - - pub fn send_to(&self, buf: &[u8], addr: &SocketAddr) -> Result { - let to = self.0.dup(format!("{}", addr).as_bytes())?; - to.write(buf) - } - - pub fn send(&self, buf: &[u8]) -> Result { - if let Some(addr) = *self.get_conn() { - self.send_to(buf, &addr) - } else { - Err(Error::new(ErrorKind::Other, "UdpSocket::send not connected")) - } - } - - pub fn take_error(&self) -> Result> { - Ok(None) - } - - pub fn peer_addr(&self) -> Result { - let path = self.0.path()?; - Ok(path_to_peer_addr(path.to_str().unwrap_or(""))) - } - - pub fn socket_addr(&self) -> Result { - let path = self.0.path()?; - Ok(path_to_local_addr(path.to_str().unwrap_or(""))) - } - - pub fn peek(&self, _buf: &mut [u8]) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::peek not implemented")) - } - - pub fn peek_from(&self, _buf: &mut [u8]) -> Result<(usize, SocketAddr)> { - Err(Error::new(ErrorKind::Other, "UdpSocket::peek_from not implemented")) - } - - pub fn broadcast(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::broadcast not implemented")) - } - - pub fn multicast_loop_v4(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::multicast_loop_v4 not implemented")) - } - - pub fn multicast_loop_v6(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::multicast_loop_v6 not implemented")) - } - - pub fn multicast_ttl_v4(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::multicast_ttl_v4 not implemented")) - } - - pub fn nonblocking(&self) -> Result { - self.0.fd().nonblocking() - } - - pub fn only_v6(&self) -> Result { - Err(Error::new(ErrorKind::Other, "UdpSocket::only_v6 not implemented")) - } - - pub fn ttl(&self) -> Result { - let mut ttl = [0]; - let file = self.0.dup(b"ttl")?; - file.read(&mut ttl)?; - Ok(ttl[0] as u32) - } - - pub fn read_timeout(&self) -> Result> { - let mut time = TimeSpec::default(); - let file = self.0.dup(b"read_timeout")?; - if file.read(&mut time)? >= mem::size_of::() { - Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) - } else { - Ok(None) - } - } - - pub fn write_timeout(&self) -> Result> { - let mut time = TimeSpec::default(); - let file = self.0.dup(b"write_timeout")?; - if file.read(&mut time)? >= mem::size_of::() { - Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))) - } else { - Ok(None) - } - } - - pub fn set_broadcast(&self, _broadcast: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_broadcast not implemented")) - } - - pub fn set_multicast_loop_v4(&self, _multicast_loop_v4: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_multicast_loop_v4 not implemented")) - } - - pub fn set_multicast_loop_v6(&self, _multicast_loop_v6: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_multicast_loop_v6 not implemented")) - } - - pub fn set_multicast_ttl_v4(&self, _multicast_ttl_v4: u32) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_multicast_ttl_v4 not implemented")) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()> { - self.0.fd().set_nonblocking(nonblocking) - } - - pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::set_only_v6 not implemented")) - } - - pub fn set_ttl(&self, ttl: u32) -> Result<()> { - let file = self.0.dup(b"ttl")?; - file.write(&[cmp::min(ttl, 255) as u8])?; - Ok(()) - } - - pub fn set_read_timeout(&self, duration_option: Option) -> Result<()> { - let file = self.0.dup(b"read_timeout")?; - if let Some(duration) = duration_option { - if duration.as_secs() == 0 && duration.subsec_nanos() == 0 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout")); - } - file.write(&TimeSpec { - tv_sec: duration.as_secs() as i64, - tv_nsec: duration.subsec_nanos() as i32 - })?; - } else { - file.write(&[])?; - } - Ok(()) - } - - pub fn set_write_timeout(&self, duration_option: Option) -> Result<()> { - let file = self.0.dup(b"write_timeout")?; - if let Some(duration) = duration_option { - if duration.as_secs() == 0 && duration.subsec_nanos() == 0 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout")); - } - file.write(&TimeSpec { - tv_sec: duration.as_secs() as i64, - tv_nsec: duration.subsec_nanos() as i32 - })?; - } else { - file.write(&[])?; - } - Ok(()) - } - - pub fn join_multicast_v4(&self, _multiaddr: &Ipv4Addr, _interface: &Ipv4Addr) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::join_multicast_v4 not implemented")) - } - - pub fn join_multicast_v6(&self, _multiaddr: &Ipv6Addr, _interface: u32) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::join_multicast_v6 not implemented")) - } - - pub fn leave_multicast_v4(&self, _multiaddr: &Ipv4Addr, _interface: &Ipv4Addr) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::leave_multicast_v4 not implemented")) - } - - pub fn leave_multicast_v6(&self, _multiaddr: &Ipv6Addr, _interface: u32) -> Result<()> { - Err(Error::new(ErrorKind::Other, "UdpSocket::leave_multicast_v6 not implemented")) - } -} - -impl AsInner for UdpSocket { - fn as_inner(&self) -> &File { &self.0 } -} - -impl FromInner for UdpSocket { - fn from_inner(file: File) -> UdpSocket { - UdpSocket(file, UnsafeCell::new(None)) - } -} - -impl IntoInner for UdpSocket { - fn into_inner(self) -> File { self.0 } -} diff --git a/src/libstd/sys/redox/os.rs b/src/libstd/sys/redox/os.rs deleted file mode 100644 index 3ae201f698c2b..0000000000000 --- a/src/libstd/sys/redox/os.rs +++ /dev/null @@ -1,241 +0,0 @@ -//! Implementation of `std::os` functionality for unix systems - -#![allow(unused_imports)] // lots of cfg code here - -use libc::c_char; - -use crate::os::unix::prelude::*; - -use crate::error::Error as StdError; -use crate::ffi::{CStr, CString, OsStr, OsString}; -use crate::fmt; -use crate::io::{self, Read, Write}; -use crate::iter; -use crate::marker::PhantomData; -use crate::mem; -use crate::memchr; -use crate::path::{self, PathBuf}; -use crate::ptr; -use crate::slice; -use crate::str; -use crate::sys_common::mutex::Mutex; -use crate::sys::{cvt, cvt_libc, fd, syscall}; -use crate::vec; - -extern { - #[link_name = "__errno_location"] - fn errno_location() -> *mut i32; -} - -/// Returns the platform-specific value of errno -pub fn errno() -> i32 { - unsafe { - (*errno_location()) - } -} - -/// Gets a detailed string description for the given error number. -pub fn error_string(errno: i32) -> String { - if let Some(string) = syscall::STR_ERROR.get(errno as usize) { - string.to_string() - } else { - "unknown error".to_string() - } -} - -pub fn getcwd() -> io::Result { - let mut buf = [0; 4096]; - let count = cvt(syscall::getcwd(&mut buf))?; - Ok(PathBuf::from(OsString::from_vec(buf[.. count].to_vec()))) -} - -pub fn chdir(p: &path::Path) -> io::Result<()> { - cvt(syscall::chdir(p.to_str().unwrap())).and(Ok(())) -} - -pub struct SplitPaths<'a> { - iter: iter::Map bool>, - fn(&'a [u8]) -> PathBuf>, -} - -pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> { - fn bytes_to_path(b: &[u8]) -> PathBuf { - PathBuf::from(::from_bytes(b)) - } - fn is_semicolon(b: &u8) -> bool { *b == b';' } - let unparsed = unparsed.as_bytes(); - SplitPaths { - iter: unparsed.split(is_semicolon 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 { self.iter.next() } - fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } -} - -#[derive(Debug)] -pub struct JoinPathsError; - -pub fn join_paths(paths: I) -> Result - where I: Iterator, T: AsRef -{ - 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" } -} - -pub fn current_exe() -> io::Result { - use crate::fs::File; - - let mut file = File::open("sys:exe")?; - - let mut path = String::new(); - file.read_to_string(&mut path)?; - - if path.ends_with('\n') { - path.pop(); - } - - Ok(PathBuf::from(path)) -} - -pub static ENV_LOCK: Mutex = Mutex::new(); - -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) { self.iter.size_hint() } -} - -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(); - if environ == ptr::null() { - panic!("os::env() failure getting env string from OS: {}", - io::Error::last_os_error()); - } - let mut result = Vec::new(); - while *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> { - // 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(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(libc::unsetenv(nbuf.as_ptr())).map(|_| ()) - } -} - -pub fn page_size() -> usize { - 4096 -} - -pub fn temp_dir() -> PathBuf { - crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| { - PathBuf::from("/tmp") - }) -} - -pub fn home_dir() -> Option { - return crate::env::var_os("HOME").map(PathBuf::from); -} - -pub fn exit(code: i32) -> ! { - let _ = syscall::exit(code as usize); - unreachable!(); -} - -pub fn getpid() -> u32 { - syscall::getpid().unwrap() as u32 -} - -pub fn getppid() -> u32 { - syscall::getppid().unwrap() as u32 -} diff --git a/src/libstd/sys/redox/path.rs b/src/libstd/sys/redox/path.rs deleted file mode 100644 index b62d6c9878211..0000000000000 --- a/src/libstd/sys/redox/path.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::ffi::OsStr; -use crate::path::Prefix; - -#[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(path: &OsStr) -> Option> { - if let Some(path_str) = path.to_str() { - if let Some(_i) = path_str.find(':') { - // FIXME: Redox specific prefix - // Some(Prefix::Verbatim(OsStr::new(&path_str[..i]))) - None - } else { - None - } - } else { - None - } -} - -pub const MAIN_SEP_STR: &str = "/"; -pub const MAIN_SEP: char = '/'; diff --git a/src/libstd/sys/redox/pipe.rs b/src/libstd/sys/redox/pipe.rs deleted file mode 100644 index 29cacb6d562f2..0000000000000 --- a/src/libstd/sys/redox/pipe.rs +++ /dev/null @@ -1,101 +0,0 @@ -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::sys::{cvt, syscall}; -use crate::sys::fd::FileDesc; - -//////////////////////////////////////////////////////////////////////////////// -// Anonymous pipes -//////////////////////////////////////////////////////////////////////////////// - -pub struct AnonPipe(FileDesc); - -pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { - let mut fds = [0; 2]; - cvt(syscall::pipe2(&mut fds, syscall::O_CLOEXEC))?; - Ok((AnonPipe(FileDesc::new(fds[0])), AnonPipe(FileDesc::new(fds[1])))) -} - -impl AnonPipe { - pub fn from_fd(fd: FileDesc) -> io::Result { - fd.set_cloexec()?; - Ok(AnonPipe(fd)) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - crate::io::default_read_vectored(|buf| self.read(buf), bufs) - } - - pub fn write(&self, buf: &[u8]) -> io::Result { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - crate::io::default_write_vectored(|buf| self.write(buf), bufs) - } - - pub fn fd(&self) -> &FileDesc { &self.0 } - pub fn into_fd(self) -> FileDesc { self.0 } -} - -pub fn read2(p1: AnonPipe, - v1: &mut Vec, - p2: AnonPipe, - v2: &mut Vec) -> io::Result<()> { - //FIXME: Use event based I/O multiplexing - //unimplemented!() - - p1.0.read_to_end(v1)?; - p2.0.read_to_end(v2)?; - - Ok(()) - - /* - // 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)?; - - loop { - // wait for either pipe to become readable using `select` - cvt_r(|| unsafe { - let mut read: libc::fd_set = mem::zeroed(); - libc::FD_SET(p1.raw(), &mut read); - libc::FD_SET(p2.raw(), &mut read); - libc::select(max + 1, &mut read, ptr::null_mut(), ptr::null_mut(), - ptr::null_mut()) - })?; - - // 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. - let read = |fd: &FileDesc, dst: &mut Vec| { - 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) - } - } - } - }; - if read(&p1, v1)? { - p2.set_nonblocking(false)?; - return p2.read_to_end(v2).map(|_| ()); - } - if read(&p2, v2)? { - p1.set_nonblocking(false)?; - return p1.read_to_end(v1).map(|_| ()); - } - } - */ -} diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs deleted file mode 100644 index 2a553b2c93bd3..0000000000000 --- a/src/libstd/sys/redox/process.rs +++ /dev/null @@ -1,609 +0,0 @@ -use crate::env::{self, split_paths}; -use crate::ffi::{CStr, OsStr}; -use crate::fmt; -use crate::fs::File; -use crate::io::{self, prelude::*, BufReader, Error, ErrorKind, SeekFrom}; -use crate::os::unix::ffi::OsStrExt; -use crate::path::{Path, PathBuf}; -use crate::ptr; -use crate::sys::ext::fs::MetadataExt; -use crate::sys::ext::io::AsRawFd; -use crate::sys::fd::FileDesc; -use crate::sys::fs::{File as SysFile, OpenOptions}; -use crate::sys::os::{ENV_LOCK, environ}; -use crate::sys::pipe::{self, AnonPipe}; -use crate::sys::{cvt, syscall}; -use crate::sys_common::process::{CommandEnv, DefaultEnvKey}; - -use libc::{EXIT_SUCCESS, EXIT_FAILURE}; - -//////////////////////////////////////////////////////////////////////////////// -// 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: String, - args: Vec, - env: CommandEnv, - - cwd: Option, - uid: Option, - gid: Option, - saw_nul: bool, - closures: Vec io::Result<()> + Send + Sync>>, - stdin: Option, - stdout: Option, - stderr: Option, -} - -// passed back to std::process with the pipes connected to the child, if any -// were requested -pub struct StdioPipes { - pub stdin: Option, - pub stdout: Option, - pub stderr: Option, -} - -// passed to do_exec() with configuration of what the child stdio should look -// like -struct ChildPipes { - stdin: ChildStdio, - stdout: ChildStdio, - stderr: ChildStdio, -} - -enum ChildStdio { - Inherit, - Explicit(usize), - Owned(FileDesc), -} - -pub enum Stdio { - Inherit, - Null, - MakePipe, - Fd(FileDesc), -} - -impl Command { - pub fn new(program: &OsStr) -> Command { - Command { - program: program.to_str().unwrap().to_owned(), - args: Vec::new(), - env: Default::default(), - cwd: None, - uid: None, - gid: None, - saw_nul: false, - closures: Vec::new(), - stdin: None, - stdout: None, - stderr: None, - } - } - - pub fn arg(&mut self, arg: &OsStr) { - self.args.push(arg.to_str().unwrap().to_owned()); - } - - pub fn env_mut(&mut self) -> &mut CommandEnv { - &mut self.env - } - - pub fn cwd(&mut self, dir: &OsStr) { - self.cwd = Some(dir.to_str().unwrap().to_owned()); - } - pub fn uid(&mut self, id: u32) { - self.uid = Some(id); - } - pub fn gid(&mut self, id: u32) { - self.gid = Some(id); - } - - pub unsafe fn pre_exec( - &mut self, - f: Box 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 spawn(&mut self, default: Stdio, needs_stdin: bool) - -> io::Result<(Process, StdioPipes)> { - const CLOEXEC_MSG_FOOTER: &[u8] = b"NOEX"; - - 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)?; - let (input, output) = pipe::anon_pipe()?; - - let pid = unsafe { - match cvt(syscall::clone(0))? { - 0 => { - drop(input); - let Err(err) = self.do_exec(theirs); - let errno = err.raw_os_error().unwrap_or(syscall::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()); - let _ = syscall::exit(1); - panic!("failed to exit"); - } - 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 { - 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 { - let Err(e) = self.do_exec(theirs); - e - }, - 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 syscall::exit) - unsafe fn do_exec(&mut self, stdio: ChildPipes) -> Result { - if let Some(fd) = stdio.stderr.fd() { - cvt(syscall::dup2(fd, 2, &[]))?; - let mut flags = cvt(syscall::fcntl(2, syscall::F_GETFD, 0))?; - flags &= ! syscall::O_CLOEXEC; - cvt(syscall::fcntl(2, syscall::F_SETFD, flags))?; - } - if let Some(fd) = stdio.stdout.fd() { - cvt(syscall::dup2(fd, 1, &[]))?; - let mut flags = cvt(syscall::fcntl(1, syscall::F_GETFD, 0))?; - flags &= ! syscall::O_CLOEXEC; - cvt(syscall::fcntl(1, syscall::F_SETFD, flags))?; - } - if let Some(fd) = stdio.stdin.fd() { - cvt(syscall::dup2(fd, 0, &[]))?; - let mut flags = cvt(syscall::fcntl(0, syscall::F_GETFD, 0))?; - flags &= ! syscall::O_CLOEXEC; - cvt(syscall::fcntl(0, syscall::F_SETFD, flags))?; - } - - if let Some(g) = self.gid { - cvt(syscall::setregid(g as usize, g as usize))?; - } - if let Some(u) = self.uid { - cvt(syscall::setreuid(u as usize, u as usize))?; - } - if let Some(ref cwd) = self.cwd { - cvt(syscall::chdir(cwd))?; - } - - for callback in self.closures.iter_mut() { - callback()?; - } - - self.env.apply(); - - let program = if self.program.contains(':') || self.program.contains('/') { - Some(PathBuf::from(&self.program)) - } else if let Ok(path_env) = env::var("PATH") { - let mut program = None; - for mut path in split_paths(&path_env) { - path.push(&self.program); - if path.exists() { - program = Some(path); - break; - } - } - program - } else { - None - }; - - let mut file = if let Some(program) = program { - File::open(program.as_os_str())? - } else { - return Err(io::Error::from_raw_os_error(syscall::ENOENT)); - }; - - // Push all the arguments - let mut args: Vec<[usize; 2]> = Vec::with_capacity(1 + self.args.len()); - - let interpreter = { - let mut reader = BufReader::new(&file); - - let mut shebang = [0; 2]; - let mut read = 0; - loop { - match reader.read(&mut shebang[read..])? { - 0 => break, - n => read += n, - } - } - - if &shebang == b"#!" { - // This is an interpreted script. - // First of all, since we'll be passing another file to - // fexec(), we need to manually check that we have permission - // to execute this file: - let uid = cvt(syscall::getuid())?; - let gid = cvt(syscall::getgid())?; - let meta = file.metadata()?; - - let mode = if uid == meta.uid() as usize { - meta.mode() >> 3*2 & 0o7 - } else if gid == meta.gid() as usize { - meta.mode() >> 3*1 & 0o7 - } else { - meta.mode() & 0o7 - }; - if mode & 1 == 0 { - return Err(io::Error::from_raw_os_error(syscall::EPERM)); - } - - // Second of all, we need to actually read which interpreter it wants - let mut interpreter = Vec::new(); - reader.read_until(b'\n', &mut interpreter)?; - // Pop one trailing newline, if any - if interpreter.ends_with(&[b'\n']) { - interpreter.pop().unwrap(); - } - - // FIXME: Here we could just reassign `file` directly, if it - // wasn't for lexical lifetimes. Remove the whole `let - // interpreter = { ... };` hack once NLL lands. - // NOTE: Although DO REMEMBER to make sure the interpreter path - // still lives long enough to reach fexec. - Some(interpreter) - } else { - None - } - }; - if let Some(ref interpreter) = interpreter { - let path: &OsStr = OsStr::from_bytes(&interpreter); - file = File::open(path)?; - - args.push([interpreter.as_ptr() as usize, interpreter.len()]); - } else { - file.seek(SeekFrom::Start(0))?; - } - - args.push([self.program.as_ptr() as usize, self.program.len()]); - args.extend(self.args.iter().map(|arg| [arg.as_ptr() as usize, arg.len()])); - - // Push all the variables - let mut vars: Vec<[usize; 2]> = Vec::new(); - { - let _guard = ENV_LOCK.lock(); - let mut environ = *environ(); - while *environ != ptr::null() { - let var = CStr::from_ptr(*environ).to_bytes(); - vars.push([var.as_ptr() as usize, var.len()]); - environ = environ.offset(1); - } - } - - if let Err(err) = syscall::fexec(file.as_raw_fd(), &args, &vars) { - Err(io::Error::from_raw_os_error(err.errno as i32)) - } else { - panic!("return from exec without err"); - } - } - - 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)) - } -} - -impl Stdio { - fn to_child_stdio(&self, readable: bool) - -> io::Result<(ChildStdio, Option)> { - 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() <= 2 { - 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 fd = SysFile::open(Path::new("null:"), &opts)?; - Ok((ChildStdio::Owned(fd.into_fd()), None)) - } - } - } -} - -impl From for Stdio { - fn from(pipe: AnonPipe) -> Stdio { - Stdio::Fd(pipe.into_fd()) - } -} - -impl From for Stdio { - fn from(file: SysFile) -> Stdio { - Stdio::Fd(file.into_fd()) - } -} - -impl ChildStdio { - fn fd(&self) -> Option { - 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(()) - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Processes -//////////////////////////////////////////////////////////////////////////////// - -/// Unix exit statuses -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitStatus(i32); - -impl ExitStatus { - fn exited(&self) -> bool { - self.0 & 0x7F == 0 - } - - pub fn success(&self) -> bool { - self.code() == Some(0) - } - - pub fn code(&self) -> Option { - if self.exited() { - Some((self.0 >> 8) & 0xFF) - } else { - None - } - } - - pub fn signal(&self) -> Option { - if !self.exited() { - Some(self.0 & 0x7F) - } else { - None - } - } -} - -impl From for ExitStatus { - fn from(a: i32) -> 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 _); - - pub fn as_i32(&self) -> i32 { - self.0 as i32 - } -} - -/// The unique ID of the process (this should never be negative). -pub struct Process { - pid: usize, - status: Option, -} - -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(syscall::kill(self.pid, syscall::SIGKILL))?; - Ok(()) - } - } - - pub fn wait(&mut self) -> io::Result { - if let Some(status) = self.status { - return Ok(status) - } - let mut status = 0; - cvt(syscall::waitpid(self.pid, &mut status, 0))?; - self.status = Some(ExitStatus(status as i32)); - Ok(ExitStatus(status as i32)) - } - - pub fn try_wait(&mut self) -> io::Result> { - if let Some(status) = self.status { - return Ok(Some(status)) - } - let mut status = 0; - let pid = cvt(syscall::waitpid(self.pid, &mut status, syscall::WNOHANG))?; - if pid == 0 { - Ok(None) - } else { - self.status = Some(ExitStatus(status as i32)); - Ok(Some(ExitStatus(status as i32))) - } - } -} diff --git a/src/libstd/sys/redox/rand.rs b/src/libstd/sys/redox/rand.rs deleted file mode 100644 index 5b58d1782bf0a..0000000000000 --- a/src/libstd/sys/redox/rand.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn hashmap_random_keys() -> (u64, u64) { - (0, 0) -} diff --git a/src/libstd/sys/redox/rwlock.rs b/src/libstd/sys/redox/rwlock.rs deleted file mode 100644 index 990e7551114bb..0000000000000 --- a/src/libstd/sys/redox/rwlock.rs +++ /dev/null @@ -1,51 +0,0 @@ -use super::mutex::Mutex; - -pub struct RWLock { - mutex: Mutex -} - -unsafe impl Send for RWLock {} -unsafe impl Sync for RWLock {} - -impl RWLock { - pub const fn new() -> RWLock { - RWLock { - mutex: Mutex::new() - } - } - - #[inline] - pub unsafe fn read(&self) { - self.mutex.lock(); - } - - #[inline] - pub unsafe fn try_read(&self) -> bool { - self.mutex.try_lock() - } - - #[inline] - pub unsafe fn write(&self) { - self.mutex.lock(); - } - - #[inline] - pub unsafe fn try_write(&self) -> bool { - self.mutex.try_lock() - } - - #[inline] - pub unsafe fn read_unlock(&self) { - self.mutex.unlock(); - } - - #[inline] - pub unsafe fn write_unlock(&self) { - self.mutex.unlock(); - } - - #[inline] - pub unsafe fn destroy(&self) { - self.mutex.destroy(); - } -} diff --git a/src/libstd/sys/redox/stack_overflow.rs b/src/libstd/sys/redox/stack_overflow.rs deleted file mode 100644 index cf01d323d45db..0000000000000 --- a/src/libstd/sys/redox/stack_overflow.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![cfg_attr(test, allow(dead_code))] - -pub struct Handler; - -impl Handler { - pub unsafe fn new() -> Handler { - Handler - } -} - -pub unsafe fn init() { - -} - -pub unsafe fn cleanup() { - -} diff --git a/src/libstd/sys/redox/stdio.rs b/src/libstd/sys/redox/stdio.rs deleted file mode 100644 index 33f5bdbb5d358..0000000000000 --- a/src/libstd/sys/redox/stdio.rs +++ /dev/null @@ -1,64 +0,0 @@ -use crate::io; -use crate::sys::{cvt, syscall}; -use crate::sys::fd::FileDesc; - -pub struct Stdin(()); -pub struct Stdout(()); -pub struct Stderr(()); - -impl Stdin { - pub fn new() -> io::Result { Ok(Stdin(())) } -} - -impl io::Read for Stdin { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - let fd = FileDesc::new(0); - let ret = fd.read(buf); - fd.into_raw(); - ret - } -} - -impl Stdout { - pub fn new() -> io::Result { Ok(Stdout(())) } -} - -impl io::Write for Stdout { - fn write(&mut self, buf: &[u8]) -> io::Result { - let fd = FileDesc::new(1); - let ret = fd.write(buf); - fd.into_raw(); - ret - } - - fn flush(&mut self) -> io::Result<()> { - cvt(syscall::fsync(1)).and(Ok(())) - } -} - -impl Stderr { - pub fn new() -> io::Result { Ok(Stderr(())) } -} - -impl io::Write for Stderr { - fn write(&mut self, buf: &[u8]) -> io::Result { - let fd = FileDesc::new(2); - let ret = fd.write(buf); - fd.into_raw(); - ret - } - - fn flush(&mut self) -> io::Result<()> { - cvt(syscall::fsync(2)).and(Ok(())) - } -} - -pub fn is_ebadf(err: &io::Error) -> bool { - err.raw_os_error() == Some(crate::sys::syscall::EBADF as i32) -} - -pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE; - -pub fn panic_output() -> Option { - Stderr::new().ok() -} diff --git a/src/libstd/sys/redox/syscall/arch/arm.rs b/src/libstd/sys/redox/syscall/arch/arm.rs deleted file mode 100644 index e640f7ed37631..0000000000000 --- a/src/libstd/sys/redox/syscall/arch/arm.rs +++ /dev/null @@ -1,73 +0,0 @@ -use super::error::{Error, Result}; - -pub unsafe fn syscall0(mut a: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a) - : "memory" - : "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall1(mut a: usize, b: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b) - : "memory" - : "volatile"); - - Error::demux(a) -} - -// Clobbers all registers - special for clone -pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b) - : "memory", "r0", "r1", "r2", "r3", "r4" - : "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b), "{r1}"(c) - : "memory" - : "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d) - : "memory" - : "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d), "{r3}"(e) - : "memory" - : "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) - -> Result { - asm!("swi $$0" - : "={r0}"(a) - : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d), "{r3}"(e), "{r4}"(f) - : "memory" - : "volatile"); - - Error::demux(a) -} diff --git a/src/libstd/sys/redox/syscall/arch/x86.rs b/src/libstd/sys/redox/syscall/arch/x86.rs deleted file mode 100644 index 0cd6409bb06f8..0000000000000 --- a/src/libstd/sys/redox/syscall/arch/x86.rs +++ /dev/null @@ -1,73 +0,0 @@ -use super::error::{Error, Result}; - -pub unsafe fn syscall0(mut a: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall1(mut a: usize, b: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -// Clobbers all registers - special for clone -pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b) - : "memory", "ebx", "ecx", "edx", "esi", "edi" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b), "{ecx}"(c) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d), "{esi}"(e) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) - -> Result { - asm!("int 0x80" - : "={eax}"(a) - : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d), "{esi}"(e), "{edi}"(f) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} diff --git a/src/libstd/sys/redox/syscall/arch/x86_64.rs b/src/libstd/sys/redox/syscall/arch/x86_64.rs deleted file mode 100644 index 52ad01bd4a8cf..0000000000000 --- a/src/libstd/sys/redox/syscall/arch/x86_64.rs +++ /dev/null @@ -1,74 +0,0 @@ -use super::error::{Error, Result}; - -pub unsafe fn syscall0(mut a: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall1(mut a: usize, b: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -// Clobbers all registers - special for clone -pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b) - : "memory", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", - "r9", "r10", "r11", "r12", "r13", "r14", "r15" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b), "{rcx}"(c) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d), "{rsi}"(e) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} - -pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) - -> Result { - asm!("int 0x80" - : "={rax}"(a) - : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d), "{rsi}"(e), "{rdi}"(f) - : "memory" - : "intel", "volatile"); - - Error::demux(a) -} diff --git a/src/libstd/sys/redox/syscall/call.rs b/src/libstd/sys/redox/syscall/call.rs deleted file mode 100644 index b9abb48a8d368..0000000000000 --- a/src/libstd/sys/redox/syscall/call.rs +++ /dev/null @@ -1,348 +0,0 @@ -use super::arch::*; -use super::data::{SigAction, Stat, StatVfs, TimeSpec}; -use super::error::Result; -use super::number::*; - -use core::{mem, ptr}; - -// Signal restorer -extern "C" fn restorer() -> ! { - sigreturn().unwrap(); - unreachable!(); -} - -/// Set the end of the process's heap -/// -/// When `addr` is `0`, this function will return the current break. -/// -/// When `addr` is nonzero, this function will attempt to set the end of the process's -/// heap to `addr` and return the new program break. The new program break should be -/// checked by the allocator, it may not be exactly `addr`, as it may be aligned to a page -/// boundary. -/// -/// On error, `Err(ENOMEM)` will be returned indicating that no memory is available -pub unsafe fn brk(addr: usize) -> Result { - syscall1(SYS_BRK, addr) -} - -/// Changes the process's working directory. -/// -/// This function will attempt to set the process's working directory to `path`, which can be -/// either a relative, scheme relative, or absolute path. -/// -/// On success, `Ok(0)` will be returned. On error, one of the following errors will be returned. -/// -/// # Errors -/// -/// * `EACCES` - permission is denied for one of the components of `path`, or `path` -/// * `EFAULT` - `path` does not point to the process's addressable memory -/// * `EIO` - an I/O error occurred -/// * `ENOENT` - `path` does not exit -/// * `ENOTDIR` - `path` is not a directory -pub fn chdir>(path: T) -> Result { - unsafe { syscall2(SYS_CHDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) } -} - -pub fn chmod>(path: T, mode: usize) -> Result { - unsafe { syscall3(SYS_CHMOD, path.as_ref().as_ptr() as usize, path.as_ref().len(), mode) } -} - -/// Produces a fork of the current process, or a new process thread. -pub unsafe fn clone(flags: usize) -> Result { - syscall1_clobber(SYS_CLONE, flags) -} - -/// Closes a file. -pub fn close(fd: usize) -> Result { - unsafe { syscall1(SYS_CLOSE, fd) } -} - -/// Gets the current system time. -pub fn clock_gettime(clock: usize, tp: &mut TimeSpec) -> Result { - unsafe { syscall2(SYS_CLOCK_GETTIME, clock, tp as *mut TimeSpec as usize) } -} - -/// Copies and transforms a file descriptor. -pub fn dup(fd: usize, buf: &[u8]) -> Result { - unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) } -} - -/// Copies and transforms a file descriptor. -pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result { - unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) } -} - -/// Exits the current process. -pub fn exit(status: usize) -> Result { - unsafe { syscall1(SYS_EXIT, status) } -} - -/// Changes file permissions. -pub fn fchmod(fd: usize, mode: u16) -> Result { - unsafe { syscall2(SYS_FCHMOD, fd, mode as usize) } - -} - -/// Changes file ownership. -pub fn fchown(fd: usize, uid: u32, gid: u32) -> Result { - unsafe { syscall3(SYS_FCHOWN, fd, uid as usize, gid as usize) } - -} - -/// Changes file descriptor flags. -pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result { - unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) } -} - -/// Replaces the current process with a new executable. -pub fn fexec(fd: usize, args: &[[usize; 2]], vars: &[[usize; 2]]) -> Result { - unsafe { syscall5(SYS_FEXEC, fd, args.as_ptr() as usize, args.len(), - vars.as_ptr() as usize, vars.len()) } -} - -/// Maps a file into memory. -pub unsafe fn fmap(fd: usize, offset: usize, size: usize) -> Result { - syscall3(SYS_FMAP, fd, offset, size) -} - -/// Unmaps a memory-mapped file. -pub unsafe fn funmap(addr: usize) -> Result { - syscall1(SYS_FUNMAP, addr) -} - -/// Retrieves the canonical path of a file. -pub fn fpath(fd: usize, buf: &mut [u8]) -> Result { - unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) } -} - -/// Renames a file. -pub fn frename>(fd: usize, path: T) -> Result { - unsafe { syscall3(SYS_FRENAME, fd, path.as_ref().as_ptr() as usize, path.as_ref().len()) } -} - -/// Gets metadata about a file. -pub fn fstat(fd: usize, stat: &mut Stat) -> Result { - unsafe { syscall3(SYS_FSTAT, fd, stat as *mut Stat as usize, mem::size_of::()) } -} - -/// Gets metadata about a filesystem. -pub fn fstatvfs(fd: usize, stat: &mut StatVfs) -> Result { - unsafe { syscall3(SYS_FSTATVFS, fd, stat as *mut StatVfs as usize, mem::size_of::()) } -} - -/// Syncs a file descriptor to its underlying medium. -pub fn fsync(fd: usize) -> Result { - unsafe { syscall1(SYS_FSYNC, fd) } -} - -/// Truncate or extend a file to a specified length -pub fn ftruncate(fd: usize, len: usize) -> Result { - unsafe { syscall2(SYS_FTRUNCATE, fd, len) } -} - -// Change modify and/or access times -pub fn futimens(fd: usize, times: &[TimeSpec]) -> Result { - unsafe { syscall3(SYS_FUTIMENS, fd, times.as_ptr() as usize, - times.len() * mem::size_of::()) } -} - -/// Fast userspace mutex -pub unsafe fn futex(addr: *mut i32, op: usize, val: i32, val2: usize, addr2: *mut i32) - -> Result { - syscall5(SYS_FUTEX, addr as usize, op, (val as isize) as usize, val2, addr2 as usize) -} - -/// Gets the current working directory. -pub fn getcwd(buf: &mut [u8]) -> Result { - unsafe { syscall2(SYS_GETCWD, buf.as_mut_ptr() as usize, buf.len()) } -} - -/// Gets the effective group ID. -pub fn getegid() -> Result { - unsafe { syscall0(SYS_GETEGID) } -} - -/// Gets the effective namespace. -pub fn getens() -> Result { - unsafe { syscall0(SYS_GETENS) } -} - -/// Gets the effective user ID. -pub fn geteuid() -> Result { - unsafe { syscall0(SYS_GETEUID) } -} - -/// Gets the current group ID. -pub fn getgid() -> Result { - unsafe { syscall0(SYS_GETGID) } -} - -/// Gets the current namespace. -pub fn getns() -> Result { - unsafe { syscall0(SYS_GETNS) } -} - -/// Gets the current process ID. -pub fn getpid() -> Result { - unsafe { syscall0(SYS_GETPID) } -} - -/// Gets the process group ID. -pub fn getpgid(pid: usize) -> Result { - unsafe { syscall1(SYS_GETPGID, pid) } -} - -/// Gets the parent process ID. -pub fn getppid() -> Result { - unsafe { syscall0(SYS_GETPPID) } -} - -/// Gets the current user ID. -pub fn getuid() -> Result { - unsafe { syscall0(SYS_GETUID) } -} - -/// Sets the I/O privilege level -pub unsafe fn iopl(level: usize) -> Result { - syscall1(SYS_IOPL, level) -} - -/// Sends a signal `sig` to the process identified by `pid`. -pub fn kill(pid: usize, sig: usize) -> Result { - unsafe { syscall2(SYS_KILL, pid, sig) } -} - -/// Creates a link to a file. -pub unsafe fn link(old: *const u8, new: *const u8) -> Result { - syscall2(SYS_LINK, old as usize, new as usize) -} - -/// Seeks to `offset` bytes in a file descriptor. -pub fn lseek(fd: usize, offset: isize, whence: usize) -> Result { - unsafe { syscall3(SYS_LSEEK, fd, offset as usize, whence) } -} - -/// Makes a new scheme namespace. -pub fn mkns(schemes: &[[usize; 2]]) -> Result { - unsafe { syscall2(SYS_MKNS, schemes.as_ptr() as usize, schemes.len()) } -} - -/// Sleeps for the time specified in `req`. -pub fn nanosleep(req: &TimeSpec, rem: &mut TimeSpec) -> Result { - unsafe { syscall2(SYS_NANOSLEEP, req as *const TimeSpec as usize, - rem as *mut TimeSpec as usize) } -} - -/// Opens a file. -pub fn open>(path: T, flags: usize) -> Result { - unsafe { syscall3(SYS_OPEN, path.as_ref().as_ptr() as usize, path.as_ref().len(), flags) } -} - -/// Allocates pages, linearly in physical memory. -pub unsafe fn physalloc(size: usize) -> Result { - syscall1(SYS_PHYSALLOC, size) -} - -/// Frees physically allocated pages. -pub unsafe fn physfree(physical_address: usize, size: usize) -> Result { - syscall2(SYS_PHYSFREE, physical_address, size) -} - -/// Maps physical memory to virtual memory. -pub unsafe fn physmap(physical_address: usize, size: usize, flags: usize) -> Result { - syscall3(SYS_PHYSMAP, physical_address, size, flags) -} - -/// Unmaps previously mapped physical memory. -pub unsafe fn physunmap(virtual_address: usize) -> Result { - syscall1(SYS_PHYSUNMAP, virtual_address) -} - -/// Creates a pair of file descriptors referencing the read and write ends of a pipe. -pub fn pipe2(fds: &mut [usize; 2], flags: usize) -> Result { - unsafe { syscall2(SYS_PIPE2, fds.as_ptr() as usize, flags) } -} - -/// Read from a file descriptor into a buffer -pub fn read(fd: usize, buf: &mut [u8]) -> Result { - unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) } -} - -/// Removes a directory. -pub fn rmdir>(path: T) -> Result { - unsafe { syscall2(SYS_RMDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) } -} - -/// Sets the process group ID. -pub fn setpgid(pid: usize, pgid: usize) -> Result { - unsafe { syscall2(SYS_SETPGID, pid, pgid) } -} - -/// Sets the current process group IDs. -pub fn setregid(rgid: usize, egid: usize) -> Result { - unsafe { syscall2(SYS_SETREGID, rgid, egid) } -} - -/// Makes a new scheme namespace. -pub fn setrens(rns: usize, ens: usize) -> Result { - unsafe { syscall2(SYS_SETRENS, rns, ens) } -} - -/// Sets the current process user IDs. -pub fn setreuid(ruid: usize, euid: usize) -> Result { - unsafe { syscall2(SYS_SETREUID, ruid, euid) } -} - -/// Sets up a signal handler. -pub fn sigaction(sig: usize, act: Option<&SigAction>, oldact: Option<&mut SigAction>) --> Result { - unsafe { syscall4(SYS_SIGACTION, sig, - act.map(|x| x as *const _).unwrap_or_else(ptr::null) as usize, - oldact.map(|x| x as *mut _).unwrap_or_else(ptr::null_mut) as usize, - restorer as usize) } -} - -/// Returns from signal handler. -pub fn sigreturn() -> Result { - unsafe { syscall0(SYS_SIGRETURN) } -} - -/// Removes a file. -pub fn unlink>(path: T) -> Result { - unsafe { syscall2(SYS_UNLINK, path.as_ref().as_ptr() as usize, path.as_ref().len()) } -} - -/// Converts a virtual address to a physical one. -pub unsafe fn virttophys(virtual_address: usize) -> Result { - syscall1(SYS_VIRTTOPHYS, virtual_address) -} - -/// Checks if a child process has exited or received a signal. -pub fn waitpid(pid: usize, status: &mut usize, options: usize) -> Result { - unsafe { syscall3(SYS_WAITPID, pid, status as *mut usize as usize, options) } -} - -/// Writes a buffer to a file descriptor. -/// -/// The kernel will attempt to write the bytes in `buf` to the file descriptor `fd`, returning -/// either an `Err`, explained below, or `Ok(count)` where `count` is the number of bytes which -/// were written. -/// -/// # Errors -/// -/// * `EAGAIN` - the file descriptor was opened with `O_NONBLOCK` and writing would block -/// * `EBADF` - the file descriptor is not valid or is not open for writing -/// * `EFAULT` - `buf` does not point to the process's addressable memory -/// * `EIO` - an I/O error occurred -/// * `ENOSPC` - the device containing the file descriptor has no room for data -/// * `EPIPE` - the file descriptor refers to a pipe or socket whose reading end is closed -pub fn write(fd: usize, buf: &[u8]) -> Result { - unsafe { syscall3(SYS_WRITE, fd, buf.as_ptr() as usize, buf.len()) } -} - -/// Yields the process's time slice to the kernel. -/// -/// This function will return Ok(0) on success -pub fn sched_yield() -> Result { - unsafe { syscall0(SYS_YIELD) } -} diff --git a/src/libstd/sys/redox/syscall/data.rs b/src/libstd/sys/redox/syscall/data.rs deleted file mode 100644 index 0b458ea89b87f..0000000000000 --- a/src/libstd/sys/redox/syscall/data.rs +++ /dev/null @@ -1,191 +0,0 @@ -use core::ops::{Deref, DerefMut}; -use core::{mem, slice}; - -#[derive(Copy, Clone, Debug, Default)] -pub struct Event { - pub id: usize, - pub flags: usize, - pub data: usize -} - -impl Deref for Event { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts( - self as *const Event as *const u8, - mem::size_of::() - ) as &[u8] - } - } -} - -impl DerefMut for Event { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self as *mut Event as *mut u8, - mem::size_of::() - ) as &mut [u8] - } - } -} - -#[derive(Copy, Clone, Debug, Default)] -#[repr(C)] -pub struct Packet { - pub id: u64, - pub pid: usize, - pub uid: u32, - pub gid: u32, - pub a: usize, - pub b: usize, - pub c: usize, - pub d: usize -} - -impl Deref for Packet { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts( - self as *const Packet as *const u8, - mem::size_of::() - ) as &[u8] - } - } -} - -impl DerefMut for Packet { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self as *mut Packet as *mut u8, - mem::size_of::() - ) as &mut [u8] - } - } -} - -#[derive(Copy, Clone, Debug)] -#[repr(C)] -pub struct SigAction { - pub sa_handler: extern "C" fn(usize), - pub sa_mask: [u64; 2], - pub sa_flags: usize, -} - -impl Default for SigAction { - fn default() -> Self { - Self { - sa_handler: unsafe { mem::transmute(0usize) }, - sa_mask: [0; 2], - sa_flags: 0, - } - } -} - -#[derive(Copy, Clone, Debug, Default)] -#[repr(C)] -pub struct Stat { - pub st_dev: u64, - pub st_ino: u64, - pub st_mode: u16, - pub st_nlink: u32, - pub st_uid: u32, - pub st_gid: u32, - pub st_size: u64, - pub st_blksize: u32, - pub st_blocks: u64, - pub st_mtime: u64, - pub st_mtime_nsec: u32, - pub st_atime: u64, - pub st_atime_nsec: u32, - pub st_ctime: u64, - pub st_ctime_nsec: u32, -} - -impl Deref for Stat { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts( - self as *const Stat as *const u8, - mem::size_of::() - ) as &[u8] - } - } -} - -impl DerefMut for Stat { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self as *mut Stat as *mut u8, - mem::size_of::() - ) as &mut [u8] - } - } -} - -#[derive(Copy, Clone, Debug, Default)] -#[repr(C)] -pub struct StatVfs { - pub f_bsize: u32, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_bavail: u64, -} - -impl Deref for StatVfs { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts( - self as *const StatVfs as *const u8, - mem::size_of::() - ) as &[u8] - } - } -} - -impl DerefMut for StatVfs { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self as *mut StatVfs as *mut u8, - mem::size_of::() - ) as &mut [u8] - } - } -} - -#[derive(Copy, Clone, Debug, Default)] -#[repr(C)] -pub struct TimeSpec { - pub tv_sec: i64, - pub tv_nsec: i32, -} - -impl Deref for TimeSpec { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts( - self as *const TimeSpec as *const u8, - mem::size_of::() - ) as &[u8] - } - } -} - -impl DerefMut for TimeSpec { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut( - self as *mut TimeSpec as *mut u8, - mem::size_of::() - ) as &mut [u8] - } - } -} diff --git a/src/libstd/sys/redox/syscall/error.rs b/src/libstd/sys/redox/syscall/error.rs deleted file mode 100644 index da84ffb042359..0000000000000 --- a/src/libstd/sys/redox/syscall/error.rs +++ /dev/null @@ -1,315 +0,0 @@ -use core::{fmt, result}; - -#[derive(Eq, PartialEq)] -pub struct Error { - pub errno: i32, -} - -pub type Result = result::Result; - -impl Error { - pub fn new(errno: i32) -> Error { - Error { errno } - } - - pub fn mux(result: Result) -> usize { - match result { - Ok(value) => value, - Err(error) => -error.errno as usize, - } - } - - pub fn demux(value: usize) -> Result { - let errno = -(value as i32); - if errno >= 1 && errno < STR_ERROR.len() as i32 { - Err(Error::new(errno)) - } else { - Ok(value) - } - } - - pub fn text(&self) -> &str { - if let Some(description) = STR_ERROR.get(self.errno as usize) { - description - } else { - "Unknown Error" - } - } -} - -impl fmt::Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.text()) - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.text()) - } -} - -pub const EPERM: i32 = 1; /* Operation not permitted */ -pub const ENOENT: i32 = 2; /* No such file or directory */ -pub const ESRCH: i32 = 3; /* No such process */ -pub const EINTR: i32 = 4; /* Interrupted system call */ -pub const EIO: i32 = 5; /* I/O error */ -pub const ENXIO: i32 = 6; /* No such device or address */ -pub const E2BIG: i32 = 7; /* Argument list too long */ -pub const ENOEXEC: i32 = 8; /* Exec format error */ -pub const EBADF: i32 = 9; /* Bad file number */ -pub const ECHILD: i32 = 10; /* No child processes */ -pub const EAGAIN: i32 = 11; /* Try again */ -pub const ENOMEM: i32 = 12; /* Out of memory */ -pub const EACCES: i32 = 13; /* Permission denied */ -pub const EFAULT: i32 = 14; /* Bad address */ -pub const ENOTBLK: i32 = 15; /* Block device required */ -pub const EBUSY: i32 = 16; /* Device or resource busy */ -pub const EEXIST: i32 = 17; /* File exists */ -pub const EXDEV: i32 = 18; /* Cross-device link */ -pub const ENODEV: i32 = 19; /* No such device */ -pub const ENOTDIR: i32 = 20; /* Not a directory */ -pub const EISDIR: i32 = 21; /* Is a directory */ -pub const EINVAL: i32 = 22; /* Invalid argument */ -pub const ENFILE: i32 = 23; /* File table overflow */ -pub const EMFILE: i32 = 24; /* Too many open files */ -pub const ENOTTY: i32 = 25; /* Not a typewriter */ -pub const ETXTBSY: i32 = 26; /* Text file busy */ -pub const EFBIG: i32 = 27; /* File too large */ -pub const ENOSPC: i32 = 28; /* No space left on device */ -pub const ESPIPE: i32 = 29; /* Illegal seek */ -pub const EROFS: i32 = 30; /* Read-only file system */ -pub const EMLINK: i32 = 31; /* Too many links */ -pub const EPIPE: i32 = 32; /* Broken pipe */ -pub const EDOM: i32 = 33; /* Math argument out of domain of func */ -pub const ERANGE: i32 = 34; /* Math result not representable */ -pub const EDEADLK: i32 = 35; /* Resource deadlock would occur */ -pub const ENAMETOOLONG: i32 = 36; /* File name too long */ -pub const ENOLCK: i32 = 37; /* No record locks available */ -pub const ENOSYS: i32 = 38; /* Function not implemented */ -pub const ENOTEMPTY: i32 = 39; /* Directory not empty */ -pub const ELOOP: i32 = 40; /* Too many symbolic links encountered */ -pub const EWOULDBLOCK: i32 = 41; /* Operation would block */ -pub const ENOMSG: i32 = 42; /* No message of desired type */ -pub const EIDRM: i32 = 43; /* Identifier removed */ -pub const ECHRNG: i32 = 44; /* Channel number out of range */ -pub const EL2NSYNC: i32 = 45; /* Level 2 not synchronized */ -pub const EL3HLT: i32 = 46; /* Level 3 halted */ -pub const EL3RST: i32 = 47; /* Level 3 reset */ -pub const ELNRNG: i32 = 48; /* Link number out of range */ -pub const EUNATCH: i32 = 49; /* Protocol driver not attached */ -pub const ENOCSI: i32 = 50; /* No CSI structure available */ -pub const EL2HLT: i32 = 51; /* Level 2 halted */ -pub const EBADE: i32 = 52; /* Invalid exchange */ -pub const EBADR: i32 = 53; /* Invalid request descriptor */ -pub const EXFULL: i32 = 54; /* Exchange full */ -pub const ENOANO: i32 = 55; /* No anode */ -pub const EBADRQC: i32 = 56; /* Invalid request code */ -pub const EBADSLT: i32 = 57; /* Invalid slot */ -pub const EDEADLOCK: i32 = 58; /* Resource deadlock would occur */ -pub const EBFONT: i32 = 59; /* Bad font file format */ -pub const ENOSTR: i32 = 60; /* Device not a stream */ -pub const ENODATA: i32 = 61; /* No data available */ -pub const ETIME: i32 = 62; /* Timer expired */ -pub const ENOSR: i32 = 63; /* Out of streams resources */ -pub const ENONET: i32 = 64; /* Machine is not on the network */ -pub const ENOPKG: i32 = 65; /* Package not installed */ -pub const EREMOTE: i32 = 66; /* Object is remote */ -pub const ENOLINK: i32 = 67; /* Link has been severed */ -pub const EADV: i32 = 68; /* Advertise error */ -pub const ESRMNT: i32 = 69; /* Srmount error */ -pub const ECOMM: i32 = 70; /* Communication error on send */ -pub const EPROTO: i32 = 71; /* Protocol error */ -pub const EMULTIHOP: i32 = 72; /* Multihop attempted */ -pub const EDOTDOT: i32 = 73; /* RFS specific error */ -pub const EBADMSG: i32 = 74; /* Not a data message */ -pub const EOVERFLOW: i32 = 75; /* Value too large for defined data type */ -pub const ENOTUNIQ: i32 = 76; /* Name not unique on network */ -pub const EBADFD: i32 = 77; /* File descriptor in bad state */ -pub const EREMCHG: i32 = 78; /* Remote address changed */ -pub const ELIBACC: i32 = 79; /* Can not access a needed shared library */ -pub const ELIBBAD: i32 = 80; /* Accessing a corrupted shared library */ -pub const ELIBSCN: i32 = 81; /* .lib section in a.out corrupted */ -pub const ELIBMAX: i32 = 82; /* Attempting to link in too many shared libraries */ -pub const ELIBEXEC: i32 = 83; /* Cannot exec a shared library directly */ -pub const EILSEQ: i32 = 84; /* Illegal byte sequence */ -pub const ERESTART: i32 = 85; /* Interrupted system call should be restarted */ -pub const ESTRPIPE: i32 = 86; /* Streams pipe error */ -pub const EUSERS: i32 = 87; /* Too many users */ -pub const ENOTSOCK: i32 = 88; /* Socket operation on non-socket */ -pub const EDESTADDRREQ: i32 = 89; /* Destination address required */ -pub const EMSGSIZE: i32 = 90; /* Message too long */ -pub const EPROTOTYPE: i32 = 91; /* Protocol wrong type for socket */ -pub const ENOPROTOOPT: i32 = 92; /* Protocol not available */ -pub const EPROTONOSUPPORT: i32 = 93; /* Protocol not supported */ -pub const ESOCKTNOSUPPORT: i32 = 94; /* Socket type not supported */ -pub const EOPNOTSUPP: i32 = 95; /* Operation not supported on transport endpoint */ -pub const EPFNOSUPPORT: i32 = 96; /* Protocol family not supported */ -pub const EAFNOSUPPORT: i32 = 97; /* Address family not supported by protocol */ -pub const EADDRINUSE: i32 = 98; /* Address already in use */ -pub const EADDRNOTAVAIL: i32 = 99; /* Cannot assign requested address */ -pub const ENETDOWN: i32 = 100; /* Network is down */ -pub const ENETUNREACH: i32 = 101; /* Network is unreachable */ -pub const ENETRESET: i32 = 102; /* Network dropped connection because of reset */ -pub const ECONNABORTED: i32 = 103; /* Software caused connection abort */ -pub const ECONNRESET: i32 = 104; /* Connection reset by peer */ -pub const ENOBUFS: i32 = 105; /* No buffer space available */ -pub const EISCONN: i32 = 106; /* Transport endpoint is already connected */ -pub const ENOTCONN: i32 = 107; /* Transport endpoint is not connected */ -pub const ESHUTDOWN: i32 = 108; /* Cannot send after transport endpoint shutdown */ -pub const ETOOMANYREFS: i32 = 109; /* Too many references: cannot splice */ -pub const ETIMEDOUT: i32 = 110; /* Connection timed out */ -pub const ECONNREFUSED: i32 = 111; /* Connection refused */ -pub const EHOSTDOWN: i32 = 112; /* Host is down */ -pub const EHOSTUNREACH: i32 = 113; /* No route to host */ -pub const EALREADY: i32 = 114; /* Operation already in progress */ -pub const EINPROGRESS: i32 = 115; /* Operation now in progress */ -pub const ESTALE: i32 = 116; /* Stale NFS file handle */ -pub const EUCLEAN: i32 = 117; /* Structure needs cleaning */ -pub const ENOTNAM: i32 = 118; /* Not a XENIX named type file */ -pub const ENAVAIL: i32 = 119; /* No XENIX semaphores available */ -pub const EISNAM: i32 = 120; /* Is a named type file */ -pub const EREMOTEIO: i32 = 121; /* Remote I/O error */ -pub const EDQUOT: i32 = 122; /* Quota exceeded */ -pub const ENOMEDIUM: i32 = 123; /* No medium found */ -pub const EMEDIUMTYPE: i32 = 124; /* Wrong medium type */ -pub const ECANCELED: i32 = 125; /* Operation Canceled */ -pub const ENOKEY: i32 = 126; /* Required key not available */ -pub const EKEYEXPIRED: i32 = 127; /* Key has expired */ -pub const EKEYREVOKED: i32 = 128; /* Key has been revoked */ -pub const EKEYREJECTED: i32 = 129; /* Key was rejected by service */ -pub const EOWNERDEAD: i32 = 130; /* Owner died */ -pub const ENOTRECOVERABLE: i32 = 131; /* State not recoverable */ - -pub static STR_ERROR: [&'static str; 132] = ["Success", - "Operation not permitted", - "No such file or directory", - "No such process", - "Interrupted system call", - "I/O error", - "No such device or address", - "Argument list too long", - "Exec format error", - "Bad file number", - "No child processes", - "Try again", - "Out of memory", - "Permission denied", - "Bad address", - "Block device required", - "Device or resource busy", - "File exists", - "Cross-device link", - "No such device", - "Not a directory", - "Is a directory", - "Invalid argument", - "File table overflow", - "Too many open files", - "Not a typewriter", - "Text file busy", - "File too large", - "No space left on device", - "Illegal seek", - "Read-only file system", - "Too many links", - "Broken pipe", - "Math argument out of domain of func", - "Math result not representable", - "Resource deadlock would occur", - "File name too long", - "No record locks available", - "Function not implemented", - "Directory not empty", - "Too many symbolic links encountered", - "Operation would block", - "No message of desired type", - "Identifier removed", - "Channel number out of range", - "Level 2 not synchronized", - "Level 3 halted", - "Level 3 reset", - "Link number out of range", - "Protocol driver not attached", - "No CSI structure available", - "Level 2 halted", - "Invalid exchange", - "Invalid request descriptor", - "Exchange full", - "No anode", - "Invalid request code", - "Invalid slot", - "Resource deadlock would occur", - "Bad font file format", - "Device not a stream", - "No data available", - "Timer expired", - "Out of streams resources", - "Machine is not on the network", - "Package not installed", - "Object is remote", - "Link has been severed", - "Advertise error", - "Srmount error", - "Communication error on send", - "Protocol error", - "Multihop attempted", - "RFS specific error", - "Not a data message", - "Value too large for defined data type", - "Name not unique on network", - "File descriptor in bad state", - "Remote address changed", - "Can not access a needed shared library", - "Accessing a corrupted shared library", - ".lib section in a.out corrupted", - "Attempting to link in too many shared libraries", - "Cannot exec a shared library directly", - "Illegal byte sequence", - "Interrupted system call should be restarted", - "Streams pipe error", - "Too many users", - "Socket operation on non-socket", - "Destination address required", - "Message too long", - "Protocol wrong type for socket", - "Protocol not available", - "Protocol not supported", - "Socket type not supported", - "Operation not supported on transport endpoint", - "Protocol family not supported", - "Address family not supported by protocol", - "Address already in use", - "Cannot assign requested address", - "Network is down", - "Network is unreachable", - "Network dropped connection because of reset", - "Software caused connection abort", - "Connection reset by peer", - "No buffer space available", - "Transport endpoint is already connected", - "Transport endpoint is not connected", - "Cannot send after transport endpoint shutdown", - "Too many references: cannot splice", - "Connection timed out", - "Connection refused", - "Host is down", - "No route to host", - "Operation already in progress", - "Operation now in progress", - "Stale NFS file handle", - "Structure needs cleaning", - "Not a XENIX named type file", - "No XENIX semaphores available", - "Is a named type file", - "Remote I/O error", - "Quota exceeded", - "No medium found", - "Wrong medium type", - "Operation Canceled", - "Required key not available", - "Key has expired", - "Key has been revoked", - "Key was rejected by service", - "Owner died", - "State not recoverable"]; diff --git a/src/libstd/sys/redox/syscall/flag.rs b/src/libstd/sys/redox/syscall/flag.rs deleted file mode 100644 index 5820f1ad03a31..0000000000000 --- a/src/libstd/sys/redox/syscall/flag.rs +++ /dev/null @@ -1,148 +0,0 @@ -pub const CLONE_VM: usize = 0x100; -pub const CLONE_FS: usize = 0x200; -pub const CLONE_FILES: usize = 0x400; -pub const CLONE_SIGHAND: usize = 0x800; -pub const CLONE_VFORK: usize = 0x4000; -pub const CLONE_THREAD: usize = 0x10000; - -pub const CLOCK_REALTIME: usize = 1; -pub const CLOCK_MONOTONIC: usize = 4; - -pub const EVENT_NONE: usize = 0; -pub const EVENT_READ: usize = 1; -pub const EVENT_WRITE: usize = 2; - -pub const F_DUPFD: usize = 0; -pub const F_GETFD: usize = 1; -pub const F_SETFD: usize = 2; -pub const F_GETFL: usize = 3; -pub const F_SETFL: usize = 4; - -pub const FUTEX_WAIT: usize = 0; -pub const FUTEX_WAKE: usize = 1; -pub const FUTEX_REQUEUE: usize = 2; - -pub const MAP_WRITE: usize = 1; -pub const MAP_WRITE_COMBINE: usize = 2; - -pub const MODE_TYPE: u16 = 0xF000; -pub const MODE_DIR: u16 = 0x4000; -pub const MODE_FILE: u16 = 0x8000; -pub const MODE_SYMLINK: u16 = 0xA000; -pub const MODE_FIFO: u16 = 0x1000; -pub const MODE_CHR: u16 = 0x2000; - -pub const MODE_PERM: u16 = 0x0FFF; -pub const MODE_SETUID: u16 = 0o4000; -pub const MODE_SETGID: u16 = 0o2000; - -pub const O_RDONLY: usize = 0x0001_0000; -pub const O_WRONLY: usize = 0x0002_0000; -pub const O_RDWR: usize = 0x0003_0000; -pub const O_NONBLOCK: usize = 0x0004_0000; -pub const O_APPEND: usize = 0x0008_0000; -pub const O_SHLOCK: usize = 0x0010_0000; -pub const O_EXLOCK: usize = 0x0020_0000; -pub const O_ASYNC: usize = 0x0040_0000; -pub const O_FSYNC: usize = 0x0080_0000; -pub const O_CLOEXEC: usize = 0x0100_0000; -pub const O_CREAT: usize = 0x0200_0000; -pub const O_TRUNC: usize = 0x0400_0000; -pub const O_EXCL: usize = 0x0800_0000; -pub const O_DIRECTORY: usize = 0x1000_0000; -pub const O_STAT: usize = 0x2000_0000; -pub const O_SYMLINK: usize = 0x4000_0000; -pub const O_NOFOLLOW: usize = 0x8000_0000; -pub const O_ACCMODE: usize = O_RDONLY | O_WRONLY | O_RDWR; - -pub const SEEK_SET: usize = 0; -pub const SEEK_CUR: usize = 1; -pub const SEEK_END: usize = 2; - -pub const SIGHUP: usize = 1; -pub const SIGINT: usize = 2; -pub const SIGQUIT: usize = 3; -pub const SIGILL: usize = 4; -pub const SIGTRAP: usize = 5; -pub const SIGABRT: usize = 6; -pub const SIGBUS: usize = 7; -pub const SIGFPE: usize = 8; -pub const SIGKILL: usize = 9; -pub const SIGUSR1: usize = 10; -pub const SIGSEGV: usize = 11; -pub const SIGUSR2: usize = 12; -pub const SIGPIPE: usize = 13; -pub const SIGALRM: usize = 14; -pub const SIGTERM: usize = 15; -pub const SIGSTKFLT: usize= 16; -pub const SIGCHLD: usize = 17; -pub const SIGCONT: usize = 18; -pub const SIGSTOP: usize = 19; -pub const SIGTSTP: usize = 20; -pub const SIGTTIN: usize = 21; -pub const SIGTTOU: usize = 22; -pub const SIGURG: usize = 23; -pub const SIGXCPU: usize = 24; -pub const SIGXFSZ: usize = 25; -pub const SIGVTALRM: usize= 26; -pub const SIGPROF: usize = 27; -pub const SIGWINCH: usize = 28; -pub const SIGIO: usize = 29; -pub const SIGPWR: usize = 30; -pub const SIGSYS: usize = 31; - -pub const SIG_DFL: usize = 0; -pub const SIG_IGN: usize = 1; - -pub const SA_NOCLDSTOP: usize = 0x00000001; -pub const SA_NOCLDWAIT: usize = 0x00000002; -pub const SA_SIGINFO: usize = 0x00000004; -pub const SA_RESTORER: usize = 0x04000000; -pub const SA_ONSTACK: usize = 0x08000000; -pub const SA_RESTART: usize = 0x10000000; -pub const SA_NODEFER: usize = 0x40000000; -pub const SA_RESETHAND: usize = 0x80000000; - -pub const WNOHANG: usize = 0x01; -pub const WUNTRACED: usize = 0x02; -pub const WCONTINUED: usize = 0x08; - -/// Returns `true` if status indicates the child is stopped. -pub fn wifstopped(status: usize) -> bool { - (status & 0xff) == 0x7f -} - -/// If wifstopped(status), returns the signal that stopped the child. -pub fn wstopsig(status: usize) -> usize { - (status >> 8) & 0xff -} - -/// Returns `true` if status indicates the child continued after a stop. -pub fn wifcontinued(status: usize) -> bool { - status == 0xffff -} - -/// Returns `true` if status indicates termination by a signal. -pub fn wifsignaled(status: usize) -> bool { - ((status & 0x7f) + 1) as i8 >= 2 -} - -/// If wifsignaled(status), returns the terminating signal. -pub fn wtermsig(status: usize) -> usize { - status & 0x7f -} - -/// Returns `true` if status indicates normal termination. -pub fn wifexited(status: usize) -> bool { - wtermsig(status) == 0 -} - -/// If wifexited(status), returns the exit status. -pub fn wexitstatus(status: usize) -> usize { - (status >> 8) & 0xff -} - -/// Returns `true` if status indicates a core dump was created. -pub fn wcoredump(status: usize) -> bool { - (status & 0x80) != 0 -} diff --git a/src/libstd/sys/redox/syscall/mod.rs b/src/libstd/sys/redox/syscall/mod.rs deleted file mode 100644 index b16f5dbd918e8..0000000000000 --- a/src/libstd/sys/redox/syscall/mod.rs +++ /dev/null @@ -1,33 +0,0 @@ -pub use self::arch::*; -pub use self::call::*; -pub use self::data::*; -pub use self::error::*; -pub use self::flag::*; -pub use self::number::*; - -#[cfg(target_arch = "arm")] -#[path="arch/arm.rs"] -mod arch; - -#[cfg(target_arch = "x86")] -#[path="arch/x86.rs"] -mod arch; - -#[cfg(target_arch = "x86_64")] -#[path="arch/x86_64.rs"] -mod arch; - -/// Function definitions -pub mod call; - -/// Complex structures that are used for some system calls -pub mod data; - -/// All errors that can be generated by a system call -pub mod error; - -/// Flags used as an argument to many system calls -pub mod flag; - -/// Call numbers used by each system call -pub mod number; diff --git a/src/libstd/sys/redox/syscall/number.rs b/src/libstd/sys/redox/syscall/number.rs deleted file mode 100644 index f8884aa2ed805..0000000000000 --- a/src/libstd/sys/redox/syscall/number.rs +++ /dev/null @@ -1,73 +0,0 @@ -pub const SYS_CLASS: usize = 0xF000_0000; -pub const SYS_CLASS_PATH: usize=0x1000_0000; -pub const SYS_CLASS_FILE: usize=0x2000_0000; - -pub const SYS_ARG: usize = 0x0F00_0000; -pub const SYS_ARG_SLICE: usize =0x0100_0000; -pub const SYS_ARG_MSLICE: usize=0x0200_0000; -pub const SYS_ARG_PATH: usize = 0x0300_0000; - -pub const SYS_RET: usize = 0x00F0_0000; -pub const SYS_RET_FILE: usize = 0x0010_0000; - -pub const SYS_LINK: usize = SYS_CLASS_PATH | SYS_ARG_PATH | 9; -pub const SYS_OPEN: usize = SYS_CLASS_PATH | SYS_RET_FILE | 5; -pub const SYS_CHMOD: usize = SYS_CLASS_PATH | 15; -pub const SYS_RMDIR: usize = SYS_CLASS_PATH | 84; -pub const SYS_UNLINK: usize = SYS_CLASS_PATH | 10; - -pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6; -pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41; -pub const SYS_DUP2: usize = SYS_CLASS_FILE | SYS_RET_FILE | 63; -pub const SYS_READ: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 3; -pub const SYS_WRITE: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 4; -pub const SYS_LSEEK: usize = SYS_CLASS_FILE | 19; -pub const SYS_FCHMOD: usize = SYS_CLASS_FILE | 94; -pub const SYS_FCHOWN: usize = SYS_CLASS_FILE | 207; -pub const SYS_FCNTL: usize = SYS_CLASS_FILE | 55; -pub const SYS_FEVENT: usize = SYS_CLASS_FILE | 927; -pub const SYS_FEXEC: usize = SYS_CLASS_FILE | 11; -pub const SYS_FMAP: usize = SYS_CLASS_FILE | 90; -pub const SYS_FUNMAP: usize = SYS_CLASS_FILE | 91; -pub const SYS_FPATH: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 928; -pub const SYS_FRENAME: usize = SYS_CLASS_FILE | SYS_ARG_PATH | 38; -pub const SYS_FSTAT: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 28; -pub const SYS_FSTATVFS: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 100; -pub const SYS_FSYNC: usize = SYS_CLASS_FILE | 118; -pub const SYS_FTRUNCATE: usize =SYS_CLASS_FILE | 93; -pub const SYS_FUTIMENS: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 320; - -pub const SYS_BRK: usize = 45; -pub const SYS_CHDIR: usize = 12; -pub const SYS_CLOCK_GETTIME: usize = 265; -pub const SYS_CLONE: usize = 120; -pub const SYS_EXIT: usize = 1; -pub const SYS_FUTEX: usize = 240; -pub const SYS_GETCWD: usize = 183; -pub const SYS_GETEGID: usize = 202; -pub const SYS_GETENS: usize = 951; -pub const SYS_GETEUID: usize = 201; -pub const SYS_GETGID: usize = 200; -pub const SYS_GETNS: usize = 950; -pub const SYS_GETPID: usize = 20; -pub const SYS_GETPGID: usize = 132; -pub const SYS_GETPPID: usize = 64; -pub const SYS_GETUID: usize = 199; -pub const SYS_IOPL: usize = 110; -pub const SYS_KILL: usize = 37; -pub const SYS_MKNS: usize = 984; -pub const SYS_NANOSLEEP: usize =162; -pub const SYS_PHYSALLOC: usize =945; -pub const SYS_PHYSFREE: usize = 946; -pub const SYS_PHYSMAP: usize = 947; -pub const SYS_PHYSUNMAP: usize =948; -pub const SYS_VIRTTOPHYS: usize=949; -pub const SYS_PIPE2: usize = 331; -pub const SYS_SETPGID: usize = 57; -pub const SYS_SETREGID: usize = 204; -pub const SYS_SETRENS: usize = 952; -pub const SYS_SETREUID: usize = 203; -pub const SYS_SIGACTION: usize =67; -pub const SYS_SIGRETURN: usize =119; -pub const SYS_WAITPID: usize = 7; -pub const SYS_YIELD: usize = 158; diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs deleted file mode 100644 index 9d40a7e8bb8b3..0000000000000 --- a/src/libstd/sys/redox/thread.rs +++ /dev/null @@ -1,84 +0,0 @@ -use crate::ffi::CStr; -use crate::io; -use crate::mem; -use crate::sys_common::thread::start_thread; -use crate::sys::{cvt, syscall}; -use crate::time::Duration; - -pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; - -pub struct Thread { - id: usize, -} - -// 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 {} - -impl Thread { - // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(_stack: usize, p: Box) -> io::Result { - let p = box p; - - let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?; - if id == 0 { - start_thread(&*p as *const _ as *mut _); - let _ = syscall::exit(0); - panic!("thread failed to exit"); - } else { - mem::forget(p); - Ok(Thread { id }) - } - } - - pub fn yield_now() { - let ret = syscall::sched_yield().expect("failed to sched_yield"); - debug_assert_eq!(ret, 0); - } - - pub fn set_name(_name: &CStr) { - - } - - pub fn sleep(dur: Duration) { - let mut secs = dur.as_secs(); - let mut nsecs = dur.subsec_nanos() as i32; - - // If we're awoken with a signal then the return value will be -1 and - // nanosleep will fill in `ts` with the remaining time. - while secs > 0 || nsecs > 0 { - let req = syscall::TimeSpec { - tv_sec: secs as i64, - tv_nsec: nsecs, - }; - secs -= req.tv_sec as u64; - let mut rem = syscall::TimeSpec::default(); - if syscall::nanosleep(&req, &mut rem).is_err() { - secs += rem.tv_sec as u64; - nsecs = rem.tv_nsec; - } else { - nsecs = 0; - } - } - } - - pub fn join(self) { - let mut status = 0; - syscall::waitpid(self.id, &mut status, 0).unwrap(); - } - - pub fn id(&self) -> usize { self.id } - - pub fn into_id(self) -> usize { - let id = self.id; - mem::forget(self); - id - } -} - -pub mod guard { - pub type Guard = !; - pub unsafe fn current() -> Option { None } - pub unsafe fn init() -> Option { None } -} diff --git a/src/libstd/sys/redox/thread_local.rs b/src/libstd/sys/redox/thread_local.rs deleted file mode 100644 index 4bc8c4d5883da..0000000000000 --- a/src/libstd/sys/redox/thread_local.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![allow(dead_code)] // not used on all platforms - -use crate::collections::BTreeMap; -use crate::ptr; -use crate::sync::atomic::{AtomicUsize, Ordering}; - -pub type Key = usize; - -type Dtor = unsafe extern fn(*mut u8); - -static NEXT_KEY: AtomicUsize = AtomicUsize::new(0); - -static mut KEYS: *mut BTreeMap> = ptr::null_mut(); - -#[thread_local] -static mut LOCALS: *mut BTreeMap = ptr::null_mut(); - -unsafe fn keys() -> &'static mut BTreeMap> { - if KEYS == ptr::null_mut() { - KEYS = Box::into_raw(Box::new(BTreeMap::new())); - } - &mut *KEYS -} - -unsafe fn locals() -> &'static mut BTreeMap { - if LOCALS == ptr::null_mut() { - LOCALS = Box::into_raw(Box::new(BTreeMap::new())); - } - &mut *LOCALS -} - -#[inline] -pub unsafe fn create(dtor: Option) -> Key { - let key = NEXT_KEY.fetch_add(1, Ordering::SeqCst); - keys().insert(key, dtor); - key -} - -#[inline] -pub unsafe fn get(key: Key) -> *mut u8 { - if let Some(&entry) = locals().get(&key) { - entry - } else { - ptr::null_mut() - } -} - -#[inline] -pub unsafe fn set(key: Key, value: *mut u8) { - locals().insert(key, value); -} - -#[inline] -pub unsafe fn destroy(key: Key) { - keys().remove(&key); -} - -#[inline] -pub fn requires_synchronized_create() -> bool { - false -} diff --git a/src/libstd/sys/redox/time.rs b/src/libstd/sys/redox/time.rs deleted file mode 100644 index 081437459cc40..0000000000000 --- a/src/libstd/sys/redox/time.rs +++ /dev/null @@ -1,207 +0,0 @@ -use crate::cmp::Ordering; -use crate::fmt; -use crate::sys::{cvt, syscall}; -use crate::time::Duration; -use crate::convert::TryInto; - -use core::hash::{Hash, Hasher}; - -const NSEC_PER_SEC: u64 = 1_000_000_000; - -#[derive(Copy, Clone)] -struct Timespec { - t: syscall::TimeSpec, -} - -impl Timespec { - fn sub_timespec(&self, other: &Timespec) -> Result { - 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 checked_add_duration(&self, other: &Duration) -> Option { - let mut secs = other - .as_secs() - .try_into() // <- target type would be `i64` - .ok() - .and_then(|secs| self.t.tv_sec.checked_add(secs))?; - - // 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)?; - } - Some(Timespec { - t: syscall::TimeSpec { - tv_sec: secs, - tv_nsec: nsec as i32, - }, - }) - } - - fn checked_sub_duration(&self, other: &Duration) -> Option { - let mut secs = other - .as_secs() - .try_into() // <- target type would be `i64` - .ok() - .and_then(|secs| self.t.tv_sec.checked_sub(secs))?; - - // 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)?; - } - Some(Timespec { - t: syscall::TimeSpec { - tv_sec: secs, - tv_nsec: nsec as i32, - }, - }) - } -} - -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 { - 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(&self, state: &mut H) { - self.t.tv_sec.hash(state); - self.t.tv_nsec.hash(state); - } -} - -#[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: syscall::TimeSpec { - tv_sec: 0, - tv_nsec: 0, - }, - }, -}; - -impl Instant { - pub fn now() -> Instant { - Instant { t: now(syscall::CLOCK_MONOTONIC) } - } - - pub const fn zero() -> Instant { - Instant { t: Timespec { t: syscall::TimeSpec { tv_sec: 0, tv_nsec: 0 } } } - } - - pub fn actually_monotonic() -> bool { - false - } - - pub fn checked_sub_instant(&self, other: &Instant) -> Option { - self.t.sub_timespec(&other.t).ok() - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - Some(Instant { t: self.t.checked_add_duration(other)? }) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - Some(Instant { t: self.t.checked_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(syscall::CLOCK_REALTIME) } - } - - pub fn sub_time(&self, other: &SystemTime) - -> Result { - self.t.sub_timespec(&other.t) - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - Some(SystemTime { t: self.t.checked_add_duration(other)? }) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - Some(SystemTime { t: self.t.checked_sub_duration(other)? }) - } -} - -impl From for SystemTime { - fn from(t: syscall::TimeSpec) -> SystemTime { - SystemTime { t: Timespec { 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() - } -} - -pub type clock_t = usize; - -fn now(clock: clock_t) -> Timespec { - let mut t = Timespec { - t: syscall::TimeSpec { - tv_sec: 0, - tv_nsec: 0, - } - }; - cvt(syscall::clock_gettime(clock, &mut t.t)).unwrap(); - t -} diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 3b4de56f2c9b7..288e9b5c12620 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -56,7 +56,8 @@ impl DoubleEndedIterator for Args { target_os = "haiku", target_os = "l4re", target_os = "fuchsia", - target_os = "hermit"))] + target_os = "hermit", + target_os = "redox"))] mod imp { use crate::os::unix::prelude::*; use crate::ptr; diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index 4201de794b708..0a93fbf8ea779 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -31,14 +31,16 @@ impl Condvar { target_os = "ios", target_os = "l4re", target_os = "android", - target_os = "hermit"))] + target_os = "hermit", + target_os = "redox"))] pub unsafe fn init(&mut self) {} #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "l4re", target_os = "android", - target_os = "hermit")))] + target_os = "hermit", + target_os = "redox")))] pub unsafe fn init(&mut self) { use crate::mem::MaybeUninit; let mut attr = MaybeUninit::::uninit(); diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs index 891013406a169..d724eeb8b3fde 100644 --- a/src/libstd/sys/unix/env.rs +++ b/src/libstd/sys/unix/env.rs @@ -162,3 +162,14 @@ pub mod os { pub const EXE_SUFFIX: &str = ""; pub const EXE_EXTENSION: &str = ""; } + +#[cfg(target_os = "redox")] +pub mod os { + pub const FAMILY: &str = "unix"; + pub const OS: &str = "redox"; + pub const DLL_PREFIX: &str = "lib"; + pub const DLL_SUFFIX: &str = ".so"; + pub const DLL_EXTENSION: &str = "so"; + pub const EXE_SUFFIX: &str = ""; + pub const EXE_EXTENSION: &str = ""; +} diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/fast_thread_local.rs index c34c2e6e786ec..952ba40ee87a9 100644 --- a/src/libstd/sys/unix/fast_thread_local.rs +++ b/src/libstd/sys/unix/fast_thread_local.rs @@ -10,7 +10,7 @@ // 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"))] +#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit", target_os = "redox"))] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) { use crate::mem; use crate::sys_common::thread_local::register_dtor_fallback; diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 0cecdd7ffa0b7..ac43526b50f2c 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -176,7 +176,8 @@ impl FileDesc { target_os = "fuchsia", target_os = "l4re", target_os = "linux", - target_os = "haiku")))] + target_os = "haiku", + target_os = "redox")))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { cvt(libc::ioctl(self.fd, libc::FIOCLEX))?; @@ -189,7 +190,8 @@ impl FileDesc { target_os = "fuchsia", target_os = "l4re", target_os = "linux", - target_os = "haiku"))] + target_os = "haiku", + target_os = "redox"))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?; diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index cc1f0790d4334..822feacea6274 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -33,7 +33,8 @@ use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, off_t as off64_t, target_os = "emscripten", target_os = "solaris", target_os = "l4re", - target_os = "fuchsia")))] + target_os = "fuchsia", + target_os = "redox")))] use libc::{readdir_r as readdir64_r}; pub use crate::sys_common::fs::remove_dir_all; @@ -69,7 +70,7 @@ pub struct DirEntry { // 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"))] + #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))] name: Box<[u8]> } @@ -216,7 +217,7 @@ impl fmt::Debug for ReadDir { impl Iterator for ReadDir { type Item = io::Result; - #[cfg(any(target_os = "solaris", target_os = "fuchsia"))] + #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))] fn next(&mut self) -> Option> { use crate::slice; @@ -253,7 +254,7 @@ impl Iterator for ReadDir { } } - #[cfg(not(any(target_os = "solaris", target_os = "fuchsia")))] + #[cfg(not(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox")))] fn next(&mut self) -> Option> { if self.end_of_stream { return None; @@ -346,7 +347,8 @@ impl DirEntry { target_os = "haiku", target_os = "l4re", target_os = "fuchsia", - target_os = "hermit"))] + target_os = "hermit", + target_os = "redox"))] pub fn ino(&self) -> u64 { self.entry.d_ino as u64 } @@ -384,7 +386,8 @@ impl DirEntry { } } #[cfg(any(target_os = "solaris", - target_os = "fuchsia"))] + target_os = "fuchsia", + target_os = "redox"))] fn name_bytes(&self) -> &[u8] { &*self.name } diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 821623db2721e..b1f7aac8b4b40 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -17,6 +17,7 @@ use crate::io::ErrorKind; #[cfg(all(not(rustdoc), target_os = "fuchsia"))] pub use crate::os::fuchsia as platform; #[cfg(all(not(rustdoc), target_os = "l4re"))] pub use crate::os::linux as platform; #[cfg(all(not(rustdoc), target_os = "hermit"))] pub use crate::os::hermit as platform; +#[cfg(all(not(rustdoc), target_os = "redox"))] pub use crate::os::redox as platform; pub use self::rand::hashmap_random_keys; pub use libc::strlen; diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index dad19eabf7db7..bc8562a0a7be2 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -25,6 +25,13 @@ use libc::{c_int, c_char, c_void}; const TMPBUF_SZ: usize = 128; +cfg_if! { + if #[cfg(target_os = "redox")] { + const PATH_SEPARATOR: u8 = b';'; + } else { + const PATH_SEPARATOR: u8 = b':'; + } +} extern { #[cfg(not(target_os = "dragonfly"))] @@ -37,6 +44,7 @@ extern { target_os = "openbsd", target_os = "android", target_os = "hermit", + target_os = "redox", target_env = "newlib"), link_name = "__errno")] #[cfg_attr(target_os = "solaris", link_name = "___errno")] @@ -155,10 +163,10 @@ pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> { fn bytes_to_path(b: &[u8]) -> PathBuf { PathBuf::from(::from_bytes(b)) } - fn is_colon(b: &u8) -> bool { *b == b':' } + fn is_separator(b: &u8) -> bool { *b == PATH_SEPARATOR } let unparsed = unparsed.as_bytes(); SplitPaths { - iter: unparsed.split(is_colon as fn(&u8) -> bool) + iter: unparsed.split(is_separator as fn(&u8) -> bool) .map(bytes_to_path as fn(&[u8]) -> PathBuf) } } @@ -176,12 +184,11 @@ pub fn join_paths(paths: I) -> Result where I: Iterator, T: AsRef { 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) { + if i > 0 { joined.push(PATH_SEPARATOR) } + if path.contains(&PATH_SEPARATOR) { return Err(JoinPathsError) } joined.extend_from_slice(path); @@ -191,7 +198,7 @@ pub fn join_paths(paths: I) -> Result impl fmt::Display for JoinPathsError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "path segment contains separator `:`".fmt(f) + write!(f, "path segment contains separator `{}`", PATH_SEPARATOR) } } @@ -382,6 +389,11 @@ pub fn current_exe() -> io::Result { } } +#[cfg(target_os = "redox")] +pub fn current_exe() -> io::Result { + crate::fs::read_to_string("sys:exe").map(PathBuf::from) +} + #[cfg(any(target_os = "fuchsia", target_os = "l4re", target_os = "hermit"))] pub fn current_exe() -> io::Result { use crate::io::ErrorKind; @@ -511,11 +523,13 @@ pub fn home_dir() -> Option { #[cfg(any(target_os = "android", target_os = "ios", - target_os = "emscripten"))] + target_os = "emscripten", + target_os = "redox"))] unsafe fn fallback() -> Option { None } #[cfg(not(any(target_os = "android", target_os = "ios", - target_os = "emscripten")))] + target_os = "emscripten", + target_os = "redox")))] unsafe fn fallback() -> Option { let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) { n if n < 0 => 512 as usize, diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index d36e94df63f8c..029f4216b7e57 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -26,7 +26,8 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { target_os = "freebsd", target_os = "linux", target_os = "netbsd", - target_os = "openbsd")) && + target_os = "openbsd", + target_os = "redox")) && !INVALID.load(Ordering::SeqCst) { diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 3ff4f194cd1a9..9f81c67b47745 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -12,6 +12,14 @@ use crate::collections::BTreeMap; use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE}; +cfg_if! { + if #[cfg(target_os = "redox")] { + const DEV_NULL: &'static str = "null:\0"; + } else { + const DEV_NULL: &'static str = "/dev/null\0"; + } +} + //////////////////////////////////////////////////////////////////////////////// // Command //////////////////////////////////////////////////////////////////////////////// @@ -298,7 +306,7 @@ impl Stdio { opts.read(readable); opts.write(!readable); let path = unsafe { - CStr::from_ptr("/dev/null\0".as_ptr() as *const _) + CStr::from_ptr(DEV_NULL.as_ptr() as *const _) }; let fd = File::open_c(&path, &opts)?; Ok((ChildStdio::Owned(fd.into_fd()), None)) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index fc1e33137c8a9..327d82e60cff3 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -183,14 +183,17 @@ impl Command { 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()); + //FIXME: Redox kernel does not support setgroups yet + if cfg!(not(target_os = "redox")) { + // 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()); + } cvt(libc::setuid(u as uid_t))?; } diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs index 71c62461ee9cb..c5be17633025f 100644 --- a/src/libstd/sys/unix/rand.rs +++ b/src/libstd/sys/unix/rand.rs @@ -15,7 +15,8 @@ pub fn hashmap_random_keys() -> (u64, u64) { not(target_os = "ios"), not(target_os = "openbsd"), not(target_os = "freebsd"), - not(target_os = "fuchsia")))] + not(target_os = "fuchsia"), + not(target_os = "redox")))] mod imp { use crate::fs::File; use crate::io::Read; @@ -174,3 +175,15 @@ mod imp { unsafe { zx_cprng_draw(v.as_mut_ptr(), v.len()) } } } + +#[cfg(target_os = "redox")] +mod imp { + use crate::fs::File; + use crate::io::Read; + + pub fn fill_bytes(v: &mut [u8]) { + // Open rand:, read from it, and close it again. + let mut file = File::open("rand:").expect("failed to open rand:"); + file.read_exact(v).expect("failed to read rand:") + } +} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 122fc11ec2725..988881e35966f 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -140,7 +140,8 @@ impl Thread { target_os = "haiku", target_os = "l4re", target_os = "emscripten", - target_os = "hermit"))] + target_os = "hermit", + target_os = "redox"))] pub fn set_name(_name: &CStr) { // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name. } diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs index 13a59f66c5c2f..9190a3b0d5fc7 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -68,7 +68,6 @@ pub mod fs; cfg_if::cfg_if! { if #[cfg(any(target_os = "cloudabi", target_os = "l4re", - target_os = "redox", all(target_arch = "wasm32", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))] { pub use crate::sys::net; diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index 3545a691a1515..da31a49ddf21f 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -40,7 +40,7 @@ fn main() { } else if target.contains("haiku") { println!("cargo:rustc-link-lib=gcc_s"); } else if target.contains("redox") { - println!("cargo:rustc-link-lib=gcc"); + // redox is handled in lib.rs } else if target.contains("cloudabi") { println!("cargo:rustc-link-lib=unwind"); } diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs index b9ce71b6b847e..8d916447128fc 100644 --- a/src/libunwind/lib.rs +++ b/src/libunwind/lib.rs @@ -24,3 +24,8 @@ cfg_if::cfg_if! { #[link(name = "unwind", kind = "static", cfg(target_feature = "crt-static"))] #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] extern {} + +#[cfg(target_os = "redox")] +#[link(name = "gcc_eh", kind = "static-nobundle", cfg(target_feature = "crt-static"))] +#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] +extern {} diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 2d1a52c920bae..9ffa9391c820b 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -46,6 +46,7 @@ static TARGETS: &[&str] = &[ "aarch64-unknown-cloudabi", "aarch64-unknown-linux-gnu", "aarch64-unknown-linux-musl", + "aarch64-unknown-redox", "arm-linux-androideabi", "arm-unknown-linux-gnueabi", "arm-unknown-linux-gnueabihf", From ebb648d4fbda07477ab9454dfda98187cd26aa34 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 6 Aug 2019 19:32:39 -0600 Subject: [PATCH 2/2] Fix cfg_if usage --- src/libstd/sys/unix/os.rs | 2 +- src/libstd/sys/unix/process/process_common.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index bc8562a0a7be2..169bb57ef78df 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -25,7 +25,7 @@ use libc::{c_int, c_char, c_void}; const TMPBUF_SZ: usize = 128; -cfg_if! { +cfg_if::cfg_if! { if #[cfg(target_os = "redox")] { const PATH_SEPARATOR: u8 = b';'; } else { diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 9f81c67b47745..6bb20bbe08794 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -12,7 +12,7 @@ use crate::collections::BTreeMap; use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE}; -cfg_if! { +cfg_if::cfg_if! { if #[cfg(target_os = "redox")] { const DEV_NULL: &'static str = "null:\0"; } else {