Added io::Read/Write impls for `ManagedFD` and `MemoryFile`.

Fortune for mapped-file's current commit: Small blessing − 小吉
master
Avril 2 years ago
parent 51c64b56b0
commit 71da5e610f
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -2,7 +2,7 @@
name = "mapped-file"
description = "Construct a memory mapping over any file object"
keywords = ["unix", "mmap", "generic", "file", "fd"]
version = "0.0.4"
version = "0.0.5"
edition = "2021"
repository="https://github.com/notflan/mapped-file"
license="MIT"

@ -24,8 +24,6 @@ impl Clone for ManagedFD {
}
}
//TODO: io::Read/io::Write impls for ManagedFD
impl ManagedFD
{
#[inline]
@ -115,3 +113,5 @@ impl From<ManagedFD> for std::fs::File
}
}
}
raw::impl_io_for_fd!(ManagedFD => .0.get());

@ -79,7 +79,7 @@ impl ops::Deref for NamedMemoryFile
}
}
//TODO: impl `MemoryFile` (memfd_create() fd wrapper)
//impl `MemoryFile` (memfd_create() fd wrapper)
impl MemoryFile
{
/// Create a new, empty, memory file with no name and no flags.
@ -234,4 +234,4 @@ impl From<MemoryFile> for std::fs::File
}
}
//TODO: io::Read/io::Write impls for MemoryFile
raw::impl_io_for_fd!(MemoryFile => .0.as_raw_fd());

@ -117,3 +117,93 @@ impl From<i32> for NonNegativeI32
}
}
/// Implements `io::Read` and `io::Write` for a type that implements an accessor for a raw file-descriptor.
///
/// Usage:
/// ```no_compile
/// struct HasFd(UnmanagedFD);
/// impl_io_for_fd(HasFd => .0);
/// ```
macro_rules! impl_io_for_fd {
($type:ty => .$($fd_path:tt)+) => {
const _:() = {
use std::io;
#[inline(always)]
fn check_error() -> bool
{
use libc::{
EINTR,
__errno_location,
};
match unsafe { *__errno_location() } {
EINTR => true,
_ => false,
}
}
impl io::Write for $type
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match unsafe { libc::write(self.$($fd_path)+, buf.as_ptr() as *const _, buf.len()) } {
-1 => Err(io::Error::last_os_error()),
n => Ok(n as usize)
}
}
fn write_all(&mut self, mut buf: &[u8]) -> io::Result<()> {
loop {
buf = match buf {
[] => break Ok(()),
buf => {
match unsafe{ libc::write(self.$($fd_path)+, buf.as_ptr() as *const _, buf.len()) } {
-1 if check_error() => {
return Err(io::Error::last_os_error());
},
-1 => continue,
0 => return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "write returned 0")),
n => &buf[(n as usize)..],
}
},
};
}
}
#[inline]
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl io::Read for $type
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
{
match unsafe { libc::read(self.$($fd_path)+, buf.as_mut_ptr() as *mut _, buf.len()) } {
-1 => Err(io::Error::last_os_error()),
n => Ok(n as usize),
}
}
fn read_exact(&mut self, mut buf: &mut [u8]) -> io::Result<()>
{
loop {
let n = match &mut buf {
[] => break Ok(()),
buf => {
match unsafe { libc::read(self.$($fd_path)+, (**buf).as_mut_ptr() as *mut libc::c_void, buf.len()) } {
-1 if check_error() => {
return Err(io::Error::last_os_error());
},
-1 => continue,
0 => return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "read returned 0")),
n => n as usize,
}
}
};
buf = &mut buf[n..];
}
}
}
};
};
}
pub(super) use impl_io_for_fd;

Loading…
Cancel
Save