Rollup merge of #135696 - joboet:move_pal_io, r=Noratrieb
std: move `io` module out of `pal`, get rid of `sys_common::io` Part of #117276. This does two related things: 1. It moves the platform-specific definitions for `IoSlice`, `IoSliceMut` and `is_terminal` out of `pal` and into `sys` and unifies some of them. 2. It gets rid of `sys_common::io`, moving the non-platform-specific test helpers into `std::test_helpers` and the buffer size definition to the new `sys::io` module.
This commit is contained in:
commit
02b8bea084
40 changed files with 165 additions and 318 deletions
|
@ -14,7 +14,7 @@ use crate::os::unix::fs::symlink as junction_point;
|
|||
use crate::os::windows::fs::{OpenOptionsExt, junction_point, symlink_dir, symlink_file};
|
||||
use crate::path::Path;
|
||||
use crate::sync::Arc;
|
||||
use crate::sys_common::io::test::{TempDir, tmpdir};
|
||||
use crate::test_helpers::{TempDir, tmpdir};
|
||||
use crate::time::{Duration, Instant, SystemTime};
|
||||
use crate::{env, str, thread};
|
||||
|
||||
|
|
|
@ -344,7 +344,7 @@ pub mod prelude;
|
|||
mod stdio;
|
||||
mod util;
|
||||
|
||||
const DEFAULT_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
|
||||
const DEFAULT_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
|
||||
|
||||
pub(crate) use stdio::cleanup;
|
||||
|
||||
|
|
|
@ -739,27 +739,4 @@ mod sealed {
|
|||
|
||||
#[cfg(test)]
|
||||
#[allow(dead_code)] // Not used in all configurations.
|
||||
pub(crate) mod test_helpers {
|
||||
/// Test-only replacement for `rand::thread_rng()`, which is unusable for
|
||||
/// us, as we want to allow running stdlib tests on tier-3 targets which may
|
||||
/// not have `getrandom` support.
|
||||
///
|
||||
/// Does a bit of a song and dance to ensure that the seed is different on
|
||||
/// each call (as some tests sadly rely on this), but doesn't try that hard.
|
||||
///
|
||||
/// This is duplicated in the `core`, `alloc` test suites (as well as
|
||||
/// `std`'s integration tests), but figuring out a mechanism to share these
|
||||
/// seems far more painful than copy-pasting a 7 line function a couple
|
||||
/// times, given that even under a perma-unstable feature, I don't think we
|
||||
/// want to expose types from `rand` from `std`.
|
||||
#[track_caller]
|
||||
pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
|
||||
use core::hash::{BuildHasher, Hash, Hasher};
|
||||
let mut hasher = crate::hash::RandomState::new().build_hasher();
|
||||
core::panic::Location::caller().hash(&mut hasher);
|
||||
let hc64 = hasher.finish();
|
||||
let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
|
||||
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
|
||||
rand::SeedableRng::from_seed(seed)
|
||||
}
|
||||
}
|
||||
pub(crate) mod test_helpers;
|
||||
|
|
|
@ -3,7 +3,7 @@ use super::*;
|
|||
#[test]
|
||||
fn read_vectored_at() {
|
||||
let msg = b"preadv is working!";
|
||||
let dir = crate::sys_common::io::test::tmpdir();
|
||||
let dir = crate::test_helpers::tmpdir();
|
||||
|
||||
let filename = dir.join("preadv.txt");
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ fn read_vectored_at() {
|
|||
#[test]
|
||||
fn write_vectored_at() {
|
||||
let msg = b"pwritev is not working!";
|
||||
let dir = crate::sys_common::io::test::tmpdir();
|
||||
let dir = crate::test_helpers::tmpdir();
|
||||
|
||||
let filename = dir.join("preadv.txt");
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::os::android::net::{SocketAddrExt, UnixSocketExt};
|
|||
use crate::os::linux::net::{SocketAddrExt, UnixSocketExt};
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
use crate::os::unix::io::AsRawFd;
|
||||
use crate::sys_common::io::test::tmpdir;
|
||||
use crate::test_helpers::tmpdir;
|
||||
use crate::thread;
|
||||
use crate::time::Duration;
|
||||
|
||||
|
|
|
@ -549,7 +549,7 @@ fn debug_print() {
|
|||
#[test]
|
||||
#[cfg(windows)]
|
||||
fn run_bat_script() {
|
||||
let tempdir = crate::sys_common::io::test::tmpdir();
|
||||
let tempdir = crate::test_helpers::tmpdir();
|
||||
let script_path = tempdir.join("hello.cmd");
|
||||
|
||||
crate::fs::write(&script_path, "@echo Hello, %~1!").unwrap();
|
||||
|
@ -568,7 +568,7 @@ fn run_bat_script() {
|
|||
#[test]
|
||||
#[cfg(windows)]
|
||||
fn run_canonical_bat_script() {
|
||||
let tempdir = crate::sys_common::io::test::tmpdir();
|
||||
let tempdir = crate::test_helpers::tmpdir();
|
||||
let script_path = tempdir.join("hello.cmd");
|
||||
|
||||
crate::fs::write(&script_path, "@echo Hello, %~1!").unwrap();
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
use hermit_abi::{c_void, iovec};
|
||||
#[cfg(target_os = "hermit")]
|
||||
use hermit_abi::iovec;
|
||||
#[cfg(target_family = "unix")]
|
||||
use libc::iovec;
|
||||
|
||||
use crate::ffi::c_void;
|
||||
use crate::marker::PhantomData;
|
||||
use crate::os::hermit::io::{AsFd, AsRawFd};
|
||||
use crate::slice;
|
||||
#[cfg(target_os = "solid_asp3")]
|
||||
use crate::sys::pal::abi::sockets::iovec;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(transparent)]
|
||||
|
@ -80,8 +85,3 @@ impl<'a> IoSliceMut<'a> {
|
|||
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())
|
||||
}
|
|
@ -50,7 +50,3 @@ impl<'a> IoSliceMut<'a> {
|
|||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_terminal<T>(_: &T) -> bool {
|
||||
false
|
||||
}
|
|
@ -1,7 +1,4 @@
|
|||
#![forbid(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use crate::marker::PhantomData;
|
||||
use crate::os::fd::{AsFd, AsRawFd};
|
||||
use crate::slice;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -77,8 +74,3 @@ impl<'a> IoSliceMut<'a> {
|
|||
unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_terminal(fd: &impl AsFd) -> bool {
|
||||
let fd = fd.as_fd();
|
||||
unsafe { libc::isatty(fd.as_raw_fd()) != 0 }
|
||||
}
|
|
@ -1,86 +1,82 @@
|
|||
use libc::c_void;
|
||||
|
||||
use super::abi::sockets::iovec;
|
||||
use crate::marker::PhantomData;
|
||||
use crate::slice;
|
||||
use crate::sys::c;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct IoSlice<'a> {
|
||||
vec: iovec,
|
||||
vec: c::WSABUF,
|
||||
_p: PhantomData<&'a [u8]>,
|
||||
}
|
||||
|
||||
impl<'a> IoSlice<'a> {
|
||||
#[inline]
|
||||
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
|
||||
assert!(buf.len() <= u32::MAX as usize);
|
||||
IoSlice {
|
||||
vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
|
||||
vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_ptr() as *mut u8 },
|
||||
_p: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn advance(&mut self, n: usize) {
|
||||
if self.vec.iov_len < n {
|
||||
if (self.vec.len as usize) < n {
|
||||
panic!("advancing IoSlice beyond its length");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
self.vec.iov_len -= n;
|
||||
self.vec.iov_base = self.vec.iov_base.add(n);
|
||||
self.vec.len -= n as u32;
|
||||
self.vec.buf = self.vec.buf.add(n);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn as_slice(&self) -> &'a [u8] {
|
||||
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||
unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct IoSliceMut<'a> {
|
||||
vec: iovec,
|
||||
vec: c::WSABUF,
|
||||
_p: PhantomData<&'a mut [u8]>,
|
||||
}
|
||||
|
||||
impl<'a> IoSliceMut<'a> {
|
||||
#[inline]
|
||||
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
||||
assert!(buf.len() <= u32::MAX as usize);
|
||||
IoSliceMut {
|
||||
vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
|
||||
vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_mut_ptr() },
|
||||
_p: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn advance(&mut self, n: usize) {
|
||||
if self.vec.iov_len < n {
|
||||
if (self.vec.len as usize) < n {
|
||||
panic!("advancing IoSliceMut beyond its length");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
self.vec.iov_len -= n;
|
||||
self.vec.iov_base = self.vec.iov_base.add(n);
|
||||
self.vec.len -= n as u32;
|
||||
self.vec.buf = self.vec.buf.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) }
|
||||
unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn into_slice(self) -> &'a mut [u8] {
|
||||
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
|
||||
unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
|
||||
}
|
||||
|
||||
#[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) }
|
||||
unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_terminal<T>(_: &T) -> bool {
|
||||
false
|
||||
}
|
6
library/std/src/sys/io/is_terminal/hermit.rs
Normal file
6
library/std/src/sys/io/is_terminal/hermit.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
use crate::os::fd::{AsFd, AsRawFd};
|
||||
|
||||
pub fn is_terminal(fd: &impl AsFd) -> bool {
|
||||
let fd = fd.as_fd();
|
||||
hermit_abi::isatty(fd.as_raw_fd())
|
||||
}
|
6
library/std/src/sys/io/is_terminal/isatty.rs
Normal file
6
library/std/src/sys/io/is_terminal/isatty.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
use crate::os::fd::{AsFd, AsRawFd};
|
||||
|
||||
pub fn is_terminal(fd: &impl AsFd) -> bool {
|
||||
let fd = fd.as_fd();
|
||||
unsafe { libc::isatty(fd.as_raw_fd()) != 0 }
|
||||
}
|
3
library/std/src/sys/io/is_terminal/unsupported.rs
Normal file
3
library/std/src/sys/io/is_terminal/unsupported.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub fn is_terminal<T>(_: &T) -> bool {
|
||||
false
|
||||
}
|
|
@ -1,90 +1,8 @@
|
|||
use core::ffi::c_void;
|
||||
|
||||
use crate::marker::PhantomData;
|
||||
use crate::ffi::c_void;
|
||||
use crate::mem::size_of;
|
||||
use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle};
|
||||
use crate::slice;
|
||||
use crate::sys::c;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct IoSlice<'a> {
|
||||
vec: c::WSABUF,
|
||||
_p: PhantomData<&'a [u8]>,
|
||||
}
|
||||
|
||||
impl<'a> IoSlice<'a> {
|
||||
#[inline]
|
||||
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
|
||||
assert!(buf.len() <= u32::MAX as usize);
|
||||
IoSlice {
|
||||
vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_ptr() as *mut u8 },
|
||||
_p: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn advance(&mut self, n: usize) {
|
||||
if (self.vec.len as usize) < n {
|
||||
panic!("advancing IoSlice beyond its length");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
self.vec.len -= n as u32;
|
||||
self.vec.buf = self.vec.buf.add(n);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn as_slice(&self) -> &'a [u8] {
|
||||
unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct IoSliceMut<'a> {
|
||||
vec: c::WSABUF,
|
||||
_p: PhantomData<&'a mut [u8]>,
|
||||
}
|
||||
|
||||
impl<'a> IoSliceMut<'a> {
|
||||
#[inline]
|
||||
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
|
||||
assert!(buf.len() <= u32::MAX as usize);
|
||||
IoSliceMut {
|
||||
vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_mut_ptr() },
|
||||
_p: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn advance(&mut self, n: usize) {
|
||||
if (self.vec.len as usize) < n {
|
||||
panic!("advancing IoSliceMut beyond its length");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
self.vec.len -= n as u32;
|
||||
self.vec.buf = self.vec.buf.add(n);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn into_slice(self) -> &'a mut [u8] {
|
||||
unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||
unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_terminal(h: &impl AsHandle) -> bool {
|
||||
handle_is_console(h.as_handle())
|
||||
}
|
44
library/std/src/sys/io/mod.rs
Normal file
44
library/std/src/sys/io/mod.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
#![forbid(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
mod io_slice {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3"))] {
|
||||
mod iovec;
|
||||
pub use iovec::*;
|
||||
} else if #[cfg(target_os = "windows")] {
|
||||
mod windows;
|
||||
pub use windows::*;
|
||||
} else if #[cfg(target_os = "wasi")] {
|
||||
mod wasi;
|
||||
pub use wasi::*;
|
||||
} else {
|
||||
mod unsupported;
|
||||
pub use unsupported::*;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod is_terminal {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(target_family = "unix", target_os = "wasi"))] {
|
||||
mod isatty;
|
||||
pub use isatty::*;
|
||||
} else if #[cfg(target_os = "windows")] {
|
||||
mod windows;
|
||||
pub use windows::*;
|
||||
} else if #[cfg(target_os = "hermit")] {
|
||||
mod hermit;
|
||||
pub use hermit::*;
|
||||
} else {
|
||||
mod unsupported;
|
||||
pub use unsupported::*;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub use io_slice::{IoSlice, IoSliceMut};
|
||||
pub use is_terminal::is_terminal;
|
||||
|
||||
// Bare metal platforms usually have very small amounts of RAM
|
||||
// (in the order of hundreds of KB)
|
||||
pub const DEFAULT_BUF_SIZE: usize = if cfg!(target_os = "espidf") { 512 } else { 8 * 1024 };
|
|
@ -12,6 +12,7 @@ pub mod anonymous_pipe;
|
|||
pub mod backtrace;
|
||||
pub mod cmath;
|
||||
pub mod exit_guard;
|
||||
pub mod io;
|
||||
pub mod net;
|
||||
pub mod os_str;
|
||||
pub mod path;
|
||||
|
|
|
@ -23,7 +23,6 @@ pub mod env;
|
|||
pub mod fd;
|
||||
pub mod fs;
|
||||
pub mod futex;
|
||||
pub mod io;
|
||||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
pub mod pipe;
|
||||
|
|
|
@ -14,8 +14,6 @@ pub mod env;
|
|||
pub mod fd;
|
||||
#[path = "../unsupported/fs.rs"]
|
||||
pub mod fs;
|
||||
#[path = "../unsupported/io.rs"]
|
||||
pub mod io;
|
||||
mod libunwind_integration;
|
||||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
|
|
|
@ -62,7 +62,7 @@ impl io::Write for Stderr {
|
|||
}
|
||||
}
|
||||
|
||||
pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
|
||||
pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
|
||||
|
||||
pub fn is_ebadf(err: &io::Error) -> bool {
|
||||
// FIXME: Rust normally maps Unix EBADF to `Uncategorized`
|
||||
|
|
|
@ -23,7 +23,6 @@ pub mod env;
|
|||
// `crate::sys::error`
|
||||
pub(crate) mod error;
|
||||
pub mod fs;
|
||||
pub mod io;
|
||||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
pub mod pipe;
|
||||
|
|
|
@ -13,8 +13,6 @@ pub mod env;
|
|||
//pub mod fd;
|
||||
#[path = "../unsupported/fs.rs"]
|
||||
pub mod fs;
|
||||
#[path = "../unsupported/io.rs"]
|
||||
pub mod io;
|
||||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
pub mod pipe;
|
||||
|
|
|
@ -17,8 +17,6 @@ pub mod args;
|
|||
pub mod env;
|
||||
pub mod fs;
|
||||
pub mod helpers;
|
||||
#[path = "../unsupported/io.rs"]
|
||||
pub mod io;
|
||||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
pub mod pipe;
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
use libc::{c_void, iovec};
|
||||
|
||||
use crate::marker::PhantomData;
|
||||
use crate::os::fd::{AsFd, AsRawFd};
|
||||
use crate::slice;
|
||||
|
||||
#[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 const fn as_slice(&self) -> &'a [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 const fn into_slice(self) -> &'a mut [u8] {
|
||||
unsafe { slice::from_raw_parts_mut(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();
|
||||
unsafe { libc::isatty(fd.as_raw_fd()) != 0 }
|
||||
}
|
|
@ -2,7 +2,7 @@ use crate::fs::OpenOptions;
|
|||
use crate::io;
|
||||
use crate::io::{BufRead, Read, Result, Seek, SeekFrom, Write};
|
||||
use crate::os::unix::io::AsRawFd;
|
||||
use crate::sys_common::io::test::tmpdir;
|
||||
use crate::test_helpers::tmpdir;
|
||||
|
||||
#[test]
|
||||
fn copy_specialization() -> Result<()> {
|
||||
|
|
|
@ -11,7 +11,6 @@ pub mod env;
|
|||
pub mod fd;
|
||||
pub mod fs;
|
||||
pub mod futex;
|
||||
pub mod io;
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
pub mod kernel_copy;
|
||||
#[cfg(target_os = "linux")]
|
||||
|
|
|
@ -92,7 +92,7 @@ pub fn is_ebadf(err: &io::Error) -> bool {
|
|||
err.raw_os_error() == Some(libc::EBADF as i32)
|
||||
}
|
||||
|
||||
pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
|
||||
pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
|
||||
|
||||
pub fn panic_output() -> Option<impl io::Write> {
|
||||
Some(Stderr::new())
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
pub mod args;
|
||||
pub mod env;
|
||||
pub mod fs;
|
||||
pub mod io;
|
||||
pub mod os;
|
||||
pub mod pipe;
|
||||
pub mod process;
|
||||
|
|
|
@ -20,7 +20,6 @@ pub mod fs;
|
|||
#[allow(unused)]
|
||||
#[path = "../wasm/atomics/futex.rs"]
|
||||
pub mod futex;
|
||||
pub mod io;
|
||||
|
||||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
|
|
|
@ -101,7 +101,7 @@ impl io::Write for Stderr {
|
|||
}
|
||||
}
|
||||
|
||||
pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
|
||||
pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
|
||||
|
||||
pub fn is_ebadf(err: &io::Error) -> bool {
|
||||
err.raw_os_error() == Some(wasi::ERRNO_BADF.raw().into())
|
||||
|
|
|
@ -17,8 +17,6 @@ pub mod fs;
|
|||
#[allow(unused)]
|
||||
#[path = "../wasm/atomics/futex.rs"]
|
||||
pub mod futex;
|
||||
#[path = "../wasi/io.rs"]
|
||||
pub mod io;
|
||||
|
||||
#[path = "../wasi/os.rs"]
|
||||
pub mod os;
|
||||
|
|
|
@ -21,8 +21,6 @@ pub mod args;
|
|||
pub mod env;
|
||||
#[path = "../unsupported/fs.rs"]
|
||||
pub mod fs;
|
||||
#[path = "../unsupported/io.rs"]
|
||||
pub mod io;
|
||||
#[path = "../unsupported/os.rs"]
|
||||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
|
|
|
@ -21,7 +21,6 @@ pub mod fs;
|
|||
#[cfg(not(target_vendor = "win7"))]
|
||||
pub mod futex;
|
||||
pub mod handle;
|
||||
pub mod io;
|
||||
pub mod os;
|
||||
pub mod pipe;
|
||||
pub mod process;
|
||||
|
|
|
@ -158,7 +158,7 @@ fn windows_exe_resolver() {
|
|||
use super::resolve_exe;
|
||||
use crate::io;
|
||||
use crate::sys::fs::symlink;
|
||||
use crate::sys_common::io::test::tmpdir;
|
||||
use crate::test_helpers::tmpdir;
|
||||
|
||||
let env_paths = || env::var_os("PATH");
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@ pub mod args;
|
|||
pub mod env;
|
||||
#[path = "../unsupported/fs.rs"]
|
||||
pub mod fs;
|
||||
#[path = "../unsupported/io.rs"]
|
||||
pub mod io;
|
||||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
pub mod pipe;
|
||||
|
|
|
@ -16,8 +16,6 @@ pub mod args;
|
|||
pub mod env;
|
||||
#[path = "../unsupported/fs.rs"]
|
||||
pub mod fs;
|
||||
#[path = "../unsupported/io.rs"]
|
||||
pub mod io;
|
||||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
pub mod pipe;
|
||||
|
|
|
@ -54,7 +54,7 @@ impl io::Write for Stderr {
|
|||
}
|
||||
}
|
||||
|
||||
pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
|
||||
pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE;
|
||||
|
||||
pub fn is_ebadf(_err: &io::Error) -> bool {
|
||||
true
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
// Bare metal platforms usually have very small amounts of RAM
|
||||
// (in the order of hundreds of KB)
|
||||
pub const DEFAULT_BUF_SIZE: usize = if cfg!(target_os = "espidf") { 512 } else { 8 * 1024 };
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(dead_code)] // not used on emscripten and wasi
|
||||
pub mod test {
|
||||
use rand::RngCore;
|
||||
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::{env, fs, thread};
|
||||
|
||||
pub struct TempDir(PathBuf);
|
||||
|
||||
impl TempDir {
|
||||
pub fn join(&self, path: &str) -> PathBuf {
|
||||
let TempDir(ref p) = *self;
|
||||
p.join(path)
|
||||
}
|
||||
|
||||
pub fn path(&self) -> &Path {
|
||||
let TempDir(ref p) = *self;
|
||||
p
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TempDir {
|
||||
fn drop(&mut self) {
|
||||
// Gee, seeing how we're testing the fs module I sure hope that we
|
||||
// at least implement this correctly!
|
||||
let TempDir(ref p) = *self;
|
||||
let result = fs::remove_dir_all(p);
|
||||
// Avoid panicking while panicking as this causes the process to
|
||||
// immediately abort, without displaying test results.
|
||||
if !thread::panicking() {
|
||||
result.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller] // for `test_rng`
|
||||
pub fn tmpdir() -> TempDir {
|
||||
let p = env::temp_dir();
|
||||
let mut r = crate::test_helpers::test_rng();
|
||||
let ret = p.join(&format!("rust-{}", r.next_u32()));
|
||||
fs::create_dir(&ret).unwrap();
|
||||
TempDir(ret)
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@
|
|||
mod tests;
|
||||
|
||||
pub mod fs;
|
||||
pub mod io;
|
||||
pub mod process;
|
||||
pub mod wstr;
|
||||
pub mod wtf8;
|
||||
|
|
65
library/std/src/test_helpers.rs
Normal file
65
library/std/src/test_helpers.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
use rand::{RngCore, SeedableRng};
|
||||
|
||||
use crate::hash::{BuildHasher, Hash, Hasher, RandomState};
|
||||
use crate::panic::Location;
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::{env, fs, thread};
|
||||
|
||||
/// Test-only replacement for `rand::thread_rng()`, which is unusable for
|
||||
/// us, as we want to allow running stdlib tests on tier-3 targets which may
|
||||
/// not have `getrandom` support.
|
||||
///
|
||||
/// Does a bit of a song and dance to ensure that the seed is different on
|
||||
/// each call (as some tests sadly rely on this), but doesn't try that hard.
|
||||
///
|
||||
/// This is duplicated in the `core`, `alloc` test suites (as well as
|
||||
/// `std`'s integration tests), but figuring out a mechanism to share these
|
||||
/// seems far more painful than copy-pasting a 7 line function a couple
|
||||
/// times, given that even under a perma-unstable feature, I don't think we
|
||||
/// want to expose types from `rand` from `std`.
|
||||
#[track_caller]
|
||||
pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
|
||||
let mut hasher = RandomState::new().build_hasher();
|
||||
Location::caller().hash(&mut hasher);
|
||||
let hc64 = hasher.finish();
|
||||
let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
|
||||
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
|
||||
SeedableRng::from_seed(seed)
|
||||
}
|
||||
|
||||
pub struct TempDir(PathBuf);
|
||||
|
||||
impl TempDir {
|
||||
pub fn join(&self, path: &str) -> PathBuf {
|
||||
let TempDir(ref p) = *self;
|
||||
p.join(path)
|
||||
}
|
||||
|
||||
pub fn path(&self) -> &Path {
|
||||
let TempDir(ref p) = *self;
|
||||
p
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TempDir {
|
||||
fn drop(&mut self) {
|
||||
// Gee, seeing how we're testing the fs module I sure hope that we
|
||||
// at least implement this correctly!
|
||||
let TempDir(ref p) = *self;
|
||||
let result = fs::remove_dir_all(p);
|
||||
// Avoid panicking while panicking as this causes the process to
|
||||
// immediately abort, without displaying test results.
|
||||
if !thread::panicking() {
|
||||
result.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller] // for `test_rng`
|
||||
pub fn tmpdir() -> TempDir {
|
||||
let p = env::temp_dir();
|
||||
let mut r = test_rng();
|
||||
let ret = p.join(&format!("rust-{}", r.next_u32()));
|
||||
fs::create_dir(&ret).unwrap();
|
||||
TempDir(ret)
|
||||
}
|
|
@ -18,7 +18,7 @@ pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
|
|||
rand::SeedableRng::from_seed(seed)
|
||||
}
|
||||
|
||||
// Copied from std::sys_common::io
|
||||
// Copied from std::test_helpers
|
||||
pub(crate) struct TempDir(PathBuf);
|
||||
|
||||
impl TempDir {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue