Dynamically detect presence of p{read,write}64 on Android
This commit is contained in:
parent
b3f2644b66
commit
f352f0eec0
2 changed files with 68 additions and 23 deletions
|
|
@ -28,10 +28,11 @@
|
|||
|
||||
#![cfg(target_os = "android")]
|
||||
|
||||
use libc::{c_int, sighandler_t};
|
||||
use libc::{c_int, c_void, sighandler_t, size_t, ssize_t};
|
||||
use libc::{ftruncate, pread, pwrite};
|
||||
|
||||
use io;
|
||||
use sys::cvt_r;
|
||||
use super::{cvt, cvt_r};
|
||||
|
||||
// The `log2` and `log2f` functions apparently appeared in android-18, or at
|
||||
// least you can see they're not present in the android-17 header [1] and they
|
||||
|
|
@ -99,10 +100,6 @@ pub unsafe fn signal(signum: c_int, handler: sighandler_t) -> sighandler_t {
|
|||
pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
|
||||
weak!(fn ftruncate64(c_int, i64) -> c_int);
|
||||
|
||||
extern {
|
||||
fn ftruncate(fd: c_int, off: i32) -> c_int;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
match ftruncate64.get() {
|
||||
Some(f) => cvt_r(|| f(fd, size as i64)).map(|_| ()),
|
||||
|
|
@ -117,3 +114,35 @@ pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
weak!(fn pread64(c_int, *mut c_void, size_t, i64) -> ssize_t);
|
||||
unsafe {
|
||||
pread64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
|
||||
if offset as u64 > i32::max_value() as u64 {
|
||||
Err(io::Error::new(io::Error::InvalidInput,
|
||||
"cannot pread >2GB"))
|
||||
} else {
|
||||
cvt(pread(fd, buf, count, offset as i32))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
weak!(fn pwrite64(c_int, *const c_void, size_t, i64) -> ssize_t);
|
||||
unsafe {
|
||||
pwrite64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
|
||||
if offset as u64 > i32::max_value() as u64 {
|
||||
Err(io::Error::new(io::Error::InvalidInput,
|
||||
"cannot pwrite >2GB"))
|
||||
} else {
|
||||
cvt(pwrite(fd, buf, count, offset as i32))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,26 @@ use sys::cvt;
|
|||
use sys_common::AsInner;
|
||||
use sys_common::io::read_to_end_uninitialized;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
|
||||
use libc::{pread64, pwrite64, off64_t};
|
||||
#[cfg(target_os = "android")]
|
||||
use super::android::{cvt_pread64, cvt_pwrite64};
|
||||
#[cfg(any(target_os = "linux", target_os = "emscripten"))]
|
||||
use libc::{pread64, pwrite64, off64_t, ssize_t};
|
||||
#[cfg(not(any(target_os = "linux", target_os = "emscripten", target_os = "android")))]
|
||||
use libc::{pread as pread64, pwrite as pwrite64, off_t as off64_t};
|
||||
use libc::{pread as pread64, pwrite as pwrite64, off_t as off64_t, ssize_t};
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: off64_t)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
cvt(pread64(fd, buf, count, offset))
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: off64_t)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
cvt(pwrite64(fd, buf, count, offset))
|
||||
}
|
||||
|
||||
pub struct FileDesc {
|
||||
fd: c_int,
|
||||
|
|
@ -56,13 +72,13 @@ impl FileDesc {
|
|||
}
|
||||
|
||||
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
pread64(self.fd,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len(),
|
||||
offset as off64_t)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
unsafe {
|
||||
cvt_pread64(self.fd,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len(),
|
||||
offset as off64_t)
|
||||
.map(|n| n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
|
|
@ -75,13 +91,13 @@ impl FileDesc {
|
|||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
pwrite64(self.fd,
|
||||
buf.as_ptr() as *const c_void,
|
||||
buf.len(),
|
||||
offset as off64_t)
|
||||
})?;
|
||||
Ok(ret as usize)
|
||||
unsafe {
|
||||
cvt_pwrite64(self.fd,
|
||||
buf.as_ptr() as *const c_void,
|
||||
buf.len(),
|
||||
offset as off64_t)
|
||||
.map(|n| n as usize)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_env = "newlib",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue