Auto merge of #89518 - a1phyr:unix_file_vectored_at, r=workingjubilee · rust-lang/rust@0fbfc3e (original) (raw)
`@@ -98,7 +98,7 @@ impl FileDesc {
`
98
98
`let ret = cvt(unsafe {
`
99
99
` libc::readv(
`
100
100
`self.as_raw_fd(),
`
101
``
`-
bufs.as_ptr() as *const libc::iovec,
`
``
101
`+
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
`
102
102
` cmp::min(bufs.len(), max_iov()) as libc::c_int,
`
103
103
`)
`
104
104
`})?;
`
`@@ -107,7 +107,7 @@ impl FileDesc {
`
107
107
``
108
108
`#[cfg(any(target_os = "espidf", target_os = "horizon"))]
`
109
109
`pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result {
`
110
``
`-
return crate::io::default_read_vectored(|b| self.read(b), bufs);
`
``
110
`+
io::default_read_vectored(|b| self.read(b), bufs)
`
111
111
`}
`
112
112
``
113
113
`#[inline]
`
`@@ -153,6 +153,95 @@ impl FileDesc {
`
153
153
`Ok(())
`
154
154
`}
`
155
155
``
``
156
`+
#[cfg(any(
`
``
157
`+
target_os = "emscripten",
`
``
158
`+
target_os = "freebsd",
`
``
159
`+
target_os = "fuchsia",
`
``
160
`+
target_os = "illumos",
`
``
161
`+
target_os = "linux",
`
``
162
`+
target_os = "netbsd",
`
``
163
`+
))]
`
``
164
`+
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result {
`
``
165
`+
let ret = cvt(unsafe {
`
``
166
`+
libc::preadv(
`
``
167
`+
self.as_raw_fd(),
`
``
168
`+
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
`
``
169
`+
cmp::min(bufs.len(), max_iov()) as libc::c_int,
`
``
170
`+
offset as _,
`
``
171
`+
)
`
``
172
`+
})?;
`
``
173
`+
Ok(ret as usize)
`
``
174
`+
}
`
``
175
+
``
176
`+
#[cfg(not(any(
`
``
177
`+
target_os = "android",
`
``
178
`+
target_os = "emscripten",
`
``
179
`+
target_os = "freebsd",
`
``
180
`+
target_os = "fuchsia",
`
``
181
`+
target_os = "illumos",
`
``
182
`+
target_os = "ios",
`
``
183
`+
target_os = "linux",
`
``
184
`+
target_os = "macos",
`
``
185
`+
target_os = "netbsd",
`
``
186
`+
)))]
`
``
187
`+
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result {
`
``
188
`+
io::default_read_vectored(|b| self.read_at(b, offset), bufs)
`
``
189
`+
}
`
``
190
+
``
191
`` +
// We support some old Android versions that do not have preadv
in libc,
``
``
192
`+
// so we use weak linkage and fallback to a direct syscall if not available.
`
``
193
`+
//
`
``
194
`+
// On 32-bit targets, we don't want to deal with weird ABI issues around
`
``
195
`+
// passing 64-bits parameters to syscalls, so we fallback to the default
`
``
196
`` +
// implementation if preadv
is not available.
``
``
197
`+
#[cfg(all(target_os = "android", target_pointer_width = "64"))]
`
``
198
`+
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result {
`
``
199
`+
super::weak::syscall! {
`
``
200
`+
fn preadv(
`
``
201
`+
fd: libc::c_int,
`
``
202
`+
iovec: *const libc::iovec,
`
``
203
`+
n_iovec: libc::c_int,
`
``
204
`+
offset: off64_t
`
``
205
`+
) -> isize
`
``
206
`+
}
`
``
207
+
``
208
`+
let ret = cvt(unsafe {
`
``
209
`+
preadv(
`
``
210
`+
self.as_raw_fd(),
`
``
211
`+
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
`
``
212
`+
cmp::min(bufs.len(), max_iov()) as libc::c_int,
`
``
213
`+
offset as _,
`
``
214
`+
)
`
``
215
`+
})?;
`
``
216
`+
Ok(ret as usize)
`
``
217
`+
}
`
``
218
+
``
219
`` +
// We support old MacOS and iOS versions that do not have preadv
. There is
``
``
220
`` +
// no syscall
possible in these platform.
``
``
221
`+
#[cfg(any(
`
``
222
`+
all(target_os = "android", target_pointer_width = "32"),
`
``
223
`+
target_os = "ios",
`
``
224
`+
target_os = "macos",
`
``
225
`+
))]
`
``
226
`+
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result {
`
``
227
`+
super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
`
``
228
+
``
229
`+
match preadv64.get() {
`
``
230
`+
Some(preadv) => {
`
``
231
`+
let ret = cvt(unsafe {
`
``
232
`+
preadv(
`
``
233
`+
self.as_raw_fd(),
`
``
234
`+
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
`
``
235
`+
cmp::min(bufs.len(), max_iov()) as libc::c_int,
`
``
236
`+
offset as _,
`
``
237
`+
)
`
``
238
`+
})?;
`
``
239
`+
Ok(ret as usize)
`
``
240
`+
}
`
``
241
`+
None => io::default_read_vectored(|b| self.read_at(b, offset), bufs),
`
``
242
`+
}
`
``
243
`+
}
`
``
244
+
156
245
`pub fn write(&self, buf: &[u8]) -> io::Result {
`
157
246
`let ret = cvt(unsafe {
`
158
247
` libc::write(
`
`@@ -178,7 +267,7 @@ impl FileDesc {
`
178
267
``
179
268
`#[cfg(any(target_os = "espidf", target_os = "horizon"))]
`
180
269
`pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result {
`
181
``
`-
return crate::io::default_write_vectored(|b| self.write(b), bufs);
`
``
270
`+
io::default_write_vectored(|b| self.write(b), bufs)
`
182
271
`}
`
183
272
``
184
273
`#[inline]
`
`@@ -203,6 +292,95 @@ impl FileDesc {
`
203
292
`}
`
204
293
`}
`
205
294
``
``
295
`+
#[cfg(any(
`
``
296
`+
target_os = "emscripten",
`
``
297
`+
target_os = "freebsd",
`
``
298
`+
target_os = "fuchsia",
`
``
299
`+
target_os = "illumos",
`
``
300
`+
target_os = "linux",
`
``
301
`+
target_os = "netbsd",
`
``
302
`+
))]
`
``
303
`+
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result {
`
``
304
`+
let ret = cvt(unsafe {
`
``
305
`+
libc::pwritev(
`
``
306
`+
self.as_raw_fd(),
`
``
307
`+
bufs.as_ptr() as *const libc::iovec,
`
``
308
`+
cmp::min(bufs.len(), max_iov()) as libc::c_int,
`
``
309
`+
offset as _,
`
``
310
`+
)
`
``
311
`+
})?;
`
``
312
`+
Ok(ret as usize)
`
``
313
`+
}
`
``
314
+
``
315
`+
#[cfg(not(any(
`
``
316
`+
target_os = "android",
`
``
317
`+
target_os = "emscripten",
`
``
318
`+
target_os = "freebsd",
`
``
319
`+
target_os = "fuchsia",
`
``
320
`+
target_os = "illumos",
`
``
321
`+
target_os = "ios",
`
``
322
`+
target_os = "linux",
`
``
323
`+
target_os = "macos",
`
``
324
`+
target_os = "netbsd",
`
``
325
`+
)))]
`
``
326
`+
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result {
`
``
327
`+
io::default_write_vectored(|b| self.write_at(b, offset), bufs)
`
``
328
`+
}
`
``
329
+
``
330
`` +
// We support some old Android versions that do not have pwritev
in libc,
``
``
331
`+
// so we use weak linkage and fallback to a direct syscall if not available.
`
``
332
`+
//
`
``
333
`+
// On 32-bit targets, we don't want to deal with weird ABI issues around
`
``
334
`+
// passing 64-bits parameters to syscalls, so we fallback to the default
`
``
335
`` +
// implementation if pwritev
is not available.
``
``
336
`+
#[cfg(all(target_os = "android", target_pointer_width = "64"))]
`
``
337
`+
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result {
`
``
338
`+
super::weak::syscall! {
`
``
339
`+
fn pwritev(
`
``
340
`+
fd: libc::c_int,
`
``
341
`+
iovec: *const libc::iovec,
`
``
342
`+
n_iovec: libc::c_int,
`
``
343
`+
offset: off64_t
`
``
344
`+
) -> isize
`
``
345
`+
}
`
``
346
+
``
347
`+
let ret = cvt(unsafe {
`
``
348
`+
pwritev(
`
``
349
`+
self.as_raw_fd(),
`
``
350
`+
bufs.as_ptr() as *const libc::iovec,
`
``
351
`+
cmp::min(bufs.len(), max_iov()) as libc::c_int,
`
``
352
`+
offset as _,
`
``
353
`+
)
`
``
354
`+
})?;
`
``
355
`+
Ok(ret as usize)
`
``
356
`+
}
`
``
357
+
``
358
`` +
// We support old MacOS and iOS versions that do not have pwritev
. There is
``
``
359
`` +
// no syscall
possible in these platform.
``
``
360
`+
#[cfg(any(
`
``
361
`+
all(target_os = "android", target_pointer_width = "32"),
`
``
362
`+
target_os = "ios",
`
``
363
`+
target_os = "macos",
`
``
364
`+
))]
`
``
365
`+
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result {
`
``
366
`+
super::weak::weak!(fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
`
``
367
+
``
368
`+
match pwritev64.get() {
`
``
369
`+
Some(pwritev) => {
`
``
370
`+
let ret = cvt(unsafe {
`
``
371
`+
pwritev(
`
``
372
`+
self.as_raw_fd(),
`
``
373
`+
bufs.as_ptr() as *const libc::iovec,
`
``
374
`+
cmp::min(bufs.len(), max_iov()) as libc::c_int,
`
``
375
`+
offset as _,
`
``
376
`+
)
`
``
377
`+
})?;
`
``
378
`+
Ok(ret as usize)
`
``
379
`+
}
`
``
380
`+
None => io::default_write_vectored(|b| self.write_at(b, offset), bufs),
`
``
381
`+
}
`
``
382
`+
}
`
``
383
+
206
384
`#[cfg(not(any(
`
207
385
` target_env = "newlib",
`
208
386
` target_os = "solaris",
`