use crate::{filelike, Advice};
#[cfg(not(any(target_os = "android", target_os = "linux")))]
use io_lifetimes::OwnedFilelike;
#[cfg(not(windows))]
use io_lifetimes::{AsFd, BorrowedFd};
use io_lifetimes::{FromFilelike, IntoFilelike};
#[cfg(feature = "io-streams")]
use io_streams::StreamReader;
use std::fs;
use std::io::{self, IoSlice, IoSliceMut, Read, Seek, Write};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd};
#[cfg(target_os = "wasi")]
use std::os::wasi::io::{AsRawFd, RawFd};
#[cfg(windows)]
use {
io_extras::os::windows::{AsRawHandleOrSocket, RawHandleOrSocket},
io_lifetimes::{AsHandle, BorrowedHandle},
std::os::windows::io::{AsRawHandle, RawHandle},
};
pub struct Metadata {
pub(crate) len: u64,
pub(crate) blksize: u64,
}
#[allow(clippy::len_without_is_empty)]
impl Metadata {
#[inline]
#[must_use]
pub const fn len(&self) -> u64 {
self.len
}
#[inline]
#[must_use]
pub const fn blksize(&self) -> u64 {
self.blksize
}
}
pub trait Array {
fn metadata(&self) -> io::Result<Metadata>;
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()>;
}
pub trait ReadAt: Array {
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()>;
fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<usize>;
fn read_exact_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<()>;
fn is_read_vectored_at(&self) -> bool;
#[cfg(feature = "io-streams")]
fn read_via_stream_at(&self, offset: u64) -> io::Result<StreamReader>;
}
pub trait WriteAt: Array {
fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize>;
fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()>;
fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize>;
fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()>;
fn is_write_vectored_at(&self) -> bool;
fn copy_from<R: ReadAt>(
&mut self,
offset: u64,
input: &R,
input_offset: u64,
len: u64,
) -> io::Result<u64>;
fn set_len(&mut self, size: u64) -> io::Result<()>;
}
pub trait EditAt: ReadAt + WriteAt {}
impl<T: ReadAt + WriteAt> EditAt for T {}
#[derive(Debug)]
pub struct ArrayReader {
file: fs::File,
}
#[derive(Debug)]
pub struct ArrayWriter {
file: fs::File,
}
#[derive(Debug)]
pub struct ArrayEditor {
file: fs::File,
}
impl ArrayReader {
#[inline]
#[must_use]
pub fn file<Filelike: IntoFilelike + Read + Seek>(filelike: Filelike) -> Self {
Self {
file: fs::File::from_into_filelike(filelike),
}
}
#[inline]
pub fn bytes(bytes: &[u8]) -> io::Result<Self> {
let owned = create_anonymous()?;
let mut file = fs::File::from_into_filelike(owned);
file.write_all(bytes)?;
Ok(Self { file })
}
}
impl ArrayWriter {
#[inline]
#[must_use]
pub fn file<Filelike: IntoFilelike + Write + Seek>(filelike: Filelike) -> Self {
Self::_file(fs::File::from_into_filelike(filelike))
}
#[inline]
fn _file(file: fs::File) -> Self {
#[cfg(not(windows))]
{
assert!(
!rustix::fs::fcntl_getfl(&file)
.unwrap()
.contains(rustix::fs::OFlags::APPEND),
"ArrayWriter doesn't support files opened with O_APPEND"
);
}
#[cfg(windows)]
{
assert!(
(winx::file::query_access_information(file.as_handle()).unwrap()
& winx::file::AccessMode::FILE_APPEND_DATA)
== winx::file::AccessMode::FILE_APPEND_DATA,
"ArrayWriter doesn't support files opened with FILE_APPEND_DATA"
);
}
Self { file }
}
}
impl ArrayEditor {
#[inline]
#[must_use]
pub fn file<Filelike: IntoFilelike + Read + Write + Seek>(filelike: Filelike) -> Self {
Self {
file: fs::File::from_into_filelike(filelike),
}
}
#[inline]
pub fn anonymous() -> io::Result<Self> {
let owned = create_anonymous()?;
Ok(Self {
file: fs::File::from_into_filelike(owned),
})
}
}
impl Array for ArrayReader {
#[inline]
fn metadata(&self) -> io::Result<Metadata> {
filelike::metadata(self)
}
#[inline]
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
filelike::advise(self, offset, len, advice)
}
}
impl Array for &ArrayReader {
#[inline]
fn metadata(&self) -> io::Result<Metadata> {
filelike::metadata(self)
}
#[inline]
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
filelike::advise(self, offset, len, advice)
}
}
impl Array for ArrayWriter {
#[inline]
fn metadata(&self) -> io::Result<Metadata> {
filelike::metadata(self)
}
#[inline]
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
filelike::advise(self, offset, len, advice)
}
}
impl Array for &ArrayWriter {
#[inline]
fn metadata(&self) -> io::Result<Metadata> {
filelike::metadata(self)
}
#[inline]
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
filelike::advise(self, offset, len, advice)
}
}
impl Array for ArrayEditor {
#[inline]
fn metadata(&self) -> io::Result<Metadata> {
filelike::metadata(self)
}
#[inline]
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
filelike::advise(self, offset, len, advice)
}
}
impl Array for &ArrayEditor {
#[inline]
fn metadata(&self) -> io::Result<Metadata> {
filelike::metadata(self)
}
#[inline]
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
filelike::advise(self, offset, len, advice)
}
}
impl ReadAt for ArrayReader {
#[inline]
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
filelike::read_at(self, buf, offset)
}
#[inline]
fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()> {
filelike::read_exact_at(self, buf, offset)
}
#[inline]
fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<usize> {
filelike::read_vectored_at(self, bufs, offset)
}
#[inline]
fn read_exact_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<()> {
filelike::read_exact_vectored_at(self, bufs, offset)
}
#[inline]
fn is_read_vectored_at(&self) -> bool {
filelike::is_read_vectored_at(self)
}
#[cfg(feature = "io-streams")]
#[inline]
fn read_via_stream_at(&self, offset: u64) -> io::Result<StreamReader> {
filelike::read_via_stream_at(self, offset)
}
}
impl ReadAt for ArrayEditor {
#[inline]
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
filelike::read_at(self, buf, offset)
}
#[inline]
fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()> {
filelike::read_exact_at(self, buf, offset)
}
#[inline]
fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<usize> {
filelike::read_vectored_at(self, bufs, offset)
}
#[inline]
fn read_exact_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<()> {
filelike::read_exact_vectored_at(self, bufs, offset)
}
#[inline]
fn is_read_vectored_at(&self) -> bool {
filelike::is_read_vectored_at(self)
}
#[cfg(feature = "io-streams")]
#[inline]
fn read_via_stream_at(&self, offset: u64) -> io::Result<StreamReader> {
filelike::read_via_stream_at(self, offset)
}
}
impl WriteAt for ArrayWriter {
#[inline]
fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
filelike::write_at(&*self, buf, offset)
}
#[inline]
fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
filelike::write_all_at(&*self, buf, offset)
}
#[inline]
fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
filelike::write_vectored_at(&*self, bufs, offset)
}
#[inline]
fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
filelike::write_all_vectored_at(&*self, bufs, offset)
}
#[inline]
fn is_write_vectored_at(&self) -> bool {
filelike::is_write_vectored_at(self)
}
#[inline]
fn copy_from<R: ReadAt>(
&mut self,
offset: u64,
input: &R,
input_offset: u64,
len: u64,
) -> io::Result<u64> {
filelike::copy_from(&*self, offset, input, input_offset, len)
}
#[inline]
fn set_len(&mut self, size: u64) -> io::Result<()> {
filelike::set_len(&*self, size)
}
}
impl WriteAt for &ArrayWriter {
#[inline]
fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
filelike::write_at(&*self, buf, offset)
}
#[inline]
fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
filelike::write_all_at(&*self, buf, offset)
}
#[inline]
fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
filelike::write_vectored_at(&*self, bufs, offset)
}
#[inline]
fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
filelike::write_all_vectored_at(&*self, bufs, offset)
}
#[inline]
fn is_write_vectored_at(&self) -> bool {
filelike::is_write_vectored_at(self)
}
#[inline]
fn copy_from<R: ReadAt>(
&mut self,
offset: u64,
input: &R,
input_offset: u64,
len: u64,
) -> io::Result<u64> {
filelike::copy_from(&*self, offset, input, input_offset, len)
}
#[inline]
fn set_len(&mut self, size: u64) -> io::Result<()> {
filelike::set_len(&*self, size)
}
}
impl WriteAt for ArrayEditor {
#[inline]
fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
filelike::write_at(&*self, buf, offset)
}
#[inline]
fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
filelike::write_all_at(&*self, buf, offset)
}
#[inline]
fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
filelike::write_vectored_at(&*self, bufs, offset)
}
#[inline]
fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
filelike::write_all_vectored_at(&*self, bufs, offset)
}
#[inline]
fn is_write_vectored_at(&self) -> bool {
filelike::is_write_vectored_at(self)
}
#[inline]
fn copy_from<R: ReadAt>(
&mut self,
offset: u64,
input: &R,
input_offset: u64,
len: u64,
) -> io::Result<u64> {
filelike::copy_from(&*self, offset, input, input_offset, len)
}
#[inline]
fn set_len(&mut self, size: u64) -> io::Result<()> {
filelike::set_len(&*self, size)
}
}
impl WriteAt for &ArrayEditor {
#[inline]
fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
filelike::write_at(&*self, buf, offset)
}
#[inline]
fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
filelike::write_all_at(&*self, buf, offset)
}
#[inline]
fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
filelike::write_vectored_at(&*self, bufs, offset)
}
#[inline]
fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
filelike::write_all_vectored_at(&*self, bufs, offset)
}
#[inline]
fn is_write_vectored_at(&self) -> bool {
filelike::is_write_vectored_at(self)
}
#[inline]
fn copy_from<R: ReadAt>(
&mut self,
offset: u64,
input: &R,
input_offset: u64,
len: u64,
) -> io::Result<u64> {
filelike::copy_from(&*self, offset, input, input_offset, len)
}
#[inline]
fn set_len(&mut self, size: u64) -> io::Result<()> {
filelike::set_len(&*self, size)
}
}
impl Array for fs::File {
#[inline]
fn metadata(&self) -> io::Result<Metadata> {
filelike::metadata(self)
}
#[inline]
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
filelike::advise(self, offset, len, advice)
}
}
impl Array for &fs::File {
#[inline]
fn metadata(&self) -> io::Result<Metadata> {
filelike::metadata(self)
}
#[inline]
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
filelike::advise(self, offset, len, advice)
}
}
impl ReadAt for fs::File {
#[inline]
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
filelike::read_at(self, buf, offset)
}
#[inline]
fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()> {
filelike::read_exact_at(self, buf, offset)
}
#[inline]
fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<usize> {
filelike::read_vectored_at(self, bufs, offset)
}
#[inline]
fn read_exact_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<()> {
filelike::read_exact_vectored_at(self, bufs, offset)
}
#[inline]
fn is_read_vectored_at(&self) -> bool {
filelike::is_read_vectored_at(self)
}
#[cfg(feature = "io-streams")]
#[inline]
fn read_via_stream_at(&self, offset: u64) -> io::Result<StreamReader> {
filelike::read_via_stream_at(self, offset)
}
}
impl WriteAt for fs::File {
#[inline]
fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
filelike::write_at(&*self, buf, offset)
}
#[inline]
fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
filelike::write_all_at(&*self, buf, offset)
}
#[inline]
fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
filelike::write_vectored_at(&*self, bufs, offset)
}
#[inline]
fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
filelike::write_all_vectored_at(&*self, bufs, offset)
}
#[inline]
fn is_write_vectored_at(&self) -> bool {
filelike::is_write_vectored_at(self)
}
#[inline]
fn copy_from<R: ReadAt>(
&mut self,
offset: u64,
input: &R,
input_offset: u64,
len: u64,
) -> io::Result<u64> {
filelike::copy_from(&*self, offset, input, input_offset, len)
}
#[inline]
fn set_len(&mut self, size: u64) -> io::Result<()> {
filelike::set_len(&*self, size)
}
}
impl WriteAt for &fs::File {
#[inline]
fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
filelike::write_at(&*self, buf, offset)
}
#[inline]
fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
filelike::write_all_at(&*self, buf, offset)
}
#[inline]
fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
filelike::write_vectored_at(&*self, bufs, offset)
}
#[inline]
fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
filelike::write_all_vectored_at(&*self, bufs, offset)
}
#[inline]
fn is_write_vectored_at(&self) -> bool {
filelike::is_write_vectored_at(self)
}
#[inline]
fn copy_from<R: ReadAt>(
&mut self,
offset: u64,
input: &R,
input_offset: u64,
len: u64,
) -> io::Result<u64> {
filelike::copy_from(&*self, offset, input, input_offset, len)
}
#[inline]
fn set_len(&mut self, size: u64) -> io::Result<()> {
filelike::set_len(&*self, size)
}
}
#[cfg(feature = "cap-std")]
impl Array for cap_std::fs::File {
#[inline]
fn metadata(&self) -> io::Result<Metadata> {
filelike::metadata(self)
}
#[inline]
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
filelike::advise(self, offset, len, advice)
}
}
#[cfg(feature = "cap-std")]
impl Array for &cap_std::fs::File {
#[inline]
fn metadata(&self) -> io::Result<Metadata> {
filelike::metadata(self)
}
#[inline]
fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
filelike::advise(self, offset, len, advice)
}
}
#[cfg(feature = "cap-std")]
impl ReadAt for cap_std::fs::File {
#[inline]
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
filelike::read_at(self, buf, offset)
}
#[inline]
fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()> {
filelike::read_exact_at(self, buf, offset)
}
#[inline]
fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<usize> {
filelike::read_vectored_at(self, bufs, offset)
}
#[inline]
fn read_exact_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<()> {
filelike::read_exact_vectored_at(self, bufs, offset)
}
#[inline]
fn is_read_vectored_at(&self) -> bool {
filelike::is_read_vectored_at(self)
}
#[cfg(feature = "io-streams")]
#[inline]
fn read_via_stream_at(&self, offset: u64) -> io::Result<StreamReader> {
filelike::read_via_stream_at(self, offset)
}
}
#[cfg(feature = "cap-std")]
impl WriteAt for cap_std::fs::File {
#[inline]
fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
filelike::write_at(self, buf, offset)
}
#[inline]
fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
filelike::write_all_at(self, buf, offset)
}
#[inline]
fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
filelike::write_vectored_at(self, bufs, offset)
}
#[inline]
fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
filelike::write_all_vectored_at(self, bufs, offset)
}
#[inline]
fn is_write_vectored_at(&self) -> bool {
filelike::is_write_vectored_at(self)
}
#[inline]
fn copy_from<R: ReadAt>(
&mut self,
offset: u64,
input: &R,
input_offset: u64,
len: u64,
) -> io::Result<u64> {
filelike::copy_from(self, offset, input, input_offset, len)
}
#[inline]
fn set_len(&mut self, size: u64) -> io::Result<()> {
filelike::set_len(self, size)
}
}
#[cfg(feature = "cap-std")]
impl WriteAt for &cap_std::fs::File {
#[inline]
fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
filelike::write_at(self, buf, offset)
}
#[inline]
fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
filelike::write_all_at(self, buf, offset)
}
#[inline]
fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
filelike::write_vectored_at(self, bufs, offset)
}
#[inline]
fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
filelike::write_all_vectored_at(self, bufs, offset)
}
#[inline]
fn is_write_vectored_at(&self) -> bool {
filelike::is_write_vectored_at(self)
}
#[inline]
fn copy_from<R: ReadAt>(
&mut self,
offset: u64,
input: &R,
input_offset: u64,
len: u64,
) -> io::Result<u64> {
filelike::copy_from(self, offset, input, input_offset, len)
}
#[inline]
fn set_len(&mut self, size: u64) -> io::Result<()> {
filelike::set_len(self, size)
}
}
#[cfg(not(windows))]
impl AsRawFd for ArrayReader {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.file.as_raw_fd()
}
}
#[cfg(not(windows))]
impl AsFd for ArrayReader {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.file.as_fd()
}
}
#[cfg(windows)]
impl AsRawHandle for ArrayReader {
#[inline]
fn as_raw_handle(&self) -> RawHandle {
self.file.as_raw_handle()
}
}
#[cfg(windows)]
impl AsHandle for ArrayReader {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
self.file.as_handle()
}
}
#[cfg(windows)]
impl AsRawHandleOrSocket for ArrayReader {
#[inline]
fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
self.file.as_raw_handle_or_socket()
}
}
#[cfg(not(windows))]
impl AsRawFd for ArrayWriter {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.file.as_raw_fd()
}
}
#[cfg(not(windows))]
impl AsFd for ArrayWriter {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.file.as_fd()
}
}
#[cfg(windows)]
impl AsRawHandle for ArrayWriter {
#[inline]
fn as_raw_handle(&self) -> RawHandle {
self.file.as_raw_handle()
}
}
#[cfg(windows)]
impl AsHandle for ArrayWriter {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
self.file.as_handle()
}
}
#[cfg(windows)]
impl AsRawHandleOrSocket for ArrayWriter {
#[inline]
fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
self.file.as_raw_handle_or_socket()
}
}
#[cfg(not(windows))]
impl AsRawFd for ArrayEditor {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.file.as_raw_fd()
}
}
#[cfg(not(windows))]
impl AsFd for ArrayEditor {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.file.as_fd()
}
}
#[cfg(windows)]
impl AsRawHandle for ArrayEditor {
#[inline]
fn as_raw_handle(&self) -> RawHandle {
self.file.as_raw_handle()
}
}
#[cfg(windows)]
impl AsHandle for ArrayEditor {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
self.file.as_handle()
}
}
#[cfg(windows)]
impl AsRawHandleOrSocket for ArrayEditor {
#[inline]
fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
self.file.as_raw_handle_or_socket()
}
}
#[cfg(any(target_os = "android", target_os = "linux"))]
fn create_anonymous() -> io::Result<rustix::fd::OwnedFd> {
let flags = rustix::fs::MemfdFlags::CLOEXEC | rustix::fs::MemfdFlags::ALLOW_SEALING;
let name = rustix::cstr!("io_arrays anonymous file");
Ok(rustix::fs::memfd_create(name, flags)?)
}
#[cfg(not(any(target_os = "android", target_os = "linux")))]
fn create_anonymous() -> io::Result<OwnedFilelike> {
let file = tempfile::tempfile()?;
Ok(file.into_filelike())
}