Use weak linkage on Android
This commit is contained in:
parent
351c154cb4
commit
2fc23c2dfe
@ -148,7 +148,6 @@ impl FileDesc {
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "emscripten",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
@ -171,7 +170,6 @@ impl FileDesc {
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "android",
|
||||
target_os = "emscripten",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
@ -185,6 +183,54 @@ impl FileDesc {
|
||||
io::default_read_vectored(|b| self.read_at(b, offset), bufs)
|
||||
}
|
||||
|
||||
// We support some old Android versions that do not have `preadv` in libc,
|
||||
// so we use weak linkage and fallback to a direct syscall if not available.
|
||||
//
|
||||
// On 32-bit targets, we don't want to deal with weird ABI issues around
|
||||
// passing 64-bits parameters to syscalls, so we fallback to the default
|
||||
// implementation.
|
||||
#[cfg(all(target_os = "android", target_pointer_width = "64"))]
|
||||
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
|
||||
super::weak::syscall! {
|
||||
fn preadv(
|
||||
fd: libc::c_int,
|
||||
iovec: *const libc::iovec,
|
||||
n_iovec: libc::c_int,
|
||||
offset: off64_t
|
||||
) -> isize
|
||||
}
|
||||
|
||||
let ret = cvt(unsafe {
|
||||
preadv(
|
||||
self.as_raw_fd(),
|
||||
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
|
||||
cmp::min(bufs.len(), max_iov()) as libc::c_int,
|
||||
offset as _,
|
||||
)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
|
||||
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
|
||||
super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
|
||||
|
||||
match preadv64.get() {
|
||||
Some(preadv) => {
|
||||
let ret = cvt(unsafe {
|
||||
preadv(
|
||||
self.as_raw_fd(),
|
||||
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
|
||||
cmp::min(bufs.len(), max_iov()) as libc::c_int,
|
||||
offset as _,
|
||||
)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
None => io::default_read_vectored(|b| self.read_at(b, offset), bufs),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::write(
|
||||
@ -236,7 +282,6 @@ impl FileDesc {
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "emscripten",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
@ -259,7 +304,6 @@ impl FileDesc {
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "android",
|
||||
target_os = "emscripten",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
@ -273,6 +317,54 @@ impl FileDesc {
|
||||
io::default_write_vectored(|b| self.write_at(b, offset), bufs)
|
||||
}
|
||||
|
||||
// We support some old Android versions that do not have `pwritev` in libc,
|
||||
// so we use weak linkage and fallback to a direct syscall if not available.
|
||||
//
|
||||
// On 32-bit targets, we don't want to deal with weird ABI issues around
|
||||
// passing 64-bits parameters to syscalls, so we fallback to the default
|
||||
// implementation.
|
||||
#[cfg(all(target_os = "android", target_pointer_width = "64"))]
|
||||
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
|
||||
super::weak::syscall! {
|
||||
fn pwritev(
|
||||
fd: libc::c_int,
|
||||
iovec: *const libc::iovec,
|
||||
n_iovec: libc::c_int,
|
||||
offset: off64_t
|
||||
) -> isize
|
||||
}
|
||||
|
||||
let ret = cvt(unsafe {
|
||||
pwritev(
|
||||
self.as_raw_fd(),
|
||||
bufs.as_ptr() as *const libc::iovec,
|
||||
cmp::min(bufs.len(), max_iov()) as libc::c_int,
|
||||
offset as _,
|
||||
)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
|
||||
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
|
||||
super::weak::weak!(fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
|
||||
|
||||
match pwritev64.get() {
|
||||
Some(pwritev) => {
|
||||
let ret = cvt(unsafe {
|
||||
pwritev(
|
||||
self.as_raw_fd(),
|
||||
bufs.as_ptr() as *const libc::iovec,
|
||||
cmp::min(bufs.len(), max_iov()) as libc::c_int,
|
||||
offset as _,
|
||||
)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
}
|
||||
None => io::default_write_vectored(|b| self.write_at(b, offset), bufs),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_env = "newlib",
|
||||
target_os = "solaris",
|
||||
|
Loading…
x
Reference in New Issue
Block a user