add HermitOS support of vectored read/write operations
In general, the I/O interface of hermit-abi is more POSIX-like interface. Consequently, platform abstraction layer for HermitOS has slightly adjusted and some inaccuracies remove.
This commit is contained in:
parent
e3c3ce62d7
commit
1f125a6716
10
Cargo.lock
10
Cargo.lock
@ -1694,6 +1694,12 @@ name = "hermit-abi"
|
|||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"rustc-std-workspace-alloc",
|
"rustc-std-workspace-alloc",
|
||||||
@ -2636,7 +2642,7 @@ version = "1.16.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi 0.3.9",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -5363,7 +5369,7 @@ dependencies = [
|
|||||||
"dlmalloc",
|
"dlmalloc",
|
||||||
"fortanix-sgx-abi",
|
"fortanix-sgx-abi",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"hermit-abi",
|
"hermit-abi 0.4.0",
|
||||||
"libc",
|
"libc",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
"object 0.36.0",
|
"object 0.36.0",
|
||||||
|
@ -50,7 +50,7 @@ dlmalloc = { version = "0.2.4", features = ['rustc-dep-of-std'] }
|
|||||||
fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'], public = true }
|
fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'], public = true }
|
||||||
|
|
||||||
[target.'cfg(target_os = "hermit")'.dependencies]
|
[target.'cfg(target_os = "hermit")'.dependencies]
|
||||||
hermit-abi = { version = "0.3.9", features = ['rustc-dep-of-std'], public = true }
|
hermit-abi = { version = "0.4.0", features = ['rustc-dep-of-std'], public = true }
|
||||||
|
|
||||||
[target.'cfg(target_os = "wasi")'.dependencies]
|
[target.'cfg(target_os = "wasi")'.dependencies]
|
||||||
wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
|
wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#![unstable(reason = "not public", issue = "none", feature = "fd")]
|
#![unstable(reason = "not public", issue = "none", feature = "fd")]
|
||||||
|
|
||||||
use super::hermit_abi;
|
use super::hermit_abi;
|
||||||
use crate::io::{self, Read};
|
use crate::cmp;
|
||||||
|
use crate::io::{self, IoSlice, IoSliceMut, Read};
|
||||||
use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd};
|
use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd};
|
||||||
use crate::sys::cvt;
|
use crate::sys::cvt;
|
||||||
use crate::sys::unsupported;
|
use crate::sys::unsupported;
|
||||||
@ -9,6 +10,10 @@
|
|||||||
|
|
||||||
use crate::os::hermit::io::*;
|
use crate::os::hermit::io::*;
|
||||||
|
|
||||||
|
const fn max_iov() -> usize {
|
||||||
|
hermit_abi::IOV_MAX
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FileDesc {
|
pub struct FileDesc {
|
||||||
fd: OwnedFd,
|
fd: OwnedFd,
|
||||||
@ -21,6 +26,22 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|||||||
Ok(result as usize)
|
Ok(result as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||||
|
let ret = cvt(unsafe {
|
||||||
|
hermit_abi::readv(
|
||||||
|
self.as_raw_fd(),
|
||||||
|
bufs.as_mut_ptr() as *mut hermit_abi::iovec as *const hermit_abi::iovec,
|
||||||
|
cmp::min(bufs.len(), max_iov()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok(ret as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_read_vectored(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||||
let mut me = self;
|
let mut me = self;
|
||||||
(&mut me).read_to_end(buf)
|
(&mut me).read_to_end(buf)
|
||||||
@ -32,6 +53,22 @@ pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
|||||||
Ok(result as usize)
|
Ok(result as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||||
|
let ret = cvt(unsafe {
|
||||||
|
hermit_abi::writev(
|
||||||
|
self.as_raw_fd(),
|
||||||
|
bufs.as_ptr() as *const hermit_abi::iovec,
|
||||||
|
cmp::min(bufs.len(), max_iov()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok(ret as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_write_vectored(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
pub fn duplicate(&self) -> io::Result<FileDesc> {
|
pub fn duplicate(&self) -> io::Result<FileDesc> {
|
||||||
self.duplicate_path(&[])
|
self.duplicate_path(&[])
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::fd::FileDesc;
|
use super::fd::FileDesc;
|
||||||
use super::hermit_abi::{
|
use super::hermit_abi::{
|
||||||
self, dirent64, stat as stat_struct, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT,
|
self, dirent64, stat as stat_struct, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT,
|
||||||
O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
|
O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
|
||||||
};
|
};
|
||||||
use crate::ffi::{CStr, OsStr, OsString};
|
use crate::ffi::{CStr, OsStr, OsString};
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
@ -62,7 +62,7 @@ pub struct DirEntry {
|
|||||||
/// 64-bit inode number
|
/// 64-bit inode number
|
||||||
ino: u64,
|
ino: u64,
|
||||||
/// File type
|
/// File type
|
||||||
type_: u32,
|
type_: u8,
|
||||||
/// name of the entry
|
/// name of the entry
|
||||||
name: OsString,
|
name: OsString,
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ pub struct FilePermissions {
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Eq, Debug)]
|
#[derive(Copy, Clone, Eq, Debug)]
|
||||||
pub struct FileType {
|
pub struct FileType {
|
||||||
mode: u32,
|
mode: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for FileType {
|
impl PartialEq for FileType {
|
||||||
@ -112,31 +112,23 @@ pub struct DirBuilder {
|
|||||||
|
|
||||||
impl FileAttr {
|
impl FileAttr {
|
||||||
pub fn modified(&self) -> io::Result<SystemTime> {
|
pub fn modified(&self) -> io::Result<SystemTime> {
|
||||||
Ok(SystemTime::new(
|
Ok(SystemTime::new(self.stat_val.st_mtim.tv_sec, self.stat_val.st_mtim.tv_nsec))
|
||||||
self.stat_val.st_mtime.try_into().unwrap(),
|
|
||||||
self.stat_val.st_mtime_nsec.try_into().unwrap(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accessed(&self) -> io::Result<SystemTime> {
|
pub fn accessed(&self) -> io::Result<SystemTime> {
|
||||||
Ok(SystemTime::new(
|
Ok(SystemTime::new(self.stat_val.st_atim.tv_sec, self.stat_val.st_atim.tv_nsec))
|
||||||
self.stat_val.st_atime.try_into().unwrap(),
|
|
||||||
self.stat_val.st_atime_nsec.try_into().unwrap(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn created(&self) -> io::Result<SystemTime> {
|
pub fn created(&self) -> io::Result<SystemTime> {
|
||||||
Ok(SystemTime::new(
|
Ok(SystemTime::new(self.stat_val.st_ctim.tv_sec, self.stat_val.st_ctim.tv_nsec))
|
||||||
self.stat_val.st_ctime.try_into().unwrap(),
|
|
||||||
self.stat_val.st_ctime_nsec.try_into().unwrap(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size(&self) -> u64 {
|
pub fn size(&self) -> u64 {
|
||||||
self.stat_val.st_size as u64
|
self.stat_val.st_size as u64
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perm(&self) -> FilePermissions {
|
pub fn perm(&self) -> FilePermissions {
|
||||||
FilePermissions { mode: (self.stat_val.st_mode) }
|
FilePermissions { mode: self.stat_val.st_mode }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_type(&self) -> FileType {
|
pub fn file_type(&self) -> FileType {
|
||||||
@ -220,7 +212,7 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
|
|||||||
let entry = DirEntry {
|
let entry = DirEntry {
|
||||||
root: self.inner.root.clone(),
|
root: self.inner.root.clone(),
|
||||||
ino: dir.d_ino,
|
ino: dir.d_ino,
|
||||||
type_: dir.d_type as u32,
|
type_: dir.d_type,
|
||||||
name: OsString::from_vec(name_bytes.to_vec()),
|
name: OsString::from_vec(name_bytes.to_vec()),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -251,7 +243,7 @@ pub fn metadata(&self) -> io::Result<FileAttr> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_type(&self) -> io::Result<FileType> {
|
pub fn file_type(&self) -> io::Result<FileType> {
|
||||||
Ok(FileType { mode: self.type_ as u32 })
|
Ok(FileType { mode: self.type_ })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -385,12 +377,12 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||||
crate::io::default_read_vectored(|buf| self.read(buf), bufs)
|
self.0.read_vectored(bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_read_vectored(&self) -> bool {
|
pub fn is_read_vectored(&self) -> bool {
|
||||||
false
|
self.0.is_read_vectored()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
|
pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
|
||||||
@ -402,12 +394,12 @@ pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||||
crate::io::default_write_vectored(|buf| self.write(buf), bufs)
|
self.0.write_vectored(bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_write_vectored(&self) -> bool {
|
pub fn is_write_vectored(&self) -> bool {
|
||||||
false
|
self.0.is_write_vectored()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -439,13 +431,13 @@ pub fn new() -> DirBuilder {
|
|||||||
|
|
||||||
pub fn mkdir(&self, path: &Path) -> io::Result<()> {
|
pub fn mkdir(&self, path: &Path) -> io::Result<()> {
|
||||||
run_path_with_cstr(path, &|path| {
|
run_path_with_cstr(path, &|path| {
|
||||||
cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode) }).map(|_| ())
|
cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode.into()) }).map(|_| ())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn set_mode(&mut self, mode: u32) {
|
pub fn set_mode(&mut self, mode: u32) {
|
||||||
self.mode = mode as u32;
|
self.mode = mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,8 +493,9 @@ unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn readdir(path: &Path) -> io::Result<ReadDir> {
|
pub fn readdir(path: &Path) -> io::Result<ReadDir> {
|
||||||
let fd_raw =
|
let fd_raw = run_path_with_cstr(path, &|path| {
|
||||||
run_path_with_cstr(path, &|path| cvt(unsafe { hermit_abi::opendir(path.as_ptr()) }))?;
|
cvt(unsafe { hermit_abi::open(path.as_ptr(), O_RDONLY | O_DIRECTORY, 0) })
|
||||||
|
})?;
|
||||||
let fd = unsafe { FileDesc::from_raw_fd(fd_raw as i32) };
|
let fd = unsafe { FileDesc::from_raw_fd(fd_raw as i32) };
|
||||||
let root = path.to_path_buf();
|
let root = path.to_path_buf();
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
|
|||||||
let timespec = timeout.and_then(|dur| {
|
let timespec = timeout.and_then(|dur| {
|
||||||
Some(hermit_abi::timespec {
|
Some(hermit_abi::timespec {
|
||||||
tv_sec: dur.as_secs().try_into().ok()?,
|
tv_sec: dur.as_secs().try_into().ok()?,
|
||||||
tv_nsec: dur.subsec_nanos().into(),
|
tv_nsec: dur.subsec_nanos().try_into().ok()?,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
82
library/std/src/sys/pal/hermit/io.rs
Normal file
82
library/std/src/sys/pal/hermit/io.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
use crate::marker::PhantomData;
|
||||||
|
use crate::os::hermit::io::{AsFd, AsRawFd};
|
||||||
|
use crate::slice;
|
||||||
|
|
||||||
|
use hermit_abi::{c_void, iovec};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct IoSlice<'a> {
|
||||||
|
vec: iovec,
|
||||||
|
_p: PhantomData<&'a [u8]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> IoSlice<'a> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
|
||||||
|
IoSlice {
|
||||||
|
vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
|
||||||
|
_p: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn advance(&mut self, n: usize) {
|
||||||
|
if self.vec.iov_len < n {
|
||||||
|
panic!("advancing IoSlice beyond its length");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
self.vec.iov_len -= n;
|
||||||
|
self.vec.iov_base = self.vec.iov_base.add(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
|
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct IoSliceMut<'a> {
|
||||||
|
vec: iovec,
|
||||||
|
_p: PhantomData<&'a mut [u8]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> IoSliceMut<'a> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
||||||
|
IoSliceMut {
|
||||||
|
vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
|
||||||
|
_p: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn advance(&mut self, n: usize) {
|
||||||
|
if self.vec.iov_len < n {
|
||||||
|
panic!("advancing IoSliceMut beyond its length");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
self.vec.iov_len -= n;
|
||||||
|
self.vec.iov_base = self.vec.iov_base.add(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
|
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||||
|
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_terminal(fd: &impl AsFd) -> bool {
|
||||||
|
let fd = fd.as_fd();
|
||||||
|
hermit_abi::isatty(fd.as_raw_fd())
|
||||||
|
}
|
@ -23,7 +23,6 @@
|
|||||||
pub mod fd;
|
pub mod fd;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod futex;
|
pub mod futex;
|
||||||
#[path = "../unsupported/io.rs"]
|
|
||||||
pub mod io;
|
pub mod io;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
pub mod os;
|
pub mod os;
|
||||||
|
@ -175,12 +175,12 @@ pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||||
crate::io::default_read_vectored(|b| self.read(b), bufs)
|
self.0.read_vectored(bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_read_vectored(&self) -> bool {
|
pub fn is_read_vectored(&self) -> bool {
|
||||||
false
|
self.0.is_read_vectored()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> {
|
fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> {
|
||||||
@ -209,16 +209,15 @@ pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
let sz = cvt(unsafe { netc::write(self.0.as_raw_fd(), buf.as_ptr(), buf.len()) })?;
|
self.0.write(buf)
|
||||||
Ok(sz.try_into().unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||||
crate::io::default_write_vectored(|b| self.write(b), bufs)
|
self.0.write_vectored(bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_write_vectored(&self) -> bool {
|
pub fn is_write_vectored(&self) -> bool {
|
||||||
false
|
self.0.is_write_vectored()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_timeout(&self, dur: Option<Duration>, kind: i32) -> io::Result<()> {
|
pub fn set_timeout(&self, dur: Option<Duration>, kind: i32) -> io::Result<()> {
|
||||||
@ -265,7 +264,7 @@ pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
|||||||
Shutdown::Read => netc::SHUT_RD,
|
Shutdown::Read => netc::SHUT_RD,
|
||||||
Shutdown::Both => netc::SHUT_RDWR,
|
Shutdown::Both => netc::SHUT_RDWR,
|
||||||
};
|
};
|
||||||
cvt(unsafe { netc::shutdown_socket(self.as_raw_fd(), how) })?;
|
cvt(unsafe { netc::shutdown(self.as_raw_fd(), how) })?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,5 +198,5 @@ pub fn exit(code: i32) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getpid() -> u32 {
|
pub fn getpid() -> u32 {
|
||||||
unsafe { hermit_abi::getpid() }
|
unsafe { hermit_abi::getpid() as u32 }
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use super::hermit_abi;
|
use super::hermit_abi;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::io::{IoSlice, IoSliceMut};
|
use crate::io::{IoSlice, IoSliceMut};
|
||||||
|
use crate::mem::ManuallyDrop;
|
||||||
|
use crate::os::hermit::io::FromRawFd;
|
||||||
|
use crate::sys::fd::FileDesc;
|
||||||
|
|
||||||
pub struct Stdin;
|
pub struct Stdin;
|
||||||
pub struct Stdout;
|
pub struct Stdout;
|
||||||
@ -13,12 +16,14 @@ pub const fn new() -> Stdin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl io::Read for Stdin {
|
impl io::Read for Stdin {
|
||||||
fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.read_vectored(&mut [IoSliceMut::new(data)])
|
unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDIN_FILENO)).read(buf) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_vectored(&mut self, _data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||||
Ok(0)
|
unsafe {
|
||||||
|
ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDIN_FILENO)).read_vectored(bufs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -34,27 +39,13 @@ pub const fn new() -> Stdout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl io::Write for Stdout {
|
impl io::Write for Stdout {
|
||||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
let len;
|
unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDOUT_FILENO)).write(buf) }
|
||||||
|
|
||||||
unsafe { len = hermit_abi::write(1, data.as_ptr() as *const u8, data.len()) }
|
|
||||||
|
|
||||||
if len < 0 {
|
|
||||||
Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stdout is not able to print"))
|
|
||||||
} else {
|
|
||||||
Ok(len as usize)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
|
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||||
let len;
|
unsafe {
|
||||||
|
ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDOUT_FILENO)).write_vectored(bufs)
|
||||||
unsafe { len = hermit_abi::write(1, data.as_ptr() as *const u8, data.len()) }
|
|
||||||
|
|
||||||
if len < 0 {
|
|
||||||
Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stdout is not able to print"))
|
|
||||||
} else {
|
|
||||||
Ok(len as usize)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,27 +66,13 @@ pub const fn new() -> Stderr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl io::Write for Stderr {
|
impl io::Write for Stderr {
|
||||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
let len;
|
unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDERR_FILENO)).write(buf) }
|
||||||
|
|
||||||
unsafe { len = hermit_abi::write(2, data.as_ptr() as *const u8, data.len()) }
|
|
||||||
|
|
||||||
if len < 0 {
|
|
||||||
Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stderr is not able to print"))
|
|
||||||
} else {
|
|
||||||
Ok(len as usize)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
|
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||||
let len;
|
unsafe {
|
||||||
|
ManuallyDrop::new(FileDesc::from_raw_fd(hermit_abi::STDERR_FILENO)).write_vectored(bufs)
|
||||||
unsafe { len = hermit_abi::write(2, data.as_ptr() as *const u8, data.len()) }
|
|
||||||
|
|
||||||
if len < 0 {
|
|
||||||
Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Stderr is not able to print"))
|
|
||||||
} else {
|
|
||||||
Ok(len as usize)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,10 +86,10 @@ fn flush(&mut self) -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const STDIN_BUF_SIZE: usize = 0;
|
pub const STDIN_BUF_SIZE: usize = 128;
|
||||||
|
|
||||||
pub fn is_ebadf(_err: &io::Error) -> bool {
|
pub fn is_ebadf(err: &io::Error) -> bool {
|
||||||
true
|
err.raw_os_error() == Some(hermit_abi::EBADF)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn panic_output() -> Option<impl io::Write> {
|
pub fn panic_output() -> Option<impl io::Write> {
|
||||||
|
@ -98,5 +98,5 @@ pub fn into_id(self) -> Tid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn available_parallelism() -> io::Result<NonZero<usize>> {
|
pub fn available_parallelism() -> io::Result<NonZero<usize>> {
|
||||||
unsafe { Ok(NonZero::new_unchecked(hermit_abi::get_processor_count())) }
|
unsafe { Ok(NonZero::new_unchecked(hermit_abi::available_parallelism())) }
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use super::hermit_abi::{self, timespec, CLOCK_MONOTONIC, CLOCK_REALTIME, NSEC_PER_SEC};
|
use super::hermit_abi::{self, timespec, CLOCK_MONOTONIC, CLOCK_REALTIME};
|
||||||
use crate::cmp::Ordering;
|
use crate::cmp::Ordering;
|
||||||
use crate::ops::{Add, AddAssign, Sub, SubAssign};
|
use crate::ops::{Add, AddAssign, Sub, SubAssign};
|
||||||
use crate::time::Duration;
|
use crate::time::Duration;
|
||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
|
|
||||||
|
const NSEC_PER_SEC: i32 = 1_000_000_000;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
struct Timespec {
|
struct Timespec {
|
||||||
t: timespec,
|
t: timespec,
|
||||||
@ -16,8 +18,8 @@ const fn zero() -> Timespec {
|
|||||||
Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } }
|
Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } }
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec {
|
const fn new(tv_sec: i64, tv_nsec: i32) -> Timespec {
|
||||||
assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64);
|
assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC);
|
||||||
// SAFETY: The assert above checks tv_nsec is within the valid range
|
// SAFETY: The assert above checks tv_nsec is within the valid range
|
||||||
Timespec { t: timespec { tv_sec: tv_sec, tv_nsec: tv_nsec } }
|
Timespec { t: timespec { tv_sec: tv_sec, tv_nsec: tv_nsec } }
|
||||||
}
|
}
|
||||||
@ -32,7 +34,7 @@ fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
|
|||||||
} else {
|
} else {
|
||||||
Duration::new(
|
Duration::new(
|
||||||
(self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
(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,
|
(self.t.tv_nsec + NSEC_PER_SEC - other.t.tv_nsec) as u32,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -48,9 +50,9 @@ fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
|
|||||||
|
|
||||||
// Nano calculations can't overflow because nanos are <1B which fit
|
// Nano calculations can't overflow because nanos are <1B which fit
|
||||||
// in a u32.
|
// in a u32.
|
||||||
let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
|
let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap();
|
||||||
if nsec >= NSEC_PER_SEC as u32 {
|
if nsec >= NSEC_PER_SEC.try_into().unwrap() {
|
||||||
nsec -= NSEC_PER_SEC as u32;
|
nsec -= u32::try_from(NSEC_PER_SEC).unwrap();
|
||||||
secs = secs.checked_add(1)?;
|
secs = secs.checked_add(1)?;
|
||||||
}
|
}
|
||||||
Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
|
||||||
@ -200,7 +202,7 @@ fn sub(self, other: Instant) -> Duration {
|
|||||||
pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero());
|
pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero());
|
||||||
|
|
||||||
impl SystemTime {
|
impl SystemTime {
|
||||||
pub fn new(tv_sec: i64, tv_nsec: i64) -> SystemTime {
|
pub fn new(tv_sec: i64, tv_nsec: i32) -> SystemTime {
|
||||||
SystemTime(Timespec::new(tv_sec, tv_nsec))
|
SystemTime(Timespec::new(tv_sec, tv_nsec))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user