diff options
| author | Stefan Lankes <slankes@eonerc.rwth-aachen.de> | 2019-10-06 15:26:14 +0000 |
|---|---|---|
| committer | Stefan Lankes <slankes@eonerc.rwth-aachen.de> | 2019-10-06 15:26:14 +0000 |
| commit | c1e440a90f472468c8069ba6254b23c6feedc32e (patch) | |
| tree | 6e7920b36e0ecd63e8b7b1a6ec236ff5e86a5a01 /src/libstd/sys | |
| parent | 7870050796e5904a0fc85ecbe6fa6dde1cfe0c91 (diff) | |
| download | rust-c1e440a90f472468c8069ba6254b23c6feedc32e.tar.gz rust-c1e440a90f472468c8069ba6254b23c6feedc32e.zip | |
redesign of the interface to the unikernel HermitCore
- the old interface between HermitCore and the Rust Standard Library based on a small C library (newlib) - remove this interface and call directly the unikernel - remove the dependency to the HermitCore linker - use rust-lld as linker
Diffstat (limited to 'src/libstd/sys')
33 files changed, 2309 insertions, 30 deletions
diff --git a/src/libstd/sys/hermit/alloc.rs b/src/libstd/sys/hermit/alloc.rs new file mode 100644 index 00000000000..802a179fb67 --- /dev/null +++ b/src/libstd/sys/hermit/alloc.rs @@ -0,0 +1,40 @@ +use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::ptr; + +extern "C" { + fn sys_malloc(size: usize, align: usize) -> *mut u8; + fn sys_realloc(ptr: *mut u8, size: usize, align: usize, new_size: usize) -> *mut u8; + fn sys_free(ptr: *mut u8, size: usize, align: usize); +} + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +unsafe impl GlobalAlloc for System { + #[inline] + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + sys_malloc(layout.size(), layout.align()) + } + + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + let addr = sys_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) { + sys_free(ptr, layout.size(), layout.align()) + } + + #[inline] + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + sys_realloc(ptr, layout.size(), layout.align(), new_size) + } +} diff --git a/src/libstd/sys/hermit/args.rs b/src/libstd/sys/hermit/args.rs new file mode 100644 index 00000000000..5b1f3add51f --- /dev/null +++ b/src/libstd/sys/hermit/args.rs @@ -0,0 +1,82 @@ +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 crate::sys_common::os_str_bytes::*; + use crate::ptr; + use crate::ffi::{CStr, OsString}; + use crate::marker::PhantomData; + use super::Args; + + 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 new file mode 100644 index 00000000000..fa7783122c2 --- /dev/null +++ b/src/libstd/sys/hermit/cmath.rs @@ -0,0 +1,29 @@ +// These symbols are all defined in `compiler-builtins` +extern { + 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 new file mode 100644 index 00000000000..1cd97d95ad2 --- /dev/null +++ b/src/libstd/sys/hermit/condvar.rs @@ -0,0 +1,68 @@ +use crate::cmp; +use crate::sys::mutex::Mutex; +use crate::time::Duration; + +pub struct Condvar { + identifier: usize, +} + +extern "C" { + fn sys_notify(id: usize, count: i32) -> i32; + fn sys_add_queue(id: usize, timeout_ns: i64) -> i32; + fn sys_wait(id: usize) -> i32; + fn sys_destroy_queue(id: usize) -> i32; +} + +impl Condvar { + pub const fn new() -> Condvar { + Condvar { identifier: 0 } + } + + #[inline] + pub unsafe fn init(&mut self) { + // nothing to do + } + + pub unsafe fn notify_one(&self) { + let _ = sys_notify(self.id(), 1); + } + + #[inline] + pub unsafe fn notify_all(&self) { + let _ = sys_notify(self.id(), -1 /* =all */); + } + + pub unsafe fn wait(&self, mutex: &Mutex) { + // add current task to the wait queue + let _ = sys_add_queue(self.id(), -1 /* no timeout */); + mutex.unlock(); + let _ = sys_wait(self.id()); + mutex.lock(); + } + + pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { + let nanos = dur.as_nanos(); + let nanos = cmp::min(i64::max_value() as u128, nanos); + + // add current task to the wait queue + let _ = sys_add_queue(self.id(), nanos as i64); + + mutex.unlock(); + // If the return value is !0 then a timeout happened, so we return + // `false` as we weren't actually notified. + let ret = sys_wait(self.id()) == 0; + mutex.lock(); + + ret + } + + #[inline] + pub unsafe fn destroy(&self) { + let _ = sys_destroy_queue(self.id()); + } + + #[inline] + fn id(&self) -> usize { + &self.identifier as *const usize as usize + } +} diff --git a/src/libstd/sys/hermit/env.rs b/src/libstd/sys/hermit/env.rs new file mode 100644 index 00000000000..7a0fcb31ef2 --- /dev/null +++ b/src/libstd/sys/hermit/env.rs @@ -0,0 +1,9 @@ +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/fast_thread_local.rs b/src/libstd/sys/hermit/fast_thread_local.rs new file mode 100644 index 00000000000..05464787a05 --- /dev/null +++ b/src/libstd/sys/hermit/fast_thread_local.rs @@ -0,0 +1,4 @@ +#![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/hermit/fd.rs b/src/libstd/sys/hermit/fd.rs new file mode 100644 index 00000000000..cbc167a677f --- /dev/null +++ b/src/libstd/sys/hermit/fd.rs @@ -0,0 +1,87 @@ +#![unstable(reason = "not public", issue = "0", feature = "fd")] + +use crate::io::{self, Read, ErrorKind}; +use crate::mem; +use crate::sys::cvt; +use crate::sys_common::AsInner; + +extern { + fn sys_read(fd: i32, buf: *mut u8, len: usize) -> isize; + fn sys_write(fd: i32, buf: *const u8, len: usize) -> isize; + fn sys_close(fd: i32) -> i32; +} + +#[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 { sys_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 { sys_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 { sys_close(self.fd) }; + } +} diff --git a/src/libstd/sys/hermit/fs.rs b/src/libstd/sys/hermit/fs.rs new file mode 100644 index 00000000000..2cec93e3e5e --- /dev/null +++ b/src/libstd/sys/hermit/fs.rs @@ -0,0 +1,389 @@ +use crate::ffi::{OsString, CString, CStr}; +use crate::fmt; +use crate::io::{self, Error, ErrorKind}; +use crate::hash::{Hash, Hasher}; +use crate::io::{SeekFrom, IoSlice, IoSliceMut}; +use crate::path::{Path, PathBuf}; +use crate::sys::time::SystemTime; +use crate::sys::{unsupported, Void}; +use crate::sys::hermit::fd::FileDesc; +use crate::sys::cvt; +use crate::sys_common::os_str_bytes::OsStrExt; + +pub use crate::sys_common::fs::copy; +//pub use crate::sys_common::fs::remove_dir_all; + +extern { + fn sys_open(name: *const i8, flags: i32, mode: i32) -> i32; + fn sys_unlink(name: *const i8) -> i32; +} + +fn cstr(path: &Path) -> io::Result<CString> { + Ok(CString::new(path.as_os_str().as_bytes())?) +} +//const O_ACCMODE: i32 = 00000003; +const O_RDONLY: i32 = 00000000; +const O_WRONLY: i32 = 00000001; +const O_RDWR: i32 = 00000002; +const O_CREAT: i32 = 00000100; +const O_EXCL: i32 = 00000200; +const O_TRUNC: i32 = 00001000; +const O_APPEND: i32 = 00002000; + +#[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(sys_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) + } + + 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) + } + + 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(sys_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 new file mode 100644 index 00000000000..976e122463d --- /dev/null +++ b/src/libstd/sys/hermit/io.rs @@ -0,0 +1,46 @@ +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/hermit/memchr.rs b/src/libstd/sys/hermit/memchr.rs new file mode 100644 index 00000000000..9967482197e --- /dev/null +++ b/src/libstd/sys/hermit/memchr.rs @@ -0,0 +1 @@ +pub use core::slice::memchr::{memchr, memrchr}; diff --git a/src/libstd/sys/hermit/mod.rs b/src/libstd/sys/hermit/mod.rs new file mode 100644 index 00000000000..c413b3e5323 --- /dev/null +++ b/src/libstd/sys/hermit/mod.rs @@ -0,0 +1,148 @@ +//! 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::os::raw::c_char; +use crate::intrinsics; + +pub mod alloc; +pub mod args; +pub mod condvar; +pub mod stdio; +pub mod memchr; +pub mod io; +pub mod mutex; +pub mod rwlock; +pub mod os; +pub mod cmath; +pub mod thread; +pub mod env; +pub mod fs; +pub mod fd; +pub mod net; +pub mod path; +pub mod pipe; +pub mod process; +pub mod stack_overflow; +pub mod time; +pub mod thread_local; +pub mod fast_thread_local; + +pub use crate::sys_common::os_str_bytes as os_str; +use crate::io::ErrorKind; + +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 unsafe fn abort_internal() -> ! { + extern "C" { + fn sys_abort() ->!; + } + + sys_abort(); +} + +// TODO: 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 unsafe extern "C" fn __rust_abort() { + abort_internal(); +} + +#[cfg(not(test))] +pub fn init() { + unsafe { + 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) -> ! { + extern "C" { + fn main(argc: isize, argv: *const *const c_char) -> i32; + fn sys_exit(arg: i32) ->!; + } + + // initialize environment + os::init_environment(env as *const *const i8); + + let result = main(argc as isize, argv); + + sys_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 new file mode 100644 index 00000000000..f119c66a6dc --- /dev/null +++ b/src/libstd/sys/hermit/mutex.rs @@ -0,0 +1,88 @@ +use crate::ptr; +use crate::ffi::c_void; + +extern "C" { + fn sys_sem_init(sem: *mut *const c_void, value: u32) -> i32; + fn sys_sem_destroy(sem: *const c_void) -> i32; + fn sys_sem_post(sem: *const c_void) -> i32; + fn sys_sem_trywait(sem: *const c_void) -> i32; + fn sys_sem_timedwait(sem: *const c_void, ms: u32) -> i32; + fn sys_recmutex_init(recmutex: *mut *const c_void) -> i32; + fn sys_recmutex_destroy(recmutex: *const c_void) -> i32; + fn sys_recmutex_lock(recmutex: *const c_void) -> i32; + fn sys_recmutex_unlock(recmutex: *const c_void) -> i32; +} + +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 _ = sys_sem_init(&mut self.inner as *mut *const c_void, 1); + } + + #[inline] + pub unsafe fn lock(&self) { + let _ = sys_sem_timedwait(self.inner, 0); + } + + #[inline] + pub unsafe fn unlock(&self) { + let _ = sys_sem_post(self.inner); + } + + #[inline] + pub unsafe fn try_lock(&self) -> bool { + let result = sys_sem_trywait(self.inner); + result == 0 + } + + #[inline] + pub unsafe fn destroy(&self) { + let _ = sys_sem_destroy(self.inner); + } +} + +pub struct ReentrantMutex { + inner: *const c_void +} + +impl ReentrantMutex { + pub unsafe fn uninitialized() -> ReentrantMutex { + ReentrantMutex { inner: ptr::null() } + } + + #[inline] + pub unsafe fn init(&mut self) { + let _ = sys_recmutex_init(&mut self.inner as *mut *const c_void); + } + + #[inline] + pub unsafe fn lock(&self) { + let _ = sys_recmutex_lock(self.inner); + } + + #[inline] + pub unsafe fn try_lock(&self) -> bool { + true + } + + #[inline] + pub unsafe fn unlock(&self) { + let _ = sys_recmutex_unlock(self.inner); + } + + #[inline] + pub unsafe fn destroy(&self) { + let _ = sys_recmutex_destroy(self.inner); + } +} diff --git a/src/libstd/sys/hermit/net.rs b/src/libstd/sys/hermit/net.rs new file mode 100644 index 00000000000..5b7ff642271 --- /dev/null +++ b/src/libstd/sys/hermit/net.rs @@ -0,0 +1,364 @@ +use crate::fmt; +use crate::convert::TryFrom; +use crate::io::{self, IoSlice, IoSliceMut}; +use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr}; +use crate::str; +use crate::sys::{unsupported, Void}; +use crate::time::Duration; + +//// Iinitializes HermitCore's network stack +pub unsafe fn init() -> io::Result<()> { + Ok(()) +} + +pub struct TcpStream(Void); + +impl TcpStream { + pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> { + unsupported() + } + + pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> { + unsupported() + } + + pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { + match self.0 {} + } + + pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { + match self.0 {} + } + + pub fn read_timeout(&self) -> io::Result<Option<Duration>> { + match self.0 {} + } + + pub fn write_timeout(&self) -> io::Result<Option<Duration>> { + match self.0 {} + } + + pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { + match self.0 {} + } + + pub fn read(&self, _: &mut [u8]) -> io::Result<usize> { + match self.0 {} + } + + pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> { + match self.0 {} + } + + pub fn write(&self, _: &[u8]) -> io::Result<usize> { + match self.0 {} + } + + pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> { + match self.0 {} + } + + pub fn peer_addr(&self) -> io::Result<SocketAddr> { + match self.0 {} + } + + pub fn socket_addr(&self) -> io::Result<SocketAddr> { + match self.0 {} + } + + pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { + match self.0 {} + } + + pub fn duplicate(&self) -> io::Result<TcpStream> { + match self.0 {} + } + + pub fn set_nodelay(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn nodelay(&self) -> io::Result<bool> { + match self.0 {} + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + match self.0 {} + } + + pub fn ttl(&self) -> io::Result<u32> { + match self.0 {} + } + + pub fn take_error(&self) -> io::Result<Option<io::Error>> { + match self.0 {} + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + match self.0 {} + } +} + +impl fmt::Debug for TcpStream { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.0 {} + } +} + +pub struct TcpListener(Void); + +impl TcpListener { + pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> { + unsupported() + } + + pub fn socket_addr(&self) -> io::Result<SocketAddr> { + match self.0 {} + } + + pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { + match self.0 {} + } + + pub fn duplicate(&self) -> io::Result<TcpListener> { + match self.0 {} + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + match self.0 {} + } + + pub fn ttl(&self) -> io::Result<u32> { + match self.0 {} + } + + pub fn set_only_v6(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn only_v6(&self) -> io::Result<bool> { + match self.0 {} + } + + pub fn take_error(&self) -> io::Result<Option<io::Error>> { + match self.0 {} + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + match self.0 {} + } +} + +impl fmt::Debug for TcpListener { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.0 {} + } +} + +pub struct UdpSocket(Void); + +impl UdpSocket { + pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { + unsupported() + } + + pub fn peer_addr(&self) -> io::Result<SocketAddr> { + match self.0 {} + } + + pub fn socket_addr(&self) -> io::Result<SocketAddr> { + match self.0 {} + } + + pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + match self.0 {} + } + + pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + match self.0 {} + } + + pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> { + match self.0 {} + } + + pub fn duplicate(&self) -> io::Result<UdpSocket> { + match self.0 {} + } + + pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { + match self.0 {} + } + + pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { + match self.0 {} + } + + pub fn read_timeout(&self) -> io::Result<Option<Duration>> { + match self.0 {} + } + + pub fn write_timeout(&self) -> io::Result<Option<Duration>> { + match self.0 {} + } + + pub fn set_broadcast(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn broadcast(&self) -> io::Result<bool> { + match self.0 {} + } + + pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn multicast_loop_v4(&self) -> io::Result<bool> { + match self.0 {} + } + + pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { + match self.0 {} + } + + pub fn multicast_ttl_v4(&self) -> io::Result<u32> { + match self.0 {} + } + + pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn multicast_loop_v6(&self) -> io::Result<bool> { + match self.0 {} + } + + pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) + -> io::Result<()> { + match self.0 {} + } + + pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) + -> io::Result<()> { + match self.0 {} + } + + pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) + -> io::Result<()> { + match self.0 {} + } + + pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) + -> io::Result<()> { + match self.0 {} + } + + pub fn set_ttl(&self, _: u32) -> io::Result<()> { + match self.0 {} + } + + pub fn ttl(&self) -> io::Result<u32> { + match self.0 {} + } + + pub fn take_error(&self) -> io::Result<Option<io::Error>> { + match self.0 {} + } + + pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { + match self.0 {} + } + + pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> { + match self.0 {} + } + + pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { + match self.0 {} + } + + pub fn send(&self, _: &[u8]) -> io::Result<usize> { + match self.0 {} + } + + pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { + match self.0 {} + } +} + +impl fmt::Debug for UdpSocket { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.0 {} + } +} + +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 new file mode 100644 index 00000000000..cdac1c74dcb --- /dev/null +++ b/src/libstd/sys/hermit/os.rs @@ -0,0 +1,178 @@ +use crate::error::Error as StdError; +use crate::ffi::{CStr, OsString, OsStr}; +use crate::fmt; +use crate::io; +use crate::marker::PhantomData; +use crate::memchr; +use crate::path::{self, PathBuf}; +use crate::ptr; +use crate::str; +use crate::sys::{unsupported, Void}; +use crate::collections::HashMap; +use crate::vec; +use crate::sync::Mutex; +use crate::sys_common::os_str_bytes::*; + +extern "C" { + fn sys_getpid() -> u32; + fn sys_exit(arg: i32) ->!; +} + +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 { + 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())); + + let mut guard = ENV.as_ref().unwrap().lock().unwrap(); + let mut environ = env; + while environ != ptr::null() && *environ != ptr::null() { + if let Some((key,value)) = parse(CStr::from_ptr(*environ).to_bytes()) { + guard.insert(key, value); + } + environ = environ.offset(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 { + sys_exit(code); + } +} + +pub fn getpid() -> u32 { + unsafe { + sys_getpid() + } +} diff --git a/src/libstd/sys/hermit/path.rs b/src/libstd/sys/hermit/path.rs new file mode 100644 index 00000000000..7a183956107 --- /dev/null +++ b/src/libstd/sys/hermit/path.rs @@ -0,0 +1,19 @@ +use crate::path::Prefix; +use crate::ffi::OsStr; + +#[inline] +pub fn is_sep_byte(b: u8) -> bool { + b == b'/' +} + +#[inline] +pub fn is_verbatim_sep(b: u8) -> bool { + b == b'/' +} + +pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> { + None +} + +pub const MAIN_SEP_STR: &str = "/"; +pub const MAIN_SEP: char = '/'; diff --git a/src/libstd/sys/hermit/pipe.rs b/src/libstd/sys/hermit/pipe.rs new file mode 100644 index 00000000000..9f07f054362 --- /dev/null +++ b/src/libstd/sys/hermit/pipe.rs @@ -0,0 +1,33 @@ +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 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 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 new file mode 100644 index 00000000000..edf933d10e0 --- /dev/null +++ b/src/libstd/sys/hermit/process.rs @@ -0,0 +1,154 @@ +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 new file mode 100644 index 00000000000..990e7551114 --- /dev/null +++ b/src/libstd/sys/hermit/rwlock.rs @@ -0,0 +1,51 @@ +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/hermit/stack_overflow.rs b/src/libstd/sys/hermit/stack_overflow.rs new file mode 100644 index 00000000000..b339e433e77 --- /dev/null +++ b/src/libstd/sys/hermit/stack_overflow.rs @@ -0,0 +1,15 @@ +pub struct Handler; + +impl Handler { + pub unsafe fn new() -> Handler { + Handler + } +} + +#[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 new file mode 100644 index 00000000000..07be3b6fdd3 --- /dev/null +++ b/src/libstd/sys/hermit/stdio.rs @@ -0,0 +1,122 @@ +use crate::io; +use crate::io::{IoSlice, IoSliceMut}; + +extern "C" { + fn sys_write(fd: i32, buf: *const u8, len: usize) -> isize; +} + +pub struct Stdin; +pub struct Stdout; +pub struct Stderr; + +impl Stdin { + pub fn new() -> io::Result<Stdin> { + Ok(Stdin) + } + + pub fn read(&self, data: &mut [u8]) -> io::Result<usize> { + self.read_vectored(&mut [IoSliceMut::new(data)]) + } + + pub fn read_vectored(&self, _data: &mut [IoSliceMut<'_>]) -> io::Result<usize> { + //ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) }) + // .read(data) + Ok(0) + } + +} + +impl Stdout { + pub fn new() -> io::Result<Stdout> { + Ok(Stdout) + } + + pub fn write(&self, data: &[u8]) -> io::Result<usize> { + let len; + + unsafe { + len = sys_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) + } + } + + pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> { + let len; + + unsafe { + len = sys_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) + } + } + + pub fn flush(&self) -> io::Result<()> { + Ok(()) + } +} + +impl Stderr { + pub fn new() -> io::Result<Stderr> { + Ok(Stderr) + } + + pub fn write(&self, data: &[u8]) -> io::Result<usize> { + let len; + + unsafe { + len = sys_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) + } + } + + pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> { + let len; + + unsafe { + len = sys_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) + } + } + + pub fn flush(&self) -> io::Result<()> { + Ok(()) + } +} + +impl io::Write for Stderr { + fn write(&mut self, data: &[u8]) -> io::Result<usize> { + (&*self).write(data) + } + fn flush(&mut self) -> io::Result<()> { + (&*self).flush() + } +} + +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 new file mode 100644 index 00000000000..cb5ed2963b1 --- /dev/null +++ b/src/libstd/sys/hermit/thread.rs @@ -0,0 +1,121 @@ +#![allow(dead_code)] + +use crate::ffi::CStr; +use crate::io; +use crate::time::Duration; +use crate::mem; +use crate::fmt; +use core::u32; + +use crate::sys_common::thread::*; + +pub type Tid = u32; + +/// Priority of a task +#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)] +pub struct Priority(u8); + +impl Priority { + pub const fn into(self) -> u8 { + self.0 + } + + pub const fn from(x: u8) -> Self { + Priority(x) + } +} + +impl fmt::Display for Priority { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +pub const NORMAL_PRIO: Priority = Priority::from(2); + +extern "C" { + fn sys_usleep(usecs: u64); + fn sys_spawn(id: *mut Tid, func: extern "C" fn(usize), arg: usize, prio: u8, core_id: isize) -> i32; + fn sys_join(id: Tid) -> i32; + fn sys_yield(); +} + +pub struct Thread { + tid: Tid +} + +unsafe impl Send for Thread {} +unsafe impl Sync for Thread {} + +pub const DEFAULT_MIN_STACK_SIZE: usize = 262144; + +impl Thread { + pub unsafe fn new_with_coreid(_stack: usize, p: Box<dyn FnOnce()>, core_id: isize) + -> io::Result<Thread> + { + let p = box p; + let mut tid: Tid = u32::MAX; + let ret = sys_spawn(&mut tid as *mut Tid, thread_start, &*p as *const _ as *const u8 as usize, + Priority::into(NORMAL_PRIO), core_id); + + return if ret == 0 { + mem::forget(p); // ownership passed to pthread_create + Ok(Thread { tid: tid }) + } else { + Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!")) + }; + + extern fn thread_start(main: usize) { + unsafe { + start_thread(main as *mut u8); + } + } + } + + 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 { + sys_yield(); + } + } + + #[inline] + pub fn set_name(_name: &CStr) { + // nope + } + + #[inline] + pub fn sleep(dur: Duration) { + unsafe { + sys_usleep(dur.as_micros() as u64); + } + } + + pub fn join(self) { + unsafe { + let _ = sys_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.rs b/src/libstd/sys/hermit/thread_local.rs new file mode 100644 index 00000000000..4bc8c4d5883 --- /dev/null +++ b/src/libstd/sys/hermit/thread_local.rs @@ -0,0 +1,61 @@ +#![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<Key, Option<Dtor>> = ptr::null_mut(); + +#[thread_local] +static mut LOCALS: *mut BTreeMap<Key, *mut u8> = ptr::null_mut(); + +unsafe fn keys() -> &'static mut BTreeMap<Key, Option<Dtor>> { + if KEYS == ptr::null_mut() { + KEYS = Box::into_raw(Box::new(BTreeMap::new())); + } + &mut *KEYS +} + +unsafe fn locals() -> &'static mut BTreeMap<Key, *mut u8> { + if LOCALS == ptr::null_mut() { + LOCALS = Box::into_raw(Box::new(BTreeMap::new())); + } + &mut *LOCALS +} + +#[inline] +pub unsafe fn create(dtor: Option<Dtor>) -> 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/hermit/time.rs b/src/libstd/sys/hermit/time.rs new file mode 100644 index 00000000000..2c8aafef0fe --- /dev/null +++ b/src/libstd/sys/hermit/time.rs @@ -0,0 +1,188 @@ +#![allow(dead_code)] + +use crate::time::Duration; +use crate::cmp::Ordering; +use crate::convert::TryInto; +use core::hash::{Hash, Hasher}; + +const NSEC_PER_SEC: u64 = 1_000_000_000; +const CLOCK_REALTIME: u64 = 1; +const CLOCK_MONOTONIC: u64 = 4; + +extern "C" { + fn sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32; +} + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct timespec { + pub tv_sec: i64, + pub tv_nsec: i64, +} + +#[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 { sys_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 { sys_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)? }) + } +} diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index 5a5859a6ad8..16b0539cdb9 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -35,6 +35,9 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "cloudabi")] { mod cloudabi; pub use self::cloudabi::*; + } else if #[cfg(target_os = "hermit")] { + mod hermit; + pub use self::hermit::*; } else if #[cfg(target_os = "wasi")] { mod wasi; pub use self::wasi::*; @@ -60,6 +63,7 @@ cfg_if::cfg_if! { #[stable(feature = "rust1", since = "1.0.0")] pub use self::ext as unix_ext; } else if #[cfg(any(target_os = "cloudabi", + target_os = "hermit", target_arch = "wasm32", all(target_vendor = "fortanix", target_env = "sgx")))] { // On CloudABI and wasm right now the module below doesn't compile diff --git a/src/libstd/sys/unix/alloc.rs b/src/libstd/sys/unix/alloc.rs index f47dc92d2de..cf4900b4894 100644 --- a/src/libstd/sys/unix/alloc.rs +++ b/src/libstd/sys/unix/alloc.rs @@ -53,7 +53,6 @@ unsafe impl GlobalAlloc for System { } #[cfg(any(target_os = "android", - target_os = "hermit", target_os = "redox", target_os = "solaris"))] #[inline] @@ -79,7 +78,6 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { } #[cfg(not(any(target_os = "android", - target_os = "hermit", target_os = "redox", target_os = "solaris")))] #[inline] diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 288e9b5c126..82ef35ea7b5 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -56,7 +56,6 @@ impl DoubleEndedIterator for Args { target_os = "haiku", target_os = "l4re", target_os = "fuchsia", - target_os = "hermit", target_os = "redox"))] mod imp { use crate::os::unix::prelude::*; diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index 0a93fbf8ea7..6be844ded19 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -31,7 +31,6 @@ impl Condvar { target_os = "ios", target_os = "l4re", target_os = "android", - target_os = "hermit", target_os = "redox"))] pub unsafe fn init(&mut self) {} @@ -39,7 +38,6 @@ impl Condvar { target_os = "ios", target_os = "l4re", target_os = "android", - target_os = "hermit", target_os = "redox")))] pub unsafe fn init(&mut self) { use crate::mem::MaybeUninit; @@ -78,8 +76,7 @@ impl Condvar { // from changes made to the system time. #[cfg(not(any(target_os = "macos", target_os = "ios", - target_os = "android", - target_os = "hermit")))] + target_os = "android")))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { use crate::mem; @@ -109,7 +106,7 @@ impl Condvar { // This implementation is modeled after libcxx's condition_variable // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46 // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367 - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android", target_os = "hermit"))] + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool { use crate::ptr; use crate::time::Instant; diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs index d724eeb8b3f..984bcfa4509 100644 --- a/src/libstd/sys/unix/env.rs +++ b/src/libstd/sys/unix/env.rs @@ -152,17 +152,6 @@ pub mod os { pub const EXE_EXTENSION: &str = ""; } -#[cfg(target_os = "hermit")] -pub mod os { - pub const FAMILY: &str = "unix"; - pub const OS: &str = "hermit"; - 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 = ""; -} - #[cfg(target_os = "redox")] pub mod os { pub const FAMILY: &str = "unix"; diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 3b1eb86b84f..c2064fca23e 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -319,12 +319,12 @@ impl DirEntry { lstat(&self.path()) } - #[cfg(any(target_os = "solaris", target_os = "haiku", target_os = "hermit"))] + #[cfg(any(target_os = "solaris", target_os = "haiku"))] pub fn file_type(&self) -> io::Result<FileType> { lstat(&self.path()).map(|m| m.file_type()) } - #[cfg(not(any(target_os = "solaris", target_os = "haiku", target_os = "hermit")))] + #[cfg(not(any(target_os = "solaris", target_os = "haiku")))] pub fn file_type(&self) -> io::Result<FileType> { match self.entry.d_type { libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }), @@ -347,7 +347,6 @@ impl DirEntry { target_os = "haiku", target_os = "l4re", target_os = "fuchsia", - target_os = "hermit", target_os = "redox"))] pub fn ino(&self) -> u64 { self.entry.d_ino as u64 @@ -378,8 +377,7 @@ impl DirEntry { target_os = "linux", target_os = "emscripten", target_os = "l4re", - target_os = "haiku", - target_os = "hermit"))] + target_os = "haiku"))] fn name_bytes(&self) -> &[u8] { unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index b1f7aac8b4b..d0bed0f038e 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -16,7 +16,6 @@ use crate::io::ErrorKind; #[cfg(all(not(rustdoc), target_os = "emscripten"))] pub use crate::os::emscripten as platform; #[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; diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 169bb57ef78..10cdb25999c 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -43,7 +43,6 @@ extern { #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "android", - target_os = "hermit", target_os = "redox", target_env = "newlib"), link_name = "__errno")] @@ -394,7 +393,7 @@ pub fn current_exe() -> io::Result<PathBuf> { crate::fs::read_to_string("sys:exe").map(PathBuf::from) } -#[cfg(any(target_os = "fuchsia", target_os = "l4re", target_os = "hermit"))] +#[cfg(any(target_os = "fuchsia", target_os = "l4re"))] pub fn current_exe() -> io::Result<PathBuf> { use crate::io::ErrorKind; Err(io::Error::new(ErrorKind::Other, "Not yet implemented!")) diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 988881e3596..72b0ac493da 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -140,7 +140,6 @@ impl Thread { target_os = "haiku", target_os = "l4re", target_os = "emscripten", - 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/unix/time.rs b/src/libstd/sys/unix/time.rs index fd6796ad22c..a9122defa55 100644 --- a/src/libstd/sys/unix/time.rs +++ b/src/libstd/sys/unix/time.rs @@ -371,9 +371,9 @@ mod inner { } } - #[cfg(not(any(target_os = "dragonfly", target_os = "hermit")))] + #[cfg(not(target_os = "dragonfly"))] pub type clock_t = libc::c_int; - #[cfg(any(target_os = "dragonfly", target_os = "hermit"))] + #[cfg(target_os = "dragonfly")] pub type clock_t = libc::c_ulong; fn now(clock: clock_t) -> Timespec { |
