@@ -213,8 +213,21 @@ pub(super) use c::posix_fadvise64 as libc_posix_fadvise;
213
213
pub ( super ) use c:: { pread as libc_pread, pwrite as libc_pwrite} ;
214
214
#[ cfg( any( target_os = "android" , target_os = "linux" , target_os = "emscripten" ) ) ]
215
215
pub ( super ) use c:: { pread64 as libc_pread, pwrite64 as libc_pwrite} ;
216
+ #[ cfg( not( any(
217
+ windows,
218
+ target_os = "android" ,
219
+ target_os = "emscripten" ,
220
+ target_os = "haiku" ,
221
+ target_os = "ios" ,
222
+ target_os = "linux" ,
223
+ target_os = "macos" ,
224
+ target_os = "redox" ,
225
+ target_os = "solaris" ,
226
+ ) ) ) ]
227
+ pub ( super ) use c:: { preadv as libc_preadv, pwritev as libc_pwritev} ;
216
228
#[ cfg( any( target_os = "linux" , target_os = "emscripten" ) ) ]
217
229
pub ( super ) use c:: { preadv64 as libc_preadv, pwritev64 as libc_pwritev} ;
230
+
218
231
#[ cfg( target_os = "android" ) ]
219
232
mod readwrite_pv64 {
220
233
use super :: c;
@@ -302,20 +315,9 @@ mod readwrite_pv64 {
302
315
}
303
316
}
304
317
}
305
- #[ cfg( not( any(
306
- windows,
307
- target_os = "android" ,
308
- target_os = "emscripten" ,
309
- target_os = "haiku" ,
310
- target_os = "ios" ,
311
- target_os = "linux" ,
312
- target_os = "macos" ,
313
- target_os = "redox" ,
314
- target_os = "solaris" ,
315
- ) ) ) ]
316
- pub ( super ) use c:: { preadv as libc_preadv, pwritev as libc_pwritev} ;
317
318
#[ cfg( target_os = "android" ) ]
318
319
pub ( super ) use readwrite_pv64:: { preadv64 as libc_preadv, pwritev64 as libc_pwritev} ;
320
+
319
321
// macOS added preadv and pwritev in version 11.0
320
322
#[ cfg( any( target_os = "ios" , target_os = "macos" ) ) ]
321
323
mod readwrite_pv {
@@ -337,11 +339,104 @@ mod readwrite_pv {
337
339
) -> c:: ssize_t
338
340
}
339
341
}
340
- #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
341
- pub ( super ) use c:: { preadv64v2 as libc_preadv2, pwritev64v2 as libc_pwritev2} ;
342
342
#[ cfg( any( target_os = "ios" , target_os = "macos" ) ) ]
343
343
pub ( super ) use readwrite_pv:: { preadv as libc_preadv, pwritev as libc_pwritev} ;
344
344
345
+ // GLIBC added `preadv64v2` and `pwritev64v2` in version 2.26.
346
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
347
+ mod readwrite_pv64v2 {
348
+ use super :: c;
349
+
350
+ // 64-bit offsets on 32-bit platforms are passed in endianness-specific
351
+ // lo/hi pairs. See src/backend/linux_raw/conv.rs for details.
352
+ #[ cfg( all( target_endian = "little" , target_pointer_width = "32" ) ) ]
353
+ fn lo ( x : u64 ) -> usize {
354
+ ( x >> 32 ) as usize
355
+ }
356
+ #[ cfg( all( target_endian = "little" , target_pointer_width = "32" ) ) ]
357
+ fn hi ( x : u64 ) -> usize {
358
+ ( x & 0xffff_ffff ) as usize
359
+ }
360
+ #[ cfg( all( target_endian = "big" , target_pointer_width = "32" ) ) ]
361
+ fn lo ( x : u64 ) -> usize {
362
+ ( x & 0xffff_ffff ) as usize
363
+ }
364
+ #[ cfg( all( target_endian = "big" , target_pointer_width = "32" ) ) ]
365
+ fn hi ( x : u64 ) -> usize {
366
+ ( x >> 32 ) as usize
367
+ }
368
+
369
+ pub ( in super :: super ) unsafe fn preadv64v2 (
370
+ fd : c:: c_int ,
371
+ iov : * const c:: iovec ,
372
+ iovcnt : c:: c_int ,
373
+ offset : c:: off64_t ,
374
+ flags : c:: c_int ,
375
+ ) -> c:: ssize_t {
376
+ // Older GLIBC lacks `preadv64v2`, so use the `weak!` mechanism to
377
+ // test for it, and call back to `c::syscall`. We don't use
378
+ // `weak_or_syscall` here because we need to pass the 64-bit offset
379
+ // specially.
380
+ weak ! {
381
+ fn preadv64v2( c:: c_int, * const c:: iovec, c:: c_int, c:: off64_t, c:: c_int) -> c:: ssize_t
382
+ }
383
+ if let Some ( fun) = preadv64v2. get ( ) {
384
+ fun ( fd, iov, iovcnt, offset, flags)
385
+ } else {
386
+ #[ cfg( target_pointer_width = "32" ) ]
387
+ {
388
+ c:: syscall (
389
+ c:: SYS_preadv ,
390
+ fd,
391
+ iov,
392
+ iovcnt,
393
+ hi ( offset as u64 ) ,
394
+ lo ( offset as u64 ) ,
395
+ flags,
396
+ ) as c:: ssize_t
397
+ }
398
+ #[ cfg( target_pointer_width = "64" ) ]
399
+ {
400
+ c:: syscall ( c:: SYS_preadv2 , fd, iov, iovcnt, offset, flags) as c:: ssize_t
401
+ }
402
+ }
403
+ }
404
+ pub ( in super :: super ) unsafe fn pwritev64v2 (
405
+ fd : c:: c_int ,
406
+ iov : * const c:: iovec ,
407
+ iovcnt : c:: c_int ,
408
+ offset : c:: off64_t ,
409
+ flags : c:: c_int ,
410
+ ) -> c:: ssize_t {
411
+ // See the comments in `preadv64v2`.
412
+ weak ! {
413
+ fn pwritev64v2( c:: c_int, * const c:: iovec, c:: c_int, c:: off64_t, c:: c_int) -> c:: ssize_t
414
+ }
415
+ if let Some ( fun) = pwritev64v2. get ( ) {
416
+ fun ( fd, iov, iovcnt, offset, flags)
417
+ } else {
418
+ #[ cfg( target_pointer_width = "32" ) ]
419
+ {
420
+ c:: syscall (
421
+ c:: SYS_pwritev ,
422
+ fd,
423
+ iov,
424
+ iovcnt,
425
+ hi ( offset as u64 ) ,
426
+ lo ( offset as u64 ) ,
427
+ flags,
428
+ ) as c:: ssize_t
429
+ }
430
+ #[ cfg( target_pointer_width = "64" ) ]
431
+ {
432
+ c:: syscall ( c:: SYS_pwritev2 , fd, iov, iovcnt, offset, flags) as c:: ssize_t
433
+ }
434
+ }
435
+ }
436
+ }
437
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
438
+ pub ( super ) use readwrite_pv64v2:: { preadv64v2 as libc_preadv2, pwritev64v2 as libc_pwritev2} ;
439
+
345
440
#[ cfg( not( any(
346
441
windows,
347
442
target_os = "aix" ,
0 commit comments