mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Fix watchOS and visionOS for pread64 and pwrite64 calls
* Refactor apple OSs to use pwritev and preadv rather pwritev64 and preadv64 * Updated the comments for preadv and pwritev
This commit is contained in:
parent
38104f3a88
commit
fa53b9f39c
@ -45,13 +45,9 @@ const READ_LIMIT: usize = libc::ssize_t::MAX as usize;
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "ios",
|
||||
target_os = "tvos",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "watchos",
|
||||
target_os = "visionos",
|
||||
target_vendor = "apple",
|
||||
))]
|
||||
const fn max_iov() -> usize {
|
||||
libc::IOV_MAX as usize
|
||||
@ -72,17 +68,13 @@ const fn max_iov() -> usize {
|
||||
target_os = "dragonfly",
|
||||
target_os = "emscripten",
|
||||
target_os = "freebsd",
|
||||
target_os = "ios",
|
||||
target_os = "tvos",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "nto",
|
||||
target_os = "openbsd",
|
||||
target_os = "horizon",
|
||||
target_os = "vita",
|
||||
target_os = "watchos",
|
||||
target_os = "visionos",
|
||||
target_vendor = "apple",
|
||||
)))]
|
||||
const fn max_iov() -> usize {
|
||||
16 // The minimum value required by POSIX.
|
||||
@ -201,13 +193,10 @@ impl FileDesc {
|
||||
target_os = "fuchsia",
|
||||
target_os = "hurd",
|
||||
target_os = "illumos",
|
||||
target_os = "ios",
|
||||
target_os = "tvos",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "watchos",
|
||||
target_vendor = "apple",
|
||||
)))]
|
||||
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
|
||||
io::default_read_vectored(|b| self.read_at(b, offset), bufs)
|
||||
@ -241,15 +230,7 @@ impl FileDesc {
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
// We support old MacOS and iOS versions that do not have `preadv`. There is
|
||||
// no `syscall` possible in these platform.
|
||||
#[cfg(any(
|
||||
all(target_os = "android", target_pointer_width = "32"),
|
||||
target_os = "ios", // ios 14.0
|
||||
target_os = "tvos", // tvos 14.0
|
||||
target_os = "macos", // macos 11.0
|
||||
target_os = "watchos", // watchos 7.0
|
||||
))]
|
||||
#[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);
|
||||
|
||||
@ -269,6 +250,35 @@ impl FileDesc {
|
||||
}
|
||||
}
|
||||
|
||||
// We support old MacOS, iOS, watchOS, tvOS and visionOS. `preadv` was added in the following
|
||||
// Apple OS versions:
|
||||
// ios 14.0
|
||||
// tvos 14.0
|
||||
// macos 11.0
|
||||
// watchos 7.0
|
||||
//
|
||||
// These versions may be newer than the minimum supported versions of OS's we support so we must
|
||||
// use "weak" linking.
|
||||
#[cfg(target_vendor = "apple")]
|
||||
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
|
||||
super::weak::weak!(fn preadv(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
|
||||
|
||||
match preadv.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(
|
||||
@ -360,13 +370,10 @@ impl FileDesc {
|
||||
target_os = "fuchsia",
|
||||
target_os = "hurd",
|
||||
target_os = "illumos",
|
||||
target_os = "ios",
|
||||
target_os = "tvos",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "watchos",
|
||||
target_vendor = "apple",
|
||||
)))]
|
||||
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
|
||||
io::default_write_vectored(|b| self.write_at(b, offset), bufs)
|
||||
@ -400,15 +407,7 @@ impl FileDesc {
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
// We support old MacOS and iOS versions that do not have `pwritev`. There is
|
||||
// no `syscall` possible in these platform.
|
||||
#[cfg(any(
|
||||
all(target_os = "android", target_pointer_width = "32"),
|
||||
target_os = "ios", // ios 14.0
|
||||
target_os = "tvos", // tvos 14.0
|
||||
target_os = "macos", // macos 11.0
|
||||
target_os = "watchos", // watchos 7.0
|
||||
))]
|
||||
#[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);
|
||||
|
||||
@ -428,6 +427,35 @@ impl FileDesc {
|
||||
}
|
||||
}
|
||||
|
||||
// We support old MacOS, iOS, watchOS, tvOS and visionOS. `pwritev` was added in the following
|
||||
// Apple OS versions:
|
||||
// ios 14.0
|
||||
// tvos 14.0
|
||||
// macos 11.0
|
||||
// watchos 7.0
|
||||
//
|
||||
// These versions may be newer than the minimum supported versions of OS's we support so we must
|
||||
// use "weak" linking.
|
||||
#[cfg(target_vendor = "apple")]
|
||||
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
|
||||
super::weak::weak!(fn pwritev(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
|
||||
|
||||
match pwritev.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",
|
||||
|
@ -28,7 +28,7 @@ use crate::ptr;
|
||||
use crate::sync::atomic::{self, AtomicPtr, Ordering};
|
||||
|
||||
// We can use true weak linkage on ELF targets.
|
||||
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos")))]
|
||||
#[cfg(all(unix, not(target_vendor = "apple")))]
|
||||
pub(crate) macro weak {
|
||||
(fn $name:ident($($t:ty),*) -> $ret:ty) => (
|
||||
let ref $name: ExternWeak<unsafe extern "C" fn($($t),*) -> $ret> = {
|
||||
@ -43,7 +43,7 @@ pub(crate) macro weak {
|
||||
}
|
||||
|
||||
// On non-ELF targets, use the dlsym approximation of weak linkage.
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos"))]
|
||||
#[cfg(target_vendor = "apple")]
|
||||
pub(crate) use self::dlsym as weak;
|
||||
|
||||
pub(crate) struct ExternWeak<F: Copy> {
|
||||
|
Loading…
Reference in New Issue
Block a user