Use weak linkage on Android
This commit is contained in:
@@ -148,7 +148,6 @@ impl FileDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "android",
|
|
||||||
target_os = "emscripten",
|
target_os = "emscripten",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "fuchsia",
|
target_os = "fuchsia",
|
||||||
@@ -171,7 +170,6 @@ impl FileDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
target_os = "android",
|
|
||||||
target_os = "emscripten",
|
target_os = "emscripten",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "fuchsia",
|
target_os = "fuchsia",
|
||||||
@@ -185,6 +183,54 @@ impl FileDesc {
|
|||||||
io::default_read_vectored(|b| self.read_at(b, offset), bufs)
|
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> {
|
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
let ret = cvt(unsafe {
|
let ret = cvt(unsafe {
|
||||||
libc::write(
|
libc::write(
|
||||||
@@ -236,7 +282,6 @@ impl FileDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "android",
|
|
||||||
target_os = "emscripten",
|
target_os = "emscripten",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "fuchsia",
|
target_os = "fuchsia",
|
||||||
@@ -259,7 +304,6 @@ impl FileDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
target_os = "android",
|
|
||||||
target_os = "emscripten",
|
target_os = "emscripten",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "fuchsia",
|
target_os = "fuchsia",
|
||||||
@@ -273,6 +317,54 @@ impl FileDesc {
|
|||||||
io::default_write_vectored(|b| self.write_at(b, offset), bufs)
|
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(
|
#[cfg(not(any(
|
||||||
target_env = "newlib",
|
target_env = "newlib",
|
||||||
target_os = "solaris",
|
target_os = "solaris",
|
||||||
|
|||||||
Reference in New Issue
Block a user