@@ -148,7 +148,6 @@ impl FileDesc {
148
148
}
149
149
150
150
#[ cfg( any(
151
- target_os = "android" ,
152
151
target_os = "emscripten" ,
153
152
target_os = "freebsd" ,
154
153
target_os = "fuchsia" ,
@@ -171,7 +170,6 @@ impl FileDesc {
171
170
}
172
171
173
172
#[ cfg( not( any(
174
- target_os = "android" ,
175
173
target_os = "emscripten" ,
176
174
target_os = "freebsd" ,
177
175
target_os = "fuchsia" ,
@@ -185,6 +183,54 @@ impl FileDesc {
185
183
io:: default_read_vectored ( |b| self . read_at ( b, offset) , bufs)
186
184
}
187
185
186
+ // We support some old Android versions that do not have `preadv` in libc,
187
+ // so we use weak linkage and fallback to a direct syscall if not available.
188
+ //
189
+ // On 32-bit targets, we don't want to deal with weird ABI issues around
190
+ // passing 64-bits parameters to syscalls, so we fallback to the default
191
+ // implementation.
192
+ #[ cfg( all( target_os = "android" , target_pointer_width = "64" ) ) ]
193
+ pub fn read_vectored_at ( & self , bufs : & mut [ IoSliceMut < ' _ > ] , offset : u64 ) -> io:: Result < usize > {
194
+ super :: weak:: syscall! {
195
+ fn preadv(
196
+ fd: libc:: c_int,
197
+ iovec: * const libc:: iovec,
198
+ n_iovec: libc:: c_int,
199
+ offset: off64_t
200
+ ) -> isize
201
+ }
202
+
203
+ let ret = cvt ( unsafe {
204
+ preadv (
205
+ self . as_raw_fd ( ) ,
206
+ bufs. as_mut_ptr ( ) as * mut libc:: iovec as * const libc:: iovec ,
207
+ cmp:: min ( bufs. len ( ) , max_iov ( ) ) as libc:: c_int ,
208
+ offset as _ ,
209
+ )
210
+ } ) ?;
211
+ Ok ( ret as usize )
212
+ }
213
+
214
+ #[ cfg( all( target_os = "android" , target_pointer_width = "32" ) ) ]
215
+ pub fn read_vectored_at ( & self , bufs : & mut [ IoSliceMut < ' _ > ] , offset : u64 ) -> io:: Result < usize > {
216
+ super :: weak:: weak!( fn preadv64( libc:: c_int, * const libc:: iovec, libc:: c_int, off64_t) -> isize ) ;
217
+
218
+ match preadv64. get ( ) {
219
+ Some ( preadv) => {
220
+ let ret = cvt ( unsafe {
221
+ preadv (
222
+ self . as_raw_fd ( ) ,
223
+ bufs. as_mut_ptr ( ) as * mut libc:: iovec as * const libc:: iovec ,
224
+ cmp:: min ( bufs. len ( ) , max_iov ( ) ) as libc:: c_int ,
225
+ offset as _ ,
226
+ )
227
+ } ) ?;
228
+ Ok ( ret as usize )
229
+ }
230
+ None => io:: default_read_vectored ( |b| self . read_at ( b, offset) , bufs) ,
231
+ }
232
+ }
233
+
188
234
pub fn write ( & self , buf : & [ u8 ] ) -> io:: Result < usize > {
189
235
let ret = cvt ( unsafe {
190
236
libc:: write (
@@ -236,7 +282,6 @@ impl FileDesc {
236
282
}
237
283
238
284
#[ cfg( any(
239
- target_os = "android" ,
240
285
target_os = "emscripten" ,
241
286
target_os = "freebsd" ,
242
287
target_os = "fuchsia" ,
@@ -259,7 +304,6 @@ impl FileDesc {
259
304
}
260
305
261
306
#[ cfg( not( any(
262
- target_os = "android" ,
263
307
target_os = "emscripten" ,
264
308
target_os = "freebsd" ,
265
309
target_os = "fuchsia" ,
@@ -273,6 +317,54 @@ impl FileDesc {
273
317
io:: default_write_vectored ( |b| self . write_at ( b, offset) , bufs)
274
318
}
275
319
320
+ // We support some old Android versions that do not have `pwritev` in libc,
321
+ // so we use weak linkage and fallback to a direct syscall if not available.
322
+ //
323
+ // On 32-bit targets, we don't want to deal with weird ABI issues around
324
+ // passing 64-bits parameters to syscalls, so we fallback to the default
325
+ // implementation.
326
+ #[ cfg( all( target_os = "android" , target_pointer_width = "64" ) ) ]
327
+ pub fn write_vectored_at ( & self , bufs : & [ IoSlice < ' _ > ] , offset : u64 ) -> io:: Result < usize > {
328
+ super :: weak:: syscall! {
329
+ fn pwritev(
330
+ fd: libc:: c_int,
331
+ iovec: * const libc:: iovec,
332
+ n_iovec: libc:: c_int,
333
+ offset: off64_t
334
+ ) -> isize
335
+ }
336
+
337
+ let ret = cvt ( unsafe {
338
+ pwritev (
339
+ self . as_raw_fd ( ) ,
340
+ bufs. as_ptr ( ) as * const libc:: iovec ,
341
+ cmp:: min ( bufs. len ( ) , max_iov ( ) ) as libc:: c_int ,
342
+ offset as _ ,
343
+ )
344
+ } ) ?;
345
+ Ok ( ret as usize )
346
+ }
347
+
348
+ #[ cfg( all( target_os = "android" , target_pointer_width = "32" ) ) ]
349
+ pub fn write_vectored_at ( & self , bufs : & [ IoSlice < ' _ > ] , offset : u64 ) -> io:: Result < usize > {
350
+ super :: weak:: weak!( fn pwritev64( libc:: c_int, * const libc:: iovec, libc:: c_int, off64_t) -> isize ) ;
351
+
352
+ match pwritev64. get ( ) {
353
+ Some ( pwritev) => {
354
+ let ret = cvt ( unsafe {
355
+ pwritev (
356
+ self . as_raw_fd ( ) ,
357
+ bufs. as_ptr ( ) as * const libc:: iovec ,
358
+ cmp:: min ( bufs. len ( ) , max_iov ( ) ) as libc:: c_int ,
359
+ offset as _ ,
360
+ )
361
+ } ) ?;
362
+ Ok ( ret as usize )
363
+ }
364
+ None => io:: default_write_vectored ( |b| self . write_at ( b, offset) , bufs) ,
365
+ }
366
+ }
367
+
276
368
#[ cfg( not( any(
277
369
target_env = "newlib" ,
278
370
target_os = "solaris" ,
0 commit comments