diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index 0284a428b5d74..631944ca259bf 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -54,6 +54,20 @@ pub trait FileExt { #[stable(feature = "file_offset", since = "1.15.0")] fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result; + /// 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 { + 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. /// /// 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")] fn write_at(&self, buf: &[u8], offset: u64) -> io::Result; + /// 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 { + io::default_write_vectored(|b| self.write_at(b, offset), bufs) + } + /// Attempts to write an entire buffer starting from a given offset. /// /// 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 { self.as_inner().read_at(buf, offset) } + fn read_vectored_at( + &mut self, + bufs: &mut [io::IoSliceMut<'_>], + offset: u64, + ) -> io::Result { + self.as_inner().read_vectored_at(bufs, offset) + } fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { self.as_inner().write_at(buf, offset) } + fn write_vectored_at(&mut self, bufs: &[io::IoSlice<'_>], offset: u64) -> io::Result { + self.as_inner().write_vectored_at(bufs, offset) + } } /// Unix-specific extensions to [`fs::Permissions`]. diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index 0956726084e02..43721e7081f5f 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -127,6 +127,24 @@ impl FileDesc { } } + #[cfg(not(target_os = "espidf"))] + pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { + let ret = cvt(unsafe { + libc::preadv( + self.as_raw_fd(), + bufs.as_ptr() as *const libc::iovec, + cmp::min(bufs.len(), max_iov()) as c_int, + offset as i64, + ) + })?; + Ok(ret as usize) + } + + #[cfg(target_os = "espidf")] + pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { + return crate::io::default_read_vectored(|b| self.read_at(b, offset), bufs); + } + pub fn write(&self, buf: &[u8]) -> io::Result { let ret = cvt(unsafe { libc::write( @@ -189,6 +207,24 @@ impl FileDesc { } } + #[cfg(not(target_os = "espidf"))] + pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { + let ret = cvt(unsafe { + libc::pwritev( + self.as_raw_fd(), + bufs.as_ptr() as *const libc::iovec, + cmp::min(bufs.len(), max_iov()) as c_int, + offset as i64, + ) + })?; + Ok(ret as usize) + } + + #[cfg(target_os = "espidf")] + pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { + return crate::io::default_write_vectored(|b| self.write_at(b, offset), bufs); + } + #[cfg(target_os = "linux")] pub fn get_cloexec(&self) -> io::Result { unsafe { Ok((cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) } diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index a4fff9b2e6473..3db62ba6465b5 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -864,6 +864,10 @@ impl File { self.0.read_at(buf, offset) } + pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { + self.0.read_vectored_at(bufs, offset) + } + pub fn write(&self, buf: &[u8]) -> io::Result { self.0.write(buf) } @@ -881,6 +885,10 @@ impl File { self.0.write_at(buf, offset) } + pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { + self.0.write_vectored_at(bufs, offset) + } + pub fn flush(&self) -> io::Result<()> { Ok(()) }