Skip to content

Commit ead81cf

Browse files
authored
Rollup merge of rust-lang#89518 - a1phyr:unix_file_vectored_at, r=joshtriplett
Add vectored positioned I/O on Unix Add methods for vectored I/O with an offset on `File` for `unix` under `#![feature(unix_file_vectored_at)]`. The new methods are wrappers around `preadv` and `pwritev`. Tracking issue: rust-lang#89517
2 parents 9a75781 + 2265bef commit ead81cf

File tree

3 files changed

+81
-3
lines changed

3 files changed

+81
-3
lines changed

library/std/src/os/unix/fs.rs

+34
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,20 @@ pub trait FileExt {
5454
#[stable(feature = "file_offset", since = "1.15.0")]
5555
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
5656

57+
/// Like `read_at`, except that it reads into a slice of buffers.
58+
///
59+
/// Data is copied to fill each buffer in order, with the final buffer
60+
/// written to possibly being only partially filled. This method must behave
61+
/// equivalently to a single call to read with concatenated buffers.
62+
#[unstable(feature = "unix_file_vectored_at", issue = "89517")]
63+
fn read_vectored_at(
64+
&mut self,
65+
bufs: &mut [io::IoSliceMut<'_>],
66+
offset: u64,
67+
) -> io::Result<usize> {
68+
io::default_read_vectored(|b| self.read_at(b, offset), bufs)
69+
}
70+
5771
/// Reads the exact number of byte required to fill `buf` from the given offset.
5872
///
5973
/// The offset is relative to the start of the file and thus independent
@@ -155,6 +169,16 @@ pub trait FileExt {
155169
#[stable(feature = "file_offset", since = "1.15.0")]
156170
fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
157171

172+
/// Like `write_at`, except that it writes from a slice of buffers.
173+
///
174+
/// Data is copied from each buffer in order, with the final buffer read
175+
/// from possibly being only partially consumed. This method must behave as
176+
/// a call to `write_at` with the buffers concatenated would.
177+
#[unstable(feature = "unix_file_vectored_at", issue = "89517")]
178+
fn write_vectored_at(&mut self, bufs: &[io::IoSlice<'_>], offset: u64) -> io::Result<usize> {
179+
io::default_write_vectored(|b| self.write_at(b, offset), bufs)
180+
}
181+
158182
/// Attempts to write an entire buffer starting from a given offset.
159183
///
160184
/// The offset is relative to the start of the file and thus independent
@@ -218,9 +242,19 @@ impl FileExt for fs::File {
218242
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
219243
self.as_inner().read_at(buf, offset)
220244
}
245+
fn read_vectored_at(
246+
&mut self,
247+
bufs: &mut [io::IoSliceMut<'_>],
248+
offset: u64,
249+
) -> io::Result<usize> {
250+
self.as_inner().read_vectored_at(bufs, offset)
251+
}
221252
fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
222253
self.as_inner().write_at(buf, offset)
223254
}
255+
fn write_vectored_at(&mut self, bufs: &[io::IoSlice<'_>], offset: u64) -> io::Result<usize> {
256+
self.as_inner().write_vectored_at(bufs, offset)
257+
}
224258
}
225259

226260
/// Unix-specific extensions to [`fs::Permissions`].

library/std/src/sys/unix/fd.rs

+39-3
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl FileDesc {
7676
let ret = cvt(unsafe {
7777
libc::readv(
7878
self.as_raw_fd(),
79-
bufs.as_ptr() as *const libc::iovec,
79+
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
8080
cmp::min(bufs.len(), max_iov()) as c_int,
8181
)
8282
})?;
@@ -85,7 +85,7 @@ impl FileDesc {
8585

8686
#[cfg(target_os = "espidf")]
8787
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
88-
return crate::io::default_read_vectored(|b| self.read(b), bufs);
88+
io::default_read_vectored(|b| self.read(b), bufs)
8989
}
9090

9191
#[inline]
@@ -127,6 +127,24 @@ impl FileDesc {
127127
}
128128
}
129129

130+
#[cfg(not(target_os = "espidf"))]
131+
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
132+
let ret = cvt(unsafe {
133+
libc::preadv(
134+
self.as_raw_fd(),
135+
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
136+
cmp::min(bufs.len(), max_iov()) as c_int,
137+
offset as _,
138+
)
139+
})?;
140+
Ok(ret as usize)
141+
}
142+
143+
#[cfg(target_os = "espidf")]
144+
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
145+
io::default_read_vectored(|b| self.read_at(b, offset), bufs)
146+
}
147+
130148
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
131149
let ret = cvt(unsafe {
132150
libc::write(
@@ -152,7 +170,7 @@ impl FileDesc {
152170

153171
#[cfg(target_os = "espidf")]
154172
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
155-
return crate::io::default_write_vectored(|b| self.write(b), bufs);
173+
io::default_write_vectored(|b| self.write(b), bufs)
156174
}
157175

158176
#[inline]
@@ -189,6 +207,24 @@ impl FileDesc {
189207
}
190208
}
191209

210+
#[cfg(not(target_os = "espidf"))]
211+
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
212+
let ret = cvt(unsafe {
213+
libc::pwritev(
214+
self.as_raw_fd(),
215+
bufs.as_ptr() as *const libc::iovec,
216+
cmp::min(bufs.len(), max_iov()) as c_int,
217+
offset as _,
218+
)
219+
})?;
220+
Ok(ret as usize)
221+
}
222+
223+
#[cfg(target_os = "espidf")]
224+
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
225+
io::default_write_vectored(|b| self.write_at(b, offset), bufs)
226+
}
227+
192228
#[cfg(target_os = "linux")]
193229
pub fn get_cloexec(&self) -> io::Result<bool> {
194230
unsafe { Ok((cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) }

library/std/src/sys/unix/fs.rs

+8
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,10 @@ impl File {
864864
self.0.read_at(buf, offset)
865865
}
866866

867+
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
868+
self.0.read_vectored_at(bufs, offset)
869+
}
870+
867871
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
868872
self.0.write(buf)
869873
}
@@ -881,6 +885,10 @@ impl File {
881885
self.0.write_at(buf, offset)
882886
}
883887

888+
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
889+
self.0.write_vectored_at(bufs, offset)
890+
}
891+
884892
pub fn flush(&self) -> io::Result<()> {
885893
Ok(())
886894
}

0 commit comments

Comments
 (0)