@@ -141,8 +141,20 @@ pub(super) use c::posix_fadvise64 as libc_posix_fadvise;
141
141
pub ( super ) use c:: { pread as libc_pread, pwrite as libc_pwrite} ;
142
142
#[ cfg( any( target_os = "android" , target_os = "linux" , target_os = "emscripten" ) ) ]
143
143
pub ( super ) use c:: { pread64 as libc_pread, pwrite64 as libc_pwrite} ;
144
+ #[ cfg( not( any(
145
+ apple,
146
+ windows,
147
+ target_os = "android" ,
148
+ target_os = "emscripten" ,
149
+ target_os = "haiku" ,
150
+ target_os = "linux" ,
151
+ target_os = "redox" ,
152
+ target_os = "solaris" ,
153
+ ) ) ) ]
154
+ pub ( super ) use c:: { preadv as libc_preadv, pwritev as libc_pwritev} ;
144
155
#[ cfg( any( target_os = "linux" , target_os = "emscripten" ) ) ]
145
156
pub ( super ) use c:: { preadv64 as libc_preadv, pwritev64 as libc_pwritev} ;
157
+
146
158
#[ cfg( target_os = "android" ) ]
147
159
mod readwrite_pv64 {
148
160
use super :: c;
@@ -230,19 +242,9 @@ mod readwrite_pv64 {
230
242
}
231
243
}
232
244
}
233
- #[ cfg( not( any(
234
- apple,
235
- windows,
236
- target_os = "android" ,
237
- target_os = "emscripten" ,
238
- target_os = "haiku" ,
239
- target_os = "linux" ,
240
- target_os = "redox" ,
241
- target_os = "solaris" ,
242
- ) ) ) ]
243
- pub ( super ) use c:: { preadv as libc_preadv, pwritev as libc_pwritev} ;
244
245
#[ cfg( target_os = "android" ) ]
245
246
pub ( super ) use readwrite_pv64:: { preadv64 as libc_preadv, pwritev64 as libc_pwritev} ;
247
+
246
248
// macOS added preadv and pwritev in version 11.0
247
249
#[ cfg( apple) ]
248
250
mod readwrite_pv {
@@ -264,11 +266,104 @@ mod readwrite_pv {
264
266
) -> c:: ssize_t
265
267
}
266
268
}
267
- #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
268
- pub ( super ) use c:: { preadv64v2 as libc_preadv2, pwritev64v2 as libc_pwritev2} ;
269
269
#[ cfg( apple) ]
270
270
pub ( super ) use readwrite_pv:: { preadv as libc_preadv, pwritev as libc_pwritev} ;
271
271
272
+ // GLIBC added `preadv64v2` and `pwritev64v2` in version 2.26.
273
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
274
+ mod readwrite_pv64v2 {
275
+ use super :: c;
276
+
277
+ // 64-bit offsets on 32-bit platforms are passed in endianness-specific
278
+ // lo/hi pairs. See src/backend/linux_raw/conv.rs for details.
279
+ #[ cfg( all( target_endian = "little" , target_pointer_width = "32" ) ) ]
280
+ fn lo ( x : u64 ) -> usize {
281
+ ( x >> 32 ) as usize
282
+ }
283
+ #[ cfg( all( target_endian = "little" , target_pointer_width = "32" ) ) ]
284
+ fn hi ( x : u64 ) -> usize {
285
+ ( x & 0xffff_ffff ) as usize
286
+ }
287
+ #[ cfg( all( target_endian = "big" , target_pointer_width = "32" ) ) ]
288
+ fn lo ( x : u64 ) -> usize {
289
+ ( x & 0xffff_ffff ) as usize
290
+ }
291
+ #[ cfg( all( target_endian = "big" , target_pointer_width = "32" ) ) ]
292
+ fn hi ( x : u64 ) -> usize {
293
+ ( x >> 32 ) as usize
294
+ }
295
+
296
+ pub ( in super :: super ) unsafe fn preadv64v2 (
297
+ fd : c:: c_int ,
298
+ iov : * const c:: iovec ,
299
+ iovcnt : c:: c_int ,
300
+ offset : c:: off64_t ,
301
+ flags : c:: c_int ,
302
+ ) -> c:: ssize_t {
303
+ // Older GLIBC lacks `preadv64v2`, so use the `weak!` mechanism to
304
+ // test for it, and call back to `c::syscall`. We don't use
305
+ // `weak_or_syscall` here because we need to pass the 64-bit offset
306
+ // specially.
307
+ weak ! {
308
+ fn preadv64v2( c:: c_int, * const c:: iovec, c:: c_int, c:: off64_t, c:: c_int) -> c:: ssize_t
309
+ }
310
+ if let Some ( fun) = preadv64v2. get ( ) {
311
+ fun ( fd, iov, iovcnt, offset, flags)
312
+ } else {
313
+ #[ cfg( target_pointer_width = "32" ) ]
314
+ {
315
+ c:: syscall (
316
+ c:: SYS_preadv ,
317
+ fd,
318
+ iov,
319
+ iovcnt,
320
+ hi ( offset as u64 ) ,
321
+ lo ( offset as u64 ) ,
322
+ flags,
323
+ ) as c:: ssize_t
324
+ }
325
+ #[ cfg( target_pointer_width = "64" ) ]
326
+ {
327
+ c:: syscall ( c:: SYS_preadv2 , fd, iov, iovcnt, offset, flags) as c:: ssize_t
328
+ }
329
+ }
330
+ }
331
+ pub ( in super :: super ) unsafe fn pwritev64v2 (
332
+ fd : c:: c_int ,
333
+ iov : * const c:: iovec ,
334
+ iovcnt : c:: c_int ,
335
+ offset : c:: off64_t ,
336
+ flags : c:: c_int ,
337
+ ) -> c:: ssize_t {
338
+ // See the comments in `preadv64v2`.
339
+ weak ! {
340
+ fn pwritev64v2( c:: c_int, * const c:: iovec, c:: c_int, c:: off64_t, c:: c_int) -> c:: ssize_t
341
+ }
342
+ if let Some ( fun) = pwritev64v2. get ( ) {
343
+ fun ( fd, iov, iovcnt, offset, flags)
344
+ } else {
345
+ #[ cfg( target_pointer_width = "32" ) ]
346
+ {
347
+ c:: syscall (
348
+ c:: SYS_pwritev ,
349
+ fd,
350
+ iov,
351
+ iovcnt,
352
+ hi ( offset as u64 ) ,
353
+ lo ( offset as u64 ) ,
354
+ flags,
355
+ ) as c:: ssize_t
356
+ }
357
+ #[ cfg( target_pointer_width = "64" ) ]
358
+ {
359
+ c:: syscall ( c:: SYS_pwritev2 , fd, iov, iovcnt, offset, flags) as c:: ssize_t
360
+ }
361
+ }
362
+ }
363
+ }
364
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
365
+ pub ( super ) use readwrite_pv64v2:: { preadv64v2 as libc_preadv2, pwritev64v2 as libc_pwritev2} ;
366
+
272
367
#[ cfg( not( any(
273
368
apple,
274
369
netbsdlike,
0 commit comments