diff options
| author | Tobias Bucher <tobiasbucher5991@gmail.com> | 2016-10-08 14:32:57 +0200 |
|---|---|---|
| committer | Tobias Bucher <tobiasbucher5991@gmail.com> | 2016-10-09 10:48:07 +0200 |
| commit | f352f0eec010ff2814ca27ac0e5a84cd533f2918 (patch) | |
| tree | 958c4e7aa408fbed0f53e76cd066fad8d1974a71 /src/libstd/sys | |
| parent | b3f2644b66647d47338051d783cae8e661312472 (diff) | |
| download | rust-f352f0eec010ff2814ca27ac0e5a84cd533f2918.tar.gz rust-f352f0eec010ff2814ca27ac0e5a84cd533f2918.zip | |
Dynamically detect presence of `p{read,write}64` on Android
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/unix/android.rs | 41 | ||||
| -rw-r--r-- | src/libstd/sys/unix/fd.rs | 50 |
2 files changed, 68 insertions, 23 deletions
diff --git a/src/libstd/sys/unix/android.rs b/src/libstd/sys/unix/android.rs index abbe3fc1846..08e6b45dcd3 100644 --- a/src/libstd/sys/unix/android.rs +++ b/src/libstd/sys/unix/android.rs @@ -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)) + } + }) + } +} diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 4f92c3274d2..30573d695aa 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -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", |
