Add vectored positioned I/O on Unix
This commit is contained in:
parent
58136ffa92
commit
351c154cb4
@ -54,6 +54,20 @@ pub trait FileExt {
|
|||||||
#[stable(feature = "file_offset", since = "1.15.0")]
|
#[stable(feature = "file_offset", since = "1.15.0")]
|
||||||
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
|
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
|
||||||
|
|
||||||
|
/// Like `read_at`, except that it reads into a slice of buffers.
|
||||||
|
///
|
||||||
|
/// Data is copied to fill each buffer in order, with the final buffer
|
||||||
|
/// written to possibly being only partially filled. This method must behave
|
||||||
|
/// equivalently to a single call to read with concatenated buffers.
|
||||||
|
#[unstable(feature = "unix_file_vectored_at", issue = "89517")]
|
||||||
|
fn read_vectored_at(
|
||||||
|
&mut self,
|
||||||
|
bufs: &mut [io::IoSliceMut<'_>],
|
||||||
|
offset: u64,
|
||||||
|
) -> io::Result<usize> {
|
||||||
|
io::default_read_vectored(|b| self.read_at(b, offset), bufs)
|
||||||
|
}
|
||||||
|
|
||||||
/// Reads the exact number of byte required to fill `buf` from the given offset.
|
/// Reads the exact number of byte required to fill `buf` from the given offset.
|
||||||
///
|
///
|
||||||
/// The offset is relative to the start of the file and thus independent
|
/// The offset is relative to the start of the file and thus independent
|
||||||
@ -155,6 +169,16 @@ pub trait FileExt {
|
|||||||
#[stable(feature = "file_offset", since = "1.15.0")]
|
#[stable(feature = "file_offset", since = "1.15.0")]
|
||||||
fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
|
fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
|
||||||
|
|
||||||
|
/// Like `write_at`, except that it writes from a slice of buffers.
|
||||||
|
///
|
||||||
|
/// Data is copied from each buffer in order, with the final buffer read
|
||||||
|
/// from possibly being only partially consumed. This method must behave as
|
||||||
|
/// a call to `write_at` with the buffers concatenated would.
|
||||||
|
#[unstable(feature = "unix_file_vectored_at", issue = "89517")]
|
||||||
|
fn write_vectored_at(&mut self, bufs: &[io::IoSlice<'_>], offset: u64) -> io::Result<usize> {
|
||||||
|
io::default_write_vectored(|b| self.write_at(b, offset), bufs)
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempts to write an entire buffer starting from a given offset.
|
/// Attempts to write an entire buffer starting from a given offset.
|
||||||
///
|
///
|
||||||
/// The offset is relative to the start of the file and thus independent
|
/// The offset is relative to the start of the file and thus independent
|
||||||
@ -218,9 +242,19 @@ impl FileExt for fs::File {
|
|||||||
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
||||||
self.as_inner().read_at(buf, offset)
|
self.as_inner().read_at(buf, offset)
|
||||||
}
|
}
|
||||||
|
fn read_vectored_at(
|
||||||
|
&mut self,
|
||||||
|
bufs: &mut [io::IoSliceMut<'_>],
|
||||||
|
offset: u64,
|
||||||
|
) -> io::Result<usize> {
|
||||||
|
self.as_inner().read_vectored_at(bufs, offset)
|
||||||
|
}
|
||||||
fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||||
self.as_inner().write_at(buf, offset)
|
self.as_inner().write_at(buf, offset)
|
||||||
}
|
}
|
||||||
|
fn write_vectored_at(&mut self, bufs: &[io::IoSlice<'_>], offset: u64) -> io::Result<usize> {
|
||||||
|
self.as_inner().write_vectored_at(bufs, offset)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unix-specific extensions to [`fs::Permissions`].
|
/// Unix-specific extensions to [`fs::Permissions`].
|
||||||
|
@ -92,7 +92,7 @@ impl FileDesc {
|
|||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::readv(
|
libc::readv(
|
||||||
self.as_raw_fd(),
|
self.as_raw_fd(),
|
||||||
bufs.as_ptr() as *const libc::iovec,
|
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
|
||||||
cmp::min(bufs.len(), max_iov()) as libc::c_int,
|
cmp::min(bufs.len(), max_iov()) as libc::c_int,
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
@ -101,7 +101,7 @@ impl FileDesc {
|
|||||||
|
|
||||||
#[cfg(any(target_os = "espidf", target_os = "horizon"))]
|
#[cfg(any(target_os = "espidf", target_os = "horizon"))]
|
||||||
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
|
||||||
return crate::io::default_read_vectored(|b| self.read(b), bufs);
|
io::default_read_vectored(|b| self.read(b), bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -147,6 +147,44 @@ impl FileDesc {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(
|
||||||
|
target_os = "android",
|
||||||
|
target_os = "emscripten",
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "fuchsia",
|
||||||
|
target_os = "illumos",
|
||||||
|
target_os = "ios",
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "netbsd",
|
||||||
|
))]
|
||||||
|
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
|
||||||
|
let ret = cvt(unsafe {
|
||||||
|
libc::preadv(
|
||||||
|
self.as_raw_fd(),
|
||||||
|
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
|
||||||
|
cmp::min(bufs.len(), max_iov()) as libc::c_int,
|
||||||
|
offset as _,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok(ret as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(
|
||||||
|
target_os = "android",
|
||||||
|
target_os = "emscripten",
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "fuchsia",
|
||||||
|
target_os = "illumos",
|
||||||
|
target_os = "ios",
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "netbsd",
|
||||||
|
)))]
|
||||||
|
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
|
||||||
|
io::default_read_vectored(|b| self.read_at(b, offset), bufs)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::write(
|
libc::write(
|
||||||
@ -172,7 +210,7 @@ impl FileDesc {
|
|||||||
|
|
||||||
#[cfg(any(target_os = "espidf", target_os = "horizon"))]
|
#[cfg(any(target_os = "espidf", target_os = "horizon"))]
|
||||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||||
return crate::io::default_write_vectored(|b| self.write(b), bufs);
|
io::default_write_vectored(|b| self.write(b), bufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -197,6 +235,44 @@ impl FileDesc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(
|
||||||
|
target_os = "android",
|
||||||
|
target_os = "emscripten",
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "fuchsia",
|
||||||
|
target_os = "illumos",
|
||||||
|
target_os = "ios",
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "netbsd",
|
||||||
|
))]
|
||||||
|
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
|
||||||
|
let ret = cvt(unsafe {
|
||||||
|
libc::pwritev(
|
||||||
|
self.as_raw_fd(),
|
||||||
|
bufs.as_ptr() as *const libc::iovec,
|
||||||
|
cmp::min(bufs.len(), max_iov()) as libc::c_int,
|
||||||
|
offset as _,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok(ret as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(
|
||||||
|
target_os = "android",
|
||||||
|
target_os = "emscripten",
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "fuchsia",
|
||||||
|
target_os = "illumos",
|
||||||
|
target_os = "ios",
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "netbsd",
|
||||||
|
)))]
|
||||||
|
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
|
||||||
|
io::default_write_vectored(|b| self.write_at(b, offset), bufs)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
target_env = "newlib",
|
target_env = "newlib",
|
||||||
target_os = "solaris",
|
target_os = "solaris",
|
||||||
|
@ -1098,6 +1098,10 @@ impl File {
|
|||||||
self.0.read_buf(cursor)
|
self.0.read_buf(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
|
||||||
|
self.0.read_vectored_at(bufs, offset)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.0.write(buf)
|
self.0.write(buf)
|
||||||
}
|
}
|
||||||
@ -1115,6 +1119,10 @@ impl File {
|
|||||||
self.0.write_at(buf, offset)
|
self.0.write_at(buf, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
|
||||||
|
self.0.write_vectored_at(bufs, offset)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn flush(&self) -> io::Result<()> {
|
pub fn flush(&self) -> io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user