diff options
| author | bors <bors@rust-lang.org> | 2020-07-27 17:39:01 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-27 17:39:01 +0000 |
| commit | 54e000891ffccd4cbfb92146b92736c83085df63 (patch) | |
| tree | 1200bb13eb9ae22def4c43bc657bc56da8faedc6 /src/libstd/sys/hermit | |
| parent | 4a90e36c85336d1d4b209556c1a9733210bbff19 (diff) | |
| parent | 6d9705220fec4553d693a7c19d99496e14c89edf (diff) | |
| download | rust-tmp-nightly.tar.gz | |
Auto merge of #73265 - mark-i-m:mv-std, r=<try>tmp-nightly
mv std libs to library/
This is the first step in refactoring the directory layout of this repository, with further followup steps planned (but not done yet).
Background: currently, all crates are under src/, without nested src directories and with the unconventional `lib*` prefixes (e.g., `src/libcore/lib.rs`). This directory structures is not idiomatic and makes the `src/` directory rather overwhelming. To improve contributor experience and make things a bit more approachable, we are reorganizing the repo a bit.
In this PR, we move the standard libs (basically anything that is "runtime", as opposed to part of the compiler, build system, or one of the tools, etc). The new layout moves these libraries to a new `library/` directory in the root of the repo. Additionally, we remove the `lib*` prefixes and add nested `src/` directories. The other crates/tools in this repo are not touched. So in summary:
```
library/<crate>/src/*.rs
src/<all the rest> // unchanged
```
where `<crate>` is:
- core
- alloc
- std
- test
- proc_macro
- panic_abort
- panic_unwind
- profiler_builtins
- term
- unwind
- rtstartup
- backtrace
- rustc-std-workspace-*
There was a lot of discussion about this and a few rounds of compiler team approvals, FCPs, MCPs, and nominations. The original MCP is https://github.com/rust-lang/compiler-team/issues/298. The final approval of the compiler team was given here: https://github.com/rust-lang/rust/pull/73265#issuecomment-659498446.
The name `library` was chosen to complement a later move of the compiler crates to a `compiler/` directory. There was a lot of discussion around adding the nested `src/` directories. Note that this does increase the nesting depth (plausibly important for manual traversal of the tree, e.g., through GitHub's UI or `cd`), but this is deemed to be better as it fits the standard layout of Rust crates throughout most of the ecosystem, though there is some debate about how much this should apply to multi-crate projects. Overall, there seem to be more people in favor of nested `src/` than against.
After this PR, there are no dependencies out of the `library/` directory except on the `build_helper` (or crates.io crates).
Diffstat (limited to 'src/libstd/sys/hermit')
25 files changed, 0 insertions, 2499 deletions
diff --git a/src/libstd/sys/hermit/alloc.rs b/src/libstd/sys/hermit/alloc.rs deleted file mode 100644 index d153914e77e..00000000000 --- a/src/libstd/sys/hermit/alloc.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::alloc::{GlobalAlloc, Layout, System}; -use crate::ptr; -use crate::sys::hermit::abi; - -#[stable(feature = "alloc_system_type", since = "1.28.0")] -unsafe impl GlobalAlloc for System { - #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - abi::malloc(layout.size(), layout.align()) - } - - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - let addr = abi::malloc(layout.size(), layout.align()); - - if !addr.is_null() { - ptr::write_bytes(addr, 0x00, layout.size()); - } - - addr - } - - #[inline] - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - abi::free(ptr, layout.size(), layout.align()) - } - - #[inline] - unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - abi::realloc(ptr, layout.size(), layout.align(), new_size) - } -} diff --git a/src/libstd/sys/hermit/args.rs b/src/libstd/sys/hermit/args.rs deleted file mode 100644 index 72c1b8511ca..00000000000 --- a/src/libstd/sys/hermit/args.rs +++ /dev/null @@ -1,93 +0,0 @@ -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<OsString>, - _dont_send_or_sync_me: PhantomData<*mut ()>, -} - -impl Args { - pub fn inner_debug(&self) -> &[OsString] { - self.iter.as_slice() - } -} - -impl Iterator for Args { - type Item = OsString; - fn next(&mut self) -> Option<OsString> { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option<usize>) { - self.iter.size_hint() - } -} - -impl ExactSizeIterator for Args { - fn len(&self) -> usize { - self.iter.len() - } -} - -impl DoubleEndedIterator for Args { - fn next_back(&mut self) -> Option<OsString> { - self.iter.next_back() - } -} - -mod imp { - use super::Args; - use crate::ffi::{CStr, OsString}; - use crate::marker::PhantomData; - use crate::ptr; - use crate::sys_common::os_str_bytes::*; - - use crate::sys_common::mutex::Mutex; - - static mut ARGC: isize = 0; - static mut ARGV: *const *const u8 = ptr::null(); - static LOCK: Mutex = Mutex::new(); - - pub unsafe fn init(argc: isize, argv: *const *const u8) { - let _guard = LOCK.lock(); - ARGC = argc; - ARGV = argv; - } - - pub unsafe fn cleanup() { - let _guard = LOCK.lock(); - ARGC = 0; - ARGV = ptr::null(); - } - - pub fn args() -> Args { - Args { iter: clone().into_iter(), _dont_send_or_sync_me: PhantomData } - } - - fn clone() -> Vec<OsString> { - unsafe { - let _guard = LOCK.lock(); - (0..ARGC) - .map(|i| { - let cstr = CStr::from_ptr(*ARGV.offset(i) as *const i8); - OsStringExt::from_vec(cstr.to_bytes().to_vec()) - }) - .collect() - } - } -} diff --git a/src/libstd/sys/hermit/cmath.rs b/src/libstd/sys/hermit/cmath.rs deleted file mode 100644 index 304cf906b2a..00000000000 --- a/src/libstd/sys/hermit/cmath.rs +++ /dev/null @@ -1,29 +0,0 @@ -// These symbols are all defined in `compiler-builtins` -extern "C" { - pub fn acos(n: f64) -> f64; - pub fn acosf(n: f32) -> f32; - pub fn asin(n: f64) -> f64; - pub fn asinf(n: f32) -> f32; - pub fn atan(n: f64) -> f64; - pub fn atan2(a: f64, b: f64) -> f64; - pub fn atan2f(a: f32, b: f32) -> f32; - pub fn atanf(n: f32) -> f32; - pub fn cbrt(n: f64) -> f64; - pub fn cbrtf(n: f32) -> f32; - pub fn cosh(n: f64) -> f64; - pub fn coshf(n: f32) -> f32; - pub fn expm1(n: f64) -> f64; - pub fn expm1f(n: f32) -> f32; - pub fn fdim(a: f64, b: f64) -> f64; - pub fn fdimf(a: f32, b: f32) -> f32; - pub fn hypot(x: f64, y: f64) -> f64; - pub fn hypotf(x: f32, y: f32) -> f32; - pub fn log1p(n: f64) -> f64; - pub fn log1pf(n: f32) -> f32; - pub fn sinh(n: f64) -> f64; - pub fn sinhf(n: f32) -> f32; - pub fn tan(n: f64) -> f64; - pub fn tanf(n: f32) -> f32; - pub fn tanh(n: f64) -> f64; - pub fn tanhf(n: f32) -> f32; -} diff --git a/src/libstd/sys/hermit/condvar.rs b/src/libstd/sys/hermit/condvar.rs deleted file mode 100644 index 52c8c3b17e8..00000000000 --- a/src/libstd/sys/hermit/condvar.rs +++ /dev/null @@ -1,64 +0,0 @@ -use crate::ffi::c_void; -use crate::ptr; -use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; -use crate::sys::hermit::abi; -use crate::sys::mutex::Mutex; -use crate::time::Duration; - -// The implementation is inspired by Andrew D. Birrell's paper -// "Implementing Condition Variables with Semaphores" - -pub struct Condvar { - counter: AtomicUsize, - sem1: *const c_void, - sem2: *const c_void, -} - -unsafe impl Send for Condvar {} -unsafe impl Sync for Condvar {} - -impl Condvar { - pub const fn new() -> Condvar { - Condvar { counter: AtomicUsize::new(0), sem1: ptr::null(), sem2: ptr::null() } - } - - pub unsafe fn init(&mut self) { - let _ = abi::sem_init(&mut self.sem1 as *mut *const c_void, 0); - let _ = abi::sem_init(&mut self.sem2 as *mut *const c_void, 0); - } - - pub unsafe fn notify_one(&self) { - if self.counter.load(SeqCst) > 0 { - self.counter.fetch_sub(1, SeqCst); - abi::sem_post(self.sem1); - abi::sem_timedwait(self.sem2, 0); - } - } - - pub unsafe fn notify_all(&self) { - let counter = self.counter.swap(0, SeqCst); - for _ in 0..counter { - abi::sem_post(self.sem1); - } - for _ in 0..counter { - abi::sem_timedwait(self.sem2, 0); - } - } - - pub unsafe fn wait(&self, mutex: &Mutex) { - self.counter.fetch_add(1, SeqCst); - mutex.unlock(); - abi::sem_timedwait(self.sem1, 0); - abi::sem_post(self.sem2); - mutex.lock(); - } - - pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool { - panic!("wait_timeout not supported on hermit"); - } - - pub unsafe fn destroy(&self) { - let _ = abi::sem_destroy(self.sem1); - let _ = abi::sem_destroy(self.sem2); - } -} diff --git a/src/libstd/sys/hermit/env.rs b/src/libstd/sys/hermit/env.rs deleted file mode 100644 index 7a0fcb31ef2..00000000000 --- a/src/libstd/sys/hermit/env.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod os { - pub const FAMILY: &str = ""; - pub const OS: &str = "hermit"; - pub const DLL_PREFIX: &str = ""; - pub const DLL_SUFFIX: &str = ""; - pub const DLL_EXTENSION: &str = ""; - pub const EXE_SUFFIX: &str = ""; - pub const EXE_EXTENSION: &str = ""; -} diff --git a/src/libstd/sys/hermit/ext/ffi.rs b/src/libstd/sys/hermit/ext/ffi.rs deleted file mode 100644 index 07b59a02556..00000000000 --- a/src/libstd/sys/hermit/ext/ffi.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! HermitCore-specific extension to the primitives in the `std::ffi` module -//! -//! # Examples -//! -//! ``` -//! use std::ffi::OsString; -//! use std::os::hermit::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::hermit::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/hermit/ext/mod.rs b/src/libstd/sys/hermit/ext/mod.rs deleted file mode 100644 index ea87d0ad2c9..00000000000 --- a/src/libstd/sys/hermit/ext/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![stable(feature = "rust1", since = "1.0.0")] -#![allow(missing_docs)] - -pub mod ffi; - -/// 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::ffi::{OsStrExt, OsStringExt}; -} diff --git a/src/libstd/sys/hermit/fd.rs b/src/libstd/sys/hermit/fd.rs deleted file mode 100644 index 97d1a38b41a..00000000000 --- a/src/libstd/sys/hermit/fd.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![unstable(reason = "not public", issue = "none", feature = "fd")] - -use crate::io::{self, ErrorKind, Read}; -use crate::mem; -use crate::sys::cvt; -use crate::sys::hermit::abi; -use crate::sys_common::AsInner; - -#[derive(Debug)] -pub struct FileDesc { - fd: i32, -} - -impl FileDesc { - pub fn new(fd: i32) -> FileDesc { - FileDesc { fd } - } - - pub fn raw(&self) -> i32 { - self.fd - } - - /// Extracts the actual file descriptor without closing it. - pub fn into_raw(self) -> i32 { - let fd = self.fd; - mem::forget(self); - fd - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - let result = unsafe { abi::read(self.fd, buf.as_mut_ptr(), buf.len()) }; - cvt(result as i32) - } - - pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> { - let mut me = self; - (&mut me).read_to_end(buf) - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - let result = unsafe { abi::write(self.fd, buf.as_ptr(), buf.len()) }; - cvt(result as i32) - } - - pub fn duplicate(&self) -> io::Result<FileDesc> { - self.duplicate_path(&[]) - } - pub fn duplicate_path(&self, _path: &[u8]) -> io::Result<FileDesc> { - Err(io::Error::new(ErrorKind::Other, "duplicate isn't supported")) - } - - pub fn nonblocking(&self) -> io::Result<bool> { - Ok(false) - } - - pub fn set_cloexec(&self) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "cloexec isn't supported")) - } - - pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "nonblocking isn't supported")) - } -} - -impl<'a> Read for &'a FileDesc { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - (**self).read(buf) - } -} - -impl AsInner<i32> for FileDesc { - fn as_inner(&self) -> &i32 { - &self.fd - } -} - -impl Drop for FileDesc { - fn drop(&mut self) { - // Note that errors are ignored when closing a file descriptor. The - // reason for this is that if an error occurs we don't actually know if - // the file descriptor was closed or not, and if we retried (for - // something like EINTR), we might close another valid file descriptor - // (opened after we closed ours. - let _ = unsafe { abi::close(self.fd) }; - } -} diff --git a/src/libstd/sys/hermit/fs.rs b/src/libstd/sys/hermit/fs.rs deleted file mode 100644 index 82ccab1462b..00000000000 --- a/src/libstd/sys/hermit/fs.rs +++ /dev/null @@ -1,402 +0,0 @@ -use crate::ffi::{CStr, CString, OsString}; -use crate::fmt; -use crate::hash::{Hash, Hasher}; -use crate::io::{self, Error, ErrorKind}; -use crate::io::{IoSlice, IoSliceMut, SeekFrom}; -use crate::path::{Path, PathBuf}; -use crate::sys::cvt; -use crate::sys::hermit::abi; -use crate::sys::hermit::abi::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY}; -use crate::sys::hermit::fd::FileDesc; -use crate::sys::time::SystemTime; -use crate::sys::{unsupported, Void}; -use crate::sys_common::os_str_bytes::OsStrExt; - -pub use crate::sys_common::fs::copy; -//pub use crate::sys_common::fs::remove_dir_all; - -fn cstr(path: &Path) -> io::Result<CString> { - Ok(CString::new(path.as_os_str().as_bytes())?) -} - -#[derive(Debug)] -pub struct File(FileDesc); - -pub struct FileAttr(Void); - -pub struct ReadDir(Void); - -pub struct DirEntry(Void); - -#[derive(Clone, Debug)] -pub struct OpenOptions { - // generic - read: bool, - write: bool, - append: bool, - truncate: bool, - create: bool, - create_new: bool, - // system-specific - mode: i32, -} - -pub struct FilePermissions(Void); - -pub struct FileType(Void); - -#[derive(Debug)] -pub struct DirBuilder {} - -impl FileAttr { - pub fn size(&self) -> u64 { - match self.0 {} - } - - pub fn perm(&self) -> FilePermissions { - match self.0 {} - } - - pub fn file_type(&self) -> FileType { - match self.0 {} - } - - pub fn modified(&self) -> io::Result<SystemTime> { - match self.0 {} - } - - pub fn accessed(&self) -> io::Result<SystemTime> { - match self.0 {} - } - - pub fn created(&self) -> io::Result<SystemTime> { - match self.0 {} - } -} - -impl Clone for FileAttr { - fn clone(&self) -> FileAttr { - match self.0 {} - } -} - -impl FilePermissions { - pub fn readonly(&self) -> bool { - match self.0 {} - } - - pub fn set_readonly(&mut self, _readonly: bool) { - match self.0 {} - } -} - -impl Clone for FilePermissions { - fn clone(&self) -> FilePermissions { - match self.0 {} - } -} - -impl PartialEq for FilePermissions { - fn eq(&self, _other: &FilePermissions) -> bool { - match self.0 {} - } -} - -impl Eq for FilePermissions {} - -impl fmt::Debug for FilePermissions { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.0 {} - } -} - -impl FileType { - pub fn is_dir(&self) -> bool { - match self.0 {} - } - - pub fn is_file(&self) -> bool { - match self.0 {} - } - - pub fn is_symlink(&self) -> bool { - match self.0 {} - } -} - -impl Clone for FileType { - fn clone(&self) -> FileType { - match self.0 {} - } -} - -impl Copy for FileType {} - -impl PartialEq for FileType { - fn eq(&self, _other: &FileType) -> bool { - match self.0 {} - } -} - -impl Eq for FileType {} - -impl Hash for FileType { - fn hash<H: Hasher>(&self, _h: &mut H) { - match self.0 {} - } -} - -impl fmt::Debug for FileType { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.0 {} - } -} - -impl fmt::Debug for ReadDir { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.0 {} - } -} - -impl Iterator for ReadDir { - type Item = io::Result<DirEntry>; - - fn next(&mut self) -> Option<io::Result<DirEntry>> { - match self.0 {} - } -} - -impl DirEntry { - pub fn path(&self) -> PathBuf { - match self.0 {} - } - - pub fn file_name(&self) -> OsString { - match self.0 {} - } - - pub fn metadata(&self) -> io::Result<FileAttr> { - match self.0 {} - } - - pub fn file_type(&self) -> io::Result<FileType> { - match self.0 {} - } -} - -impl OpenOptions { - pub fn new() -> OpenOptions { - OpenOptions { - // generic - read: false, - write: false, - append: false, - truncate: false, - create: false, - create_new: false, - // system-specific - mode: 0x777, - } - } - - 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; - } - - fn get_access_mode(&self) -> io::Result<i32> { - match (self.read, self.write, self.append) { - (true, false, false) => Ok(O_RDONLY), - (false, true, false) => Ok(O_WRONLY), - (true, true, false) => Ok(O_RDWR), - (false, _, true) => Ok(O_WRONLY | O_APPEND), - (true, _, true) => Ok(O_RDWR | O_APPEND), - (false, false, false) => { - Err(io::Error::new(ErrorKind::InvalidInput, "invalid access mode")) - } - } - } - - fn get_creation_mode(&self) -> io::Result<i32> { - match (self.write, self.append) { - (true, false) => {} - (false, false) => { - if self.truncate || self.create || self.create_new { - return Err(io::Error::new(ErrorKind::InvalidInput, "invalid creation mode")); - } - } - (_, true) => { - if self.truncate && !self.create_new { - return Err(io::Error::new(ErrorKind::InvalidInput, "invalid creation mode")); - } - } - } - - Ok(match (self.create, self.truncate, self.create_new) { - (false, false, false) => 0, - (true, false, false) => O_CREAT, - (false, true, false) => O_TRUNC, - (true, true, false) => O_CREAT | O_TRUNC, - (_, _, true) => O_CREAT | O_EXCL, - }) - } -} - -impl File { - pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> { - let path = cstr(path)?; - File::open_c(&path, opts) - } - - pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> { - let mut flags = opts.get_access_mode()?; - flags = flags | opts.get_creation_mode()?; - - let mode; - if flags & O_CREAT == O_CREAT { - mode = opts.mode; - } else { - mode = 0; - } - - let fd = unsafe { cvt(abi::open(path.as_ptr(), flags, mode))? }; - Ok(File(FileDesc::new(fd as i32))) - } - - pub fn file_attr(&self) -> io::Result<FileAttr> { - Err(Error::from_raw_os_error(22)) - } - - pub fn fsync(&self) -> io::Result<()> { - Err(Error::from_raw_os_error(22)) - } - - pub fn datasync(&self) -> io::Result<()> { - self.fsync() - } - - pub fn truncate(&self, _size: u64) -> io::Result<()> { - Err(Error::from_raw_os_error(22)) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - self.0.read(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - crate::io::default_read_vectored(|buf| self.read(buf), bufs) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - false - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - crate::io::default_write_vectored(|buf| self.write(buf), bufs) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - false - } - - pub fn flush(&self) -> io::Result<()> { - Ok(()) - } - - pub fn seek(&self, _pos: SeekFrom) -> io::Result<u64> { - Err(Error::from_raw_os_error(22)) - } - - pub fn duplicate(&self) -> io::Result<File> { - Err(Error::from_raw_os_error(22)) - } - - pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { - Err(Error::from_raw_os_error(22)) - } - - pub fn diverge(&self) -> ! { - loop {} - } -} - -impl DirBuilder { - pub fn new() -> DirBuilder { - DirBuilder {} - } - - pub fn mkdir(&self, _p: &Path) -> io::Result<()> { - unsupported() - } -} - -pub fn readdir(_p: &Path) -> io::Result<ReadDir> { - unsupported() -} - -pub fn unlink(path: &Path) -> io::Result<()> { - let name = cstr(path)?; - let _ = unsafe { cvt(abi::unlink(name.as_ptr()))? }; - Ok(()) -} - -pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> { - unsupported() -} - -pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> { - match perm.0 {} -} - -pub fn rmdir(_p: &Path) -> io::Result<()> { - unsupported() -} - -pub fn remove_dir_all(_path: &Path) -> io::Result<()> { - //unsupported() - Ok(()) -} - -pub fn readlink(_p: &Path) -> io::Result<PathBuf> { - unsupported() -} - -pub fn symlink(_src: &Path, _dst: &Path) -> io::Result<()> { - unsupported() -} - -pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { - unsupported() -} - -pub fn stat(_p: &Path) -> io::Result<FileAttr> { - unsupported() -} - -pub fn lstat(_p: &Path) -> io::Result<FileAttr> { - unsupported() -} - -pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> { - unsupported() -} diff --git a/src/libstd/sys/hermit/io.rs b/src/libstd/sys/hermit/io.rs deleted file mode 100644 index d5f475b4310..00000000000 --- a/src/libstd/sys/hermit/io.rs +++ /dev/null @@ -1,47 +0,0 @@ -use crate::mem; - -#[derive(Copy, Clone)] -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/hermit/memchr.rs b/src/libstd/sys/hermit/memchr.rs deleted file mode 100644 index 9967482197e..00000000000 --- a/src/libstd/sys/hermit/memchr.rs +++ /dev/null @@ -1 +0,0 @@ -pub use core::slice::memchr::{memchr, memrchr}; diff --git a/src/libstd/sys/hermit/mod.rs b/src/libstd/sys/hermit/mod.rs deleted file mode 100644 index 675b82ceb77..00000000000 --- a/src/libstd/sys/hermit/mod.rs +++ /dev/null @@ -1,146 +0,0 @@ -//! System bindings for HermitCore -//! -//! This module contains the facade (aka platform-specific) implementations of -//! OS level functionality for HermitCore. -//! -//! This is all super highly experimental and not actually intended for -//! wide/production use yet, it's still all in the experimental category. This -//! will likely change over time. -//! -//! Currently all functions here are basically stubs that immediately return -//! errors. The hope is that with a portability lint we can turn actually just -//! remove all this and just omit parts of the standard library if we're -//! compiling for wasm. That way it's a compile time error for something that's -//! guaranteed to be a runtime error! - -use crate::intrinsics; -use crate::os::raw::c_char; - -pub mod alloc; -pub mod args; -pub mod cmath; -pub mod condvar; -pub mod env; -pub mod ext; -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 rwlock; -pub mod stack_overflow; -pub mod stdio; -pub mod thread; -pub mod thread_local_dtor; -pub mod thread_local_key; -pub mod time; - -use crate::io::ErrorKind; -pub use crate::sys_common::os_str_bytes as os_str; - -#[allow(unused_extern_crates)] -pub extern crate hermit_abi as abi; - -pub fn unsupported<T>() -> crate::io::Result<T> { - Err(unsupported_err()) -} - -pub fn unsupported_err() -> crate::io::Error { - crate::io::Error::new(crate::io::ErrorKind::Other, "operation not supported on HermitCore yet") -} - -// This enum is used as the storage for a bunch of types which can't actually -// exist. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub enum Void {} - -pub unsafe fn strlen(start: *const c_char) -> usize { - let mut str = start; - - while *str != 0 { - str = str.offset(1); - } - - (str as usize) - (start as usize) -} - -#[no_mangle] -pub extern "C" fn floor(x: f64) -> f64 { - unsafe { intrinsics::floorf64(x) } -} - -pub fn abort_internal() -> ! { - unsafe { - abi::abort(); - } -} - -// FIXME: just a workaround to test the system -pub fn hashmap_random_keys() -> (u64, u64) { - (1, 2) -} - -// This function is needed by the panic runtime. The symbol is named in -// pre-link args for the target specification, so keep that in sync. -#[cfg(not(test))] -#[no_mangle] -// NB. used by both libunwind and libpanic_abort -pub extern "C" fn __rust_abort() { - abort_internal(); -} - -#[cfg(not(test))] -pub fn init() { - let _ = net::init(); -} - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn runtime_entry( - argc: i32, - argv: *const *const c_char, - env: *const *const c_char, -) -> ! { - use crate::sys::hermit::fast_thread_local::run_dtors; - extern "C" { - fn main(argc: isize, argv: *const *const c_char) -> i32; - } - - // initialize environment - os::init_environment(env as *const *const i8); - - let result = main(argc as isize, argv); - - run_dtors(); - abi::exit(result); -} - -pub fn decode_error_kind(errno: i32) -> ErrorKind { - match errno { - x if x == 13 as i32 => ErrorKind::PermissionDenied, - x if x == 98 as i32 => ErrorKind::AddrInUse, - x if x == 99 as i32 => ErrorKind::AddrNotAvailable, - x if x == 11 as i32 => ErrorKind::WouldBlock, - x if x == 103 as i32 => ErrorKind::ConnectionAborted, - x if x == 111 as i32 => ErrorKind::ConnectionRefused, - x if x == 104 as i32 => ErrorKind::ConnectionReset, - x if x == 17 as i32 => ErrorKind::AlreadyExists, - x if x == 4 as i32 => ErrorKind::Interrupted, - x if x == 22 as i32 => ErrorKind::InvalidInput, - x if x == 2 as i32 => ErrorKind::NotFound, - x if x == 107 as i32 => ErrorKind::NotConnected, - x if x == 1 as i32 => ErrorKind::PermissionDenied, - x if x == 32 as i32 => ErrorKind::BrokenPipe, - x if x == 110 as i32 => ErrorKind::TimedOut, - _ => ErrorKind::Other, - } -} - -pub fn cvt(result: i32) -> crate::io::Result<usize> { - if result < 0 { Err(crate::io::Error::from_raw_os_error(-result)) } else { Ok(result as usize) } -} diff --git a/src/libstd/sys/hermit/mutex.rs b/src/libstd/sys/hermit/mutex.rs deleted file mode 100644 index 3d4813209cb..00000000000 --- a/src/libstd/sys/hermit/mutex.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::ffi::c_void; -use crate::ptr; -use crate::sys::hermit::abi; - -pub struct Mutex { - inner: *const c_void, -} - -unsafe impl Send for Mutex {} -unsafe impl Sync for Mutex {} - -impl Mutex { - pub const fn new() -> Mutex { - Mutex { inner: ptr::null() } - } - - #[inline] - pub unsafe fn init(&mut self) { - let _ = abi::sem_init(&mut self.inner as *mut *const c_void, 1); - } - - #[inline] - pub unsafe fn lock(&self) { - let _ = abi::sem_timedwait(self.inner, 0); - } - - #[inline] - pub unsafe fn unlock(&self) { - let _ = abi::sem_post(self.inner); - } - - #[inline] - pub unsafe fn try_lock(&self) -> bool { - let result = abi::sem_trywait(self.inner); - result == 0 - } - - #[inline] - pub unsafe fn destroy(&self) { - let _ = abi::sem_destroy(self.inner); - } -} - -pub struct ReentrantMutex { - inner: *const c_void, -} - -impl ReentrantMutex { - pub const unsafe fn uninitialized() -> ReentrantMutex { - ReentrantMutex { inner: ptr::null() } - } - - #[inline] - pub unsafe fn init(&self) { - let _ = abi::recmutex_init(&self.inner as *const *const c_void as *mut _); - } - - #[inline] - pub unsafe fn lock(&self) { - let _ = abi::recmutex_lock(self.inner); - } - - #[inline] - pub unsafe fn try_lock(&self) -> bool { - true - } - - #[inline] - pub unsafe fn unlock(&self) { - let _ = abi::recmutex_unlock(self.inner); - } - - #[inline] - pub unsafe fn destroy(&self) { - let _ = abi::recmutex_destroy(self.inner); - } -} diff --git a/src/libstd/sys/hermit/net.rs b/src/libstd/sys/hermit/net.rs deleted file mode 100644 index 8a788a9265f..00000000000 --- a/src/libstd/sys/hermit/net.rs +++ /dev/null @@ -1,473 +0,0 @@ -use crate::convert::TryFrom; -use crate::fmt; -use crate::io::{self, ErrorKind, IoSlice, IoSliceMut}; -use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; -use crate::str; -use crate::sync::Arc; -use crate::sys::hermit::abi; -use crate::sys::hermit::abi::IpAddress::{Ipv4, Ipv6}; -use crate::sys::{unsupported, Void}; -use crate::sys_common::AsInner; -use crate::time::Duration; - -/// Checks whether the HermitCore's socket interface has been started already, and -/// if not, starts it. -pub fn init() -> io::Result<()> { - if abi::network_init() < 0 { - return Err(io::Error::new(ErrorKind::Other, "Unable to initialize network interface")); - } - - Ok(()) -} - -#[derive(Debug, Clone)] -pub struct Socket(abi::Handle); - -impl AsInner<abi::Handle> for Socket { - fn as_inner(&self) -> &abi::Handle { - &self.0 - } -} - -impl Drop for Socket { - fn drop(&mut self) { - let _ = abi::tcpstream::close(self.0); - } -} - -// Arc is used to count the number of used sockets. -// Only if all sockets are released, the drop -// method will close the socket. -#[derive(Clone)] -pub struct TcpStream(Arc<Socket>); - -impl TcpStream { - pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> { - let addr = addr?; - - match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) { - Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))), - _ => { - Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket")) - } - } - } - - pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> { - match abi::tcpstream::connect( - saddr.ip().to_string().as_bytes(), - saddr.port(), - Some(duration.as_millis() as u64), - ) { - Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))), - _ => { - Err(io::Error::new(ErrorKind::Other, "Unable to initiate a connection on a socket")) - } - } - } - - pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> { - abi::tcpstream::set_read_timeout(*self.0.as_inner(), duration.map(|d| d.as_millis() as u64)) - .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value")) - } - - pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> { - abi::tcpstream::set_write_timeout( - *self.0.as_inner(), - duration.map(|d| d.as_millis() as u64), - ) - .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to set timeout value")) - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - let duration = abi::tcpstream::get_read_timeout(*self.0.as_inner()) - .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?; - - Ok(duration.map(|d| Duration::from_millis(d))) - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - let duration = abi::tcpstream::get_write_timeout(*self.0.as_inner()) - .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to determine timeout value"))?; - - Ok(duration.map(|d| Duration::from_millis(d))) - } - - pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - abi::tcpstream::peek(*self.0.as_inner(), buf) - .map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed")) - } - - pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> { - self.read_vectored(&mut [IoSliceMut::new(buffer)]) - } - - pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - let mut size: usize = 0; - - for i in ioslice.iter_mut() { - let ret = abi::tcpstream::read(*self.0.as_inner(), &mut i[0..]) - .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to read on socket"))?; - - if ret != 0 { - size += ret; - } - } - - Ok(size) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - true - } - - pub fn write(&self, buffer: &[u8]) -> io::Result<usize> { - self.write_vectored(&[IoSlice::new(buffer)]) - } - - pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> { - let mut size: usize = 0; - - for i in ioslice.iter() { - size += abi::tcpstream::write(*self.0.as_inner(), i) - .map_err(|_| io::Error::new(ErrorKind::Other, "Unable to write on socket"))?; - } - - Ok(size) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - true - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - let (ipaddr, port) = abi::tcpstream::peer_addr(*self.0.as_inner()) - .map_err(|_| io::Error::new(ErrorKind::Other, "peer_addr failed"))?; - - let saddr = match ipaddr { - Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port), - Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port), - _ => { - return Err(io::Error::new(ErrorKind::Other, "peer_addr failed")); - } - }; - - Ok(saddr) - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - Err(io::Error::new(ErrorKind::Other, "socket_addr isn't supported")) - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - abi::tcpstream::shutdown(*self.0.as_inner(), how as i32) - .map_err(|_| io::Error::new(ErrorKind::Other, "unable to shutdown socket")) - } - - pub fn duplicate(&self) -> io::Result<TcpStream> { - Ok(self.clone()) - } - - pub fn set_nodelay(&self, mode: bool) -> io::Result<()> { - abi::tcpstream::set_nodelay(*self.0.as_inner(), mode) - .map_err(|_| io::Error::new(ErrorKind::Other, "set_nodelay failed")) - } - - pub fn nodelay(&self) -> io::Result<bool> { - abi::tcpstream::nodelay(*self.0.as_inner()) - .map_err(|_| io::Error::new(ErrorKind::Other, "nodelay failed")) - } - - pub fn set_ttl(&self, tll: u32) -> io::Result<()> { - abi::tcpstream::set_tll(*self.0.as_inner(), tll) - .map_err(|_| io::Error::new(ErrorKind::Other, "unable to set TTL")) - } - - pub fn ttl(&self) -> io::Result<u32> { - abi::tcpstream::get_tll(*self.0.as_inner()) - .map_err(|_| io::Error::new(ErrorKind::Other, "unable to get TTL")) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - Err(io::Error::new(ErrorKind::Other, "take_error isn't supported")) - } - - pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> { - abi::tcpstream::set_nonblocking(*self.0.as_inner(), mode) - .map_err(|_| io::Error::new(ErrorKind::Other, "unable to set blocking mode")) - } -} - -impl fmt::Debug for TcpStream { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -#[derive(Clone)] -pub struct TcpListener(SocketAddr); - -impl TcpListener { - pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> { - let addr = addr?; - - Ok(TcpListener(*addr)) - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - Ok(self.0) - } - - pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - let (handle, ipaddr, port) = abi::tcplistener::accept(self.0.port()) - .map_err(|_| io::Error::new(ErrorKind::Other, "accept failed"))?; - let saddr = match ipaddr { - Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port), - Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port), - _ => { - return Err(io::Error::new(ErrorKind::Other, "accept failed")); - } - }; - - Ok((TcpStream(Arc::new(Socket(handle))), saddr)) - } - - pub fn duplicate(&self) -> io::Result<TcpListener> { - Ok(self.clone()) - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn ttl(&self) -> io::Result<u32> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn set_only_v6(&self, _: bool) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn only_v6(&self) -> io::Result<bool> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } -} - -impl fmt::Debug for TcpListener { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub struct UdpSocket(abi::Handle); - -impl UdpSocket { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn duplicate(&self) -> io::Result<UdpSocket> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn set_broadcast(&self, _: bool) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn broadcast(&self) -> io::Result<bool> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn multicast_loop_v4(&self) -> io::Result<bool> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn multicast_ttl_v4(&self) -> io::Result<u32> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn multicast_loop_v6(&self) -> io::Result<bool> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn ttl(&self) -> io::Result<u32> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn send(&self, _: &[u8]) -> io::Result<usize> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } - - pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { - Err(io::Error::new(ErrorKind::Other, "not supported")) - } -} - -impl fmt::Debug for UdpSocket { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub struct LookupHost(Void); - -impl LookupHost { - pub fn port(&self) -> u16 { - match self.0 {} - } -} - -impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option<SocketAddr> { - match self.0 {} - } -} - -impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(_v: &str) -> io::Result<LookupHost> { - unsupported() - } -} - -impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> { - unsupported() - } -} - -#[allow(nonstandard_style)] -pub mod netc { - pub const AF_INET: u8 = 0; - pub const AF_INET6: u8 = 1; - pub type sa_family_t = u8; - - #[derive(Copy, Clone)] - pub struct in_addr { - pub s_addr: u32, - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in { - pub sin_family: sa_family_t, - pub sin_port: u16, - pub sin_addr: in_addr, - } - - #[derive(Copy, Clone)] - pub struct in6_addr { - pub s6_addr: [u8; 16], - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in6 { - pub sin6_family: sa_family_t, - pub sin6_port: u16, - pub sin6_addr: in6_addr, - pub sin6_flowinfo: u32, - pub sin6_scope_id: u32, - } - - #[derive(Copy, Clone)] - pub struct sockaddr {} - - pub type socklen_t = usize; -} diff --git a/src/libstd/sys/hermit/os.rs b/src/libstd/sys/hermit/os.rs deleted file mode 100644 index 78eabf8f81e..00000000000 --- a/src/libstd/sys/hermit/os.rs +++ /dev/null @@ -1,181 +0,0 @@ -use crate::collections::HashMap; -use crate::error::Error as StdError; -use crate::ffi::{CStr, OsStr, OsString}; -use crate::fmt; -use crate::io; -use crate::marker::PhantomData; -use crate::memchr; -use crate::path::{self, PathBuf}; -use crate::str; -use crate::sync::Mutex; -use crate::sys::hermit::abi; -use crate::sys::{unsupported, Void}; -use crate::sys_common::os_str_bytes::*; -use crate::vec; - -pub fn errno() -> i32 { - 0 -} - -pub fn error_string(_errno: i32) -> String { - "operation successful".to_string() -} - -pub fn getcwd() -> io::Result<PathBuf> { - unsupported() -} - -pub fn chdir(_: &path::Path) -> io::Result<()> { - unsupported() -} - -pub struct SplitPaths<'a>(&'a Void); - -pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { - panic!("unsupported") -} - -impl<'a> Iterator for SplitPaths<'a> { - type Item = PathBuf; - fn next(&mut self) -> Option<PathBuf> { - match *self.0 {} - } -} - -#[derive(Debug)] -pub struct JoinPathsError; - -pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError> -where - I: Iterator<Item = T>, - T: AsRef<OsStr>, -{ - Err(JoinPathsError) -} - -impl fmt::Display for JoinPathsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported on hermit yet".fmt(f) - } -} - -impl StdError for JoinPathsError { - #[allow(deprecated)] - fn description(&self) -> &str { - "not supported on hermit yet" - } -} - -pub fn current_exe() -> io::Result<PathBuf> { - unsupported() -} - -static mut ENV: Option<Mutex<HashMap<OsString, OsString>>> = None; - -pub fn init_environment(env: *const *const i8) { - unsafe { - ENV = Some(Mutex::new(HashMap::new())); - - if env.is_null() { - return; - } - - let mut guard = ENV.as_ref().unwrap().lock().unwrap(); - let mut environ = env; - while !(*environ).is_null() { - if let Some((key, value)) = parse(CStr::from_ptr(*environ).to_bytes()) { - guard.insert(key, value); - } - environ = environ.add(1); - } - } - - 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 struct Env { - iter: vec::IntoIter<(OsString, OsString)>, - _dont_send_or_sync_me: PhantomData<*mut ()>, -} - -impl Iterator for Env { - type Item = (OsString, OsString); - fn next(&mut self) -> Option<(OsString, OsString)> { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option<usize>) { - self.iter.size_hint() - } -} - -/// 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.as_ref().unwrap().lock().unwrap(); - let mut result = Vec::new(); - - for (key, value) in guard.iter() { - result.push((key.clone(), value.clone())); - } - - return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData }; - } -} - -pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> { - unsafe { - match ENV.as_ref().unwrap().lock().unwrap().get_mut(k) { - Some(value) => Ok(Some(value.clone())), - None => Ok(None), - } - } -} - -pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { - unsafe { - let (k, v) = (k.to_owned(), v.to_owned()); - ENV.as_ref().unwrap().lock().unwrap().insert(k, v); - } - Ok(()) -} - -pub fn unsetenv(k: &OsStr) -> io::Result<()> { - unsafe { - ENV.as_ref().unwrap().lock().unwrap().remove(k); - } - Ok(()) -} - -pub fn temp_dir() -> PathBuf { - panic!("no filesystem on hermit") -} - -pub fn home_dir() -> Option<PathBuf> { - None -} - -pub fn exit(code: i32) -> ! { - unsafe { - abi::exit(code); - } -} - -pub fn getpid() -> u32 { - unsafe { abi::getpid() } -} diff --git a/src/libstd/sys/hermit/path.rs b/src/libstd/sys/hermit/path.rs deleted file mode 100644 index 840a7ae0426..00000000000 --- a/src/libstd/sys/hermit/path.rs +++ /dev/null @@ -1,19 +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(_: &OsStr) -> Option<Prefix<'_>> { - None -} - -pub const MAIN_SEP_STR: &str = "/"; -pub const MAIN_SEP: char = '/'; diff --git a/src/libstd/sys/hermit/pipe.rs b/src/libstd/sys/hermit/pipe.rs deleted file mode 100644 index 10d0925823e..00000000000 --- a/src/libstd/sys/hermit/pipe.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::sys::Void; - -pub struct AnonPipe(Void); - -impl AnonPipe { - pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> { - match self.0 {} - } - - pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - match self.0 {} - } - - pub fn is_read_vectored(&self) -> bool { - match self.0 {} - } - - pub fn write(&self, _buf: &[u8]) -> io::Result<usize> { - match self.0 {} - } - - pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result<usize> { - match self.0 {} - } - - pub fn is_write_vectored(&self) -> bool { - match self.0 {} - } - - pub fn diverge(&self) -> ! { - match self.0 {} - } -} - -pub fn read2(p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> { - match p1.0 {} -} diff --git a/src/libstd/sys/hermit/process.rs b/src/libstd/sys/hermit/process.rs deleted file mode 100644 index 4702e5c5492..00000000000 --- a/src/libstd/sys/hermit/process.rs +++ /dev/null @@ -1,149 +0,0 @@ -use crate::ffi::OsStr; -use crate::fmt; -use crate::io; -use crate::sys::fs::File; -use crate::sys::pipe::AnonPipe; -use crate::sys::{unsupported, Void}; -use crate::sys_common::process::CommandEnv; - -pub use crate::ffi::OsString as EnvKey; - -//////////////////////////////////////////////////////////////////////////////// -// Command -//////////////////////////////////////////////////////////////////////////////// - -pub struct Command { - env: CommandEnv, -} - -// passed back to std::process with the pipes connected to the child, if any -// were requested -pub struct StdioPipes { - pub stdin: Option<AnonPipe>, - pub stdout: Option<AnonPipe>, - pub stderr: Option<AnonPipe>, -} - -pub enum Stdio { - Inherit, - Null, - MakePipe, -} - -impl Command { - pub fn new(_program: &OsStr) -> Command { - Command { env: Default::default() } - } - - pub fn arg(&mut self, _arg: &OsStr) {} - - pub fn env_mut(&mut self) -> &mut CommandEnv { - &mut self.env - } - - pub fn cwd(&mut self, _dir: &OsStr) {} - - pub fn stdin(&mut self, _stdin: Stdio) {} - - pub fn stdout(&mut self, _stdout: Stdio) {} - - pub fn stderr(&mut self, _stderr: Stdio) {} - - pub fn spawn( - &mut self, - _default: Stdio, - _needs_stdin: bool, - ) -> io::Result<(Process, StdioPipes)> { - unsupported() - } -} - -impl From<AnonPipe> for Stdio { - fn from(pipe: AnonPipe) -> Stdio { - pipe.diverge() - } -} - -impl From<File> for Stdio { - fn from(file: File) -> Stdio { - file.diverge() - } -} - -impl fmt::Debug for Command { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub struct ExitStatus(Void); - -impl ExitStatus { - pub fn success(&self) -> bool { - match self.0 {} - } - - pub fn code(&self) -> Option<i32> { - match self.0 {} - } -} - -impl Clone for ExitStatus { - fn clone(&self) -> ExitStatus { - match self.0 {} - } -} - -impl Copy for ExitStatus {} - -impl PartialEq for ExitStatus { - fn eq(&self, _other: &ExitStatus) -> bool { - match self.0 {} - } -} - -impl Eq for ExitStatus {} - -impl fmt::Debug for ExitStatus { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.0 {} - } -} - -impl fmt::Display for ExitStatus { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.0 {} - } -} - -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitCode(bool); - -impl ExitCode { - pub const SUCCESS: ExitCode = ExitCode(false); - pub const FAILURE: ExitCode = ExitCode(true); - - pub fn as_i32(&self) -> i32 { - self.0 as i32 - } -} - -pub struct Process(Void); - -impl Process { - pub fn id(&self) -> u32 { - match self.0 {} - } - - pub fn kill(&mut self) -> io::Result<()> { - match self.0 {} - } - - pub fn wait(&mut self) -> io::Result<ExitStatus> { - match self.0 {} - } - - pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> { - match self.0 {} - } -} diff --git a/src/libstd/sys/hermit/rwlock.rs b/src/libstd/sys/hermit/rwlock.rs deleted file mode 100644 index 06442e925f4..00000000000 --- a/src/libstd/sys/hermit/rwlock.rs +++ /dev/null @@ -1,144 +0,0 @@ -use crate::cell::UnsafeCell; -use crate::sys::condvar::Condvar; -use crate::sys::mutex::Mutex; - -pub struct RWLock { - lock: Mutex, - cond: Condvar, - state: UnsafeCell<State>, -} - -enum State { - Unlocked, - Reading(usize), - Writing, -} - -unsafe impl Send for RWLock {} -unsafe impl Sync for RWLock {} - -// This rwlock implementation is a relatively simple implementation which has a -// condition variable for readers/writers as well as a mutex protecting the -// internal state of the lock. A current downside of the implementation is that -// unlocking the lock will notify *all* waiters rather than just readers or just -// writers. This can cause lots of "thundering stampede" problems. While -// hopefully correct this implementation is very likely to want to be changed in -// the future. - -impl RWLock { - pub const fn new() -> RWLock { - RWLock { lock: Mutex::new(), cond: Condvar::new(), state: UnsafeCell::new(State::Unlocked) } - } - - #[inline] - pub unsafe fn read(&self) { - self.lock.lock(); - while !(*self.state.get()).inc_readers() { - self.cond.wait(&self.lock); - } - self.lock.unlock(); - } - - #[inline] - pub unsafe fn try_read(&self) -> bool { - self.lock.lock(); - let ok = (*self.state.get()).inc_readers(); - self.lock.unlock(); - return ok; - } - - #[inline] - pub unsafe fn write(&self) { - self.lock.lock(); - while !(*self.state.get()).inc_writers() { - self.cond.wait(&self.lock); - } - self.lock.unlock(); - } - - #[inline] - pub unsafe fn try_write(&self) -> bool { - self.lock.lock(); - let ok = (*self.state.get()).inc_writers(); - self.lock.unlock(); - return ok; - } - - #[inline] - pub unsafe fn read_unlock(&self) { - self.lock.lock(); - let notify = (*self.state.get()).dec_readers(); - self.lock.unlock(); - if notify { - // FIXME: should only wake up one of these some of the time - self.cond.notify_all(); - } - } - - #[inline] - pub unsafe fn write_unlock(&self) { - self.lock.lock(); - (*self.state.get()).dec_writers(); - self.lock.unlock(); - // FIXME: should only wake up one of these some of the time - self.cond.notify_all(); - } - - #[inline] - pub unsafe fn destroy(&self) { - self.lock.destroy(); - self.cond.destroy(); - } -} - -impl State { - fn inc_readers(&mut self) -> bool { - match *self { - State::Unlocked => { - *self = State::Reading(1); - true - } - State::Reading(ref mut cnt) => { - *cnt += 1; - true - } - State::Writing => false, - } - } - - fn inc_writers(&mut self) -> bool { - match *self { - State::Unlocked => { - *self = State::Writing; - true - } - State::Reading(_) | State::Writing => false, - } - } - - fn dec_readers(&mut self) -> bool { - let zero = match *self { - State::Reading(ref mut cnt) => { - *cnt -= 1; - *cnt == 0 - } - State::Unlocked | State::Writing => invalid(), - }; - if zero { - *self = State::Unlocked; - } - zero - } - - fn dec_writers(&mut self) { - match *self { - State::Writing => {} - State::Unlocked | State::Reading(_) => invalid(), - } - *self = State::Unlocked; - } -} - -fn invalid() -> ! { - panic!("inconsistent rwlock"); -} diff --git a/src/libstd/sys/hermit/stack_overflow.rs b/src/libstd/sys/hermit/stack_overflow.rs deleted file mode 100644 index 121fe42011d..00000000000 --- a/src/libstd/sys/hermit/stack_overflow.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[inline] -pub unsafe fn init() {} - -#[inline] -pub unsafe fn cleanup() {} diff --git a/src/libstd/sys/hermit/stdio.rs b/src/libstd/sys/hermit/stdio.rs deleted file mode 100644 index f3654ee3871..00000000000 --- a/src/libstd/sys/hermit/stdio.rs +++ /dev/null @@ -1,120 +0,0 @@ -use crate::io; -use crate::io::{IoSlice, IoSliceMut}; -use crate::sys::hermit::abi; - -pub struct Stdin; -pub struct Stdout; -pub struct Stderr; - -impl Stdin { - pub fn new() -> io::Result<Stdin> { - Ok(Stdin) - } -} - -impl io::Read for Stdin { - fn read(&mut self, data: &mut [u8]) -> io::Result<usize> { - self.read_vectored(&mut [IoSliceMut::new(data)]) - } - - fn read_vectored(&mut self, _data: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - Ok(0) - } - - #[inline] - fn is_read_vectored(&self) -> bool { - true - } -} - -impl Stdout { - pub fn new() -> io::Result<Stdout> { - Ok(Stdout) - } -} - -impl io::Write for Stdout { - fn write(&mut self, data: &[u8]) -> io::Result<usize> { - let len; - - unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) } - - if len < 0 { - Err(io::Error::new(io::ErrorKind::Other, "Stdout is not able to print")) - } else { - Ok(len as usize) - } - } - - fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> { - let len; - - unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) } - - if len < 0 { - Err(io::Error::new(io::ErrorKind::Other, "Stdout is not able to print")) - } else { - Ok(len as usize) - } - } - - #[inline] - fn is_write_vectored(&self) -> bool { - true - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl Stderr { - pub fn new() -> io::Result<Stderr> { - Ok(Stderr) - } -} - -impl io::Write for Stderr { - fn write(&mut self, data: &[u8]) -> io::Result<usize> { - let len; - - unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) } - - if len < 0 { - Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print")) - } else { - Ok(len as usize) - } - } - - fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> { - let len; - - unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) } - - if len < 0 { - Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print")) - } else { - Ok(len as usize) - } - } - - #[inline] - fn is_write_vectored(&self) -> bool { - true - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -pub const STDIN_BUF_SIZE: usize = 0; - -pub fn is_ebadf(_err: &io::Error) -> bool { - true -} - -pub fn panic_output() -> Option<impl io::Write> { - Stderr::new().ok() -} diff --git a/src/libstd/sys/hermit/thread.rs b/src/libstd/sys/hermit/thread.rs deleted file mode 100644 index e11afed6687..00000000000 --- a/src/libstd/sys/hermit/thread.rs +++ /dev/null @@ -1,106 +0,0 @@ -#![allow(dead_code)] - -use crate::ffi::CStr; -use crate::io; -use crate::mem; -use crate::sys::hermit::abi; -use crate::sys::hermit::fast_thread_local::run_dtors; -use crate::time::Duration; - -pub type Tid = abi::Tid; - -pub struct Thread { - tid: Tid, -} - -unsafe impl Send for Thread {} -unsafe impl Sync for Thread {} - -pub const DEFAULT_MIN_STACK_SIZE: usize = 1 << 20; - -impl Thread { - pub unsafe fn new_with_coreid( - stack: usize, - p: Box<dyn FnOnce()>, - core_id: isize, - ) -> io::Result<Thread> { - let p = Box::into_raw(box p); - let tid = abi::spawn2( - thread_start, - p as usize, - abi::Priority::into(abi::NORMAL_PRIO), - stack, - core_id, - ); - - return if tid == 0 { - // The thread failed to start and as a result p was not consumed. Therefore, it is - // safe to reconstruct the box so that it gets deallocated. - drop(Box::from_raw(p)); - Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!")) - } else { - Ok(Thread { tid: tid }) - }; - - extern "C" fn thread_start(main: usize) { - unsafe { - // Finally, let's run some code. - Box::from_raw(main as *mut Box<dyn FnOnce()>)(); - - // run all destructors - run_dtors(); - } - } - } - - pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> { - Thread::new_with_coreid(stack, p, -1 /* = no specific core */) - } - - #[inline] - pub fn yield_now() { - unsafe { - abi::yield_now(); - } - } - - #[inline] - pub fn set_name(_name: &CStr) { - // nope - } - - #[inline] - pub fn sleep(dur: Duration) { - unsafe { - abi::usleep(dur.as_micros() as u64); - } - } - - pub fn join(self) { - unsafe { - let _ = abi::join(self.tid); - } - } - - #[inline] - pub fn id(&self) -> Tid { - self.tid - } - - #[inline] - pub fn into_id(self) -> Tid { - let id = self.tid; - mem::forget(self); - id - } -} - -pub mod guard { - pub type Guard = !; - pub unsafe fn current() -> Option<Guard> { - None - } - pub unsafe fn init() -> Option<Guard> { - None - } -} diff --git a/src/libstd/sys/hermit/thread_local_dtor.rs b/src/libstd/sys/hermit/thread_local_dtor.rs deleted file mode 100644 index 9b683fce157..00000000000 --- a/src/libstd/sys/hermit/thread_local_dtor.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![cfg(target_thread_local)] -#![unstable(feature = "thread_local_internals", issue = "none")] - -// Simplify dtor registration by using a list of destructors. -// The this solution works like the implementation of macOS and -// doesn't additional OS support - -use crate::cell::Cell; -use crate::ptr; - -#[thread_local] -static DTORS: Cell<*mut List> = Cell::new(ptr::null_mut()); - -type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>; - -pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { - if DTORS.get().is_null() { - let v: Box<List> = box Vec::new(); - DTORS.set(Box::into_raw(v)); - } - - let list: &mut List = &mut *DTORS.get(); - list.push((t, dtor)); -} - -// every thread call this function to run through all possible destructors -pub unsafe fn run_dtors() { - let mut ptr = DTORS.replace(ptr::null_mut()); - while !ptr.is_null() { - let list = Box::from_raw(ptr); - for (ptr, dtor) in list.into_iter() { - dtor(ptr); - } - ptr = DTORS.replace(ptr::null_mut()); - } -} diff --git a/src/libstd/sys/hermit/thread_local_key.rs b/src/libstd/sys/hermit/thread_local_key.rs deleted file mode 100644 index bf1b49eb83b..00000000000 --- a/src/libstd/sys/hermit/thread_local_key.rs +++ /dev/null @@ -1,26 +0,0 @@ -pub type Key = usize; - -#[inline] -pub unsafe fn create(_dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key { - panic!("should not be used on the hermit target"); -} - -#[inline] -pub unsafe fn set(_key: Key, _value: *mut u8) { - panic!("should not be used on the hermit target"); -} - -#[inline] -pub unsafe fn get(_key: Key) -> *mut u8 { - panic!("should not be used on the hermit target"); -} - -#[inline] -pub unsafe fn destroy(_key: Key) { - panic!("should not be used on the hermit target"); -} - -#[inline] -pub fn requires_synchronized_create() -> bool { - panic!("should not be used on the hermit target"); -} diff --git a/src/libstd/sys/hermit/time.rs b/src/libstd/sys/hermit/time.rs deleted file mode 100644 index c02de17c1fc..00000000000 --- a/src/libstd/sys/hermit/time.rs +++ /dev/null @@ -1,165 +0,0 @@ -#![allow(dead_code)] - -use crate::cmp::Ordering; -use crate::convert::TryInto; -use crate::sys::hermit::abi; -use crate::sys::hermit::abi::timespec; -use crate::sys::hermit::abi::{CLOCK_MONOTONIC, CLOCK_REALTIME, NSEC_PER_SEC}; -use crate::time::Duration; -use core::hash::{Hash, Hasher}; - -#[derive(Copy, Clone, Debug)] -struct Timespec { - t: timespec, -} - -impl Timespec { - const fn zero() -> Timespec { - Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } } - } - - fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> { - if self >= other { - Ok(if self.t.tv_nsec >= other.t.tv_nsec { - Duration::new( - (self.t.tv_sec - other.t.tv_sec) as u64, - (self.t.tv_nsec - other.t.tv_nsec) as u32, - ) - } else { - Duration::new( - (self.t.tv_sec - 1 - other.t.tv_sec) as u64, - self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32, - ) - }) - } else { - match other.sub_timespec(self) { - Ok(d) => Err(d), - Err(d) => Ok(d), - } - } - } - - fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> { - let mut secs = other - .as_secs() - .try_into() // <- target type would be `libc::time_t` - .ok() - .and_then(|secs| self.t.tv_sec.checked_add(secs))?; - - // 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: timespec { tv_sec: secs, tv_nsec: nsec as _ } }) - } - - fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> { - let mut secs = other - .as_secs() - .try_into() // <- target type would be `libc::time_t` - .ok() - .and_then(|secs| self.t.tv_sec.checked_sub(secs))?; - - // 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: timespec { tv_sec: secs, tv_nsec: nsec as _ } }) - } -} - -impl PartialEq for Timespec { - fn eq(&self, other: &Timespec) -> bool { - self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec - } -} - -impl Eq for Timespec {} - -impl PartialOrd for Timespec { - fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -impl Ord for Timespec { - fn cmp(&self, other: &Timespec) -> Ordering { - let me = (self.t.tv_sec, self.t.tv_nsec); - let other = (other.t.tv_sec, other.t.tv_nsec); - me.cmp(&other) - } -} - -impl Hash for Timespec { - fn hash<H: Hasher>(&self, state: &mut H) { - self.t.tv_sec.hash(state); - self.t.tv_nsec.hash(state); - } -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub struct Instant { - t: Timespec, -} - -impl Instant { - pub fn now() -> Instant { - let mut time: Timespec = Timespec::zero(); - let _ = unsafe { abi::clock_gettime(CLOCK_MONOTONIC, &mut time.t as *mut timespec) }; - - Instant { t: time } - } - - pub const fn zero() -> Instant { - Instant { t: Timespec::zero() } - } - - pub fn actually_monotonic() -> bool { - true - } - - pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> { - self.t.sub_timespec(&other.t).ok() - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> { - Some(Instant { t: self.t.checked_add_duration(other)? }) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> { - Some(Instant { t: self.t.checked_sub_duration(other)? }) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct SystemTime { - t: Timespec, -} - -pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() }; - -impl SystemTime { - pub fn now() -> SystemTime { - let mut time: Timespec = Timespec::zero(); - let _ = unsafe { abi::clock_gettime(CLOCK_REALTIME, &mut time.t as *mut timespec) }; - - SystemTime { t: time } - } - - pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { - self.t.sub_timespec(&other.t) - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { - Some(SystemTime { t: self.t.checked_add_duration(other)? }) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { - Some(SystemTime { t: self.t.checked_sub_duration(other)? }) - } -} |
