Skip to content

Commit d11afab

Browse files
Rollup merge of rust-lang#124089 - simlay:fix-preadv64-and-pwritev64-link-for-watchos-and-visionos, r=workingjubilee
Fix watchOS and visionOS for pread64 and pwrite64 calls In rust-lang#122880, links to `preadv64` and `pwritev64` were added for `watchOS` however the underlying [`weak!` macro did not include `target_os = "watchos"`](https://github.com/rust-lang/rust/blob/c45dee5efd0c042e9d1e24559ebd0d6424d8aa70/library/std/src/sys/pal/unix/weak.rs#L30-L74). This resulted in an `xcodebuild` error when targeting `watchOS`: ``` Undefined symbols for architecture arm64: "_preadv64", referenced from: __rust_extern_with_linkage_preadv64 in libliveview_native_core.a[274](std-324fdd8d31e8eaa2.std.e18cf7e8d0336778-cgu.08.rcgu.o) "_pwritev64", referenced from: __rust_extern_with_linkage_pwritev64 in libliveview_native_core.a[274](std-324fdd8d31e8eaa2.std.e18cf7e8d0336778-cgu.08.rcgu.o) ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) ``` So I added them. I also went ahead and added the same for visionOS because it's bound to create the same issue.
2 parents 1602a46 + bab3c02 commit d11afab

File tree

2 files changed

+66
-38
lines changed

2 files changed

+66
-38
lines changed

std/src/sys/pal/unix/fd.rs

+64-36
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,9 @@ const READ_LIMIT: usize = libc::ssize_t::MAX as usize;
4545
#[cfg(any(
4646
target_os = "dragonfly",
4747
target_os = "freebsd",
48-
target_os = "ios",
49-
target_os = "tvos",
50-
target_os = "macos",
5148
target_os = "netbsd",
5249
target_os = "openbsd",
53-
target_os = "watchos",
54-
target_os = "visionos",
50+
target_vendor = "apple",
5551
))]
5652
const fn max_iov() -> usize {
5753
libc::IOV_MAX as usize
@@ -72,17 +68,13 @@ const fn max_iov() -> usize {
7268
target_os = "dragonfly",
7369
target_os = "emscripten",
7470
target_os = "freebsd",
75-
target_os = "ios",
76-
target_os = "tvos",
7771
target_os = "linux",
78-
target_os = "macos",
7972
target_os = "netbsd",
8073
target_os = "nto",
8174
target_os = "openbsd",
8275
target_os = "horizon",
8376
target_os = "vita",
84-
target_os = "watchos",
85-
target_os = "visionos",
77+
target_vendor = "apple",
8678
)))]
8779
const fn max_iov() -> usize {
8880
16 // The minimum value required by POSIX.
@@ -201,13 +193,10 @@ impl FileDesc {
201193
target_os = "fuchsia",
202194
target_os = "hurd",
203195
target_os = "illumos",
204-
target_os = "ios",
205-
target_os = "tvos",
206196
target_os = "linux",
207-
target_os = "macos",
208197
target_os = "netbsd",
209198
target_os = "openbsd",
210-
target_os = "watchos",
199+
target_vendor = "apple",
211200
)))]
212201
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
213202
io::default_read_vectored(|b| self.read_at(b, offset), bufs)
@@ -241,15 +230,7 @@ impl FileDesc {
241230
Ok(ret as usize)
242231
}
243232

244-
// We support old MacOS and iOS versions that do not have `preadv`. There is
245-
// no `syscall` possible in these platform.
246-
#[cfg(any(
247-
all(target_os = "android", target_pointer_width = "32"),
248-
target_os = "ios", // ios 14.0
249-
target_os = "tvos", // tvos 14.0
250-
target_os = "macos", // macos 11.0
251-
target_os = "watchos", // watchos 7.0
252-
))]
233+
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
253234
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
254235
super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
255236

@@ -269,6 +250,35 @@ impl FileDesc {
269250
}
270251
}
271252

253+
// We support old MacOS, iOS, watchOS, tvOS and visionOS. `preadv` was added in the following
254+
// Apple OS versions:
255+
// ios 14.0
256+
// tvos 14.0
257+
// macos 11.0
258+
// watchos 7.0
259+
//
260+
// These versions may be newer than the minimum supported versions of OS's we support so we must
261+
// use "weak" linking.
262+
#[cfg(target_vendor = "apple")]
263+
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
264+
super::weak::weak!(fn preadv(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
265+
266+
match preadv.get() {
267+
Some(preadv) => {
268+
let ret = cvt(unsafe {
269+
preadv(
270+
self.as_raw_fd(),
271+
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
272+
cmp::min(bufs.len(), max_iov()) as libc::c_int,
273+
offset as _,
274+
)
275+
})?;
276+
Ok(ret as usize)
277+
}
278+
None => io::default_read_vectored(|b| self.read_at(b, offset), bufs),
279+
}
280+
}
281+
272282
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
273283
let ret = cvt(unsafe {
274284
libc::write(
@@ -360,13 +370,10 @@ impl FileDesc {
360370
target_os = "fuchsia",
361371
target_os = "hurd",
362372
target_os = "illumos",
363-
target_os = "ios",
364-
target_os = "tvos",
365373
target_os = "linux",
366-
target_os = "macos",
367374
target_os = "netbsd",
368375
target_os = "openbsd",
369-
target_os = "watchos",
376+
target_vendor = "apple",
370377
)))]
371378
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
372379
io::default_write_vectored(|b| self.write_at(b, offset), bufs)
@@ -400,15 +407,7 @@ impl FileDesc {
400407
Ok(ret as usize)
401408
}
402409

403-
// We support old MacOS and iOS versions that do not have `pwritev`. There is
404-
// no `syscall` possible in these platform.
405-
#[cfg(any(
406-
all(target_os = "android", target_pointer_width = "32"),
407-
target_os = "ios", // ios 14.0
408-
target_os = "tvos", // tvos 14.0
409-
target_os = "macos", // macos 11.0
410-
target_os = "watchos", // watchos 7.0
411-
))]
410+
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
412411
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
413412
super::weak::weak!(fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
414413

@@ -428,6 +427,35 @@ impl FileDesc {
428427
}
429428
}
430429

430+
// We support old MacOS, iOS, watchOS, tvOS and visionOS. `pwritev` was added in the following
431+
// Apple OS versions:
432+
// ios 14.0
433+
// tvos 14.0
434+
// macos 11.0
435+
// watchos 7.0
436+
//
437+
// These versions may be newer than the minimum supported versions of OS's we support so we must
438+
// use "weak" linking.
439+
#[cfg(target_vendor = "apple")]
440+
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
441+
super::weak::weak!(fn pwritev(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);
442+
443+
match pwritev.get() {
444+
Some(pwritev) => {
445+
let ret = cvt(unsafe {
446+
pwritev(
447+
self.as_raw_fd(),
448+
bufs.as_ptr() as *const libc::iovec,
449+
cmp::min(bufs.len(), max_iov()) as libc::c_int,
450+
offset as _,
451+
)
452+
})?;
453+
Ok(ret as usize)
454+
}
455+
None => io::default_write_vectored(|b| self.write_at(b, offset), bufs),
456+
}
457+
}
458+
431459
#[cfg(not(any(
432460
target_env = "newlib",
433461
target_os = "solaris",

std/src/sys/pal/unix/weak.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::ptr;
2828
use crate::sync::atomic::{self, AtomicPtr, Ordering};
2929

3030
// We can use true weak linkage on ELF targets.
31-
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos")))]
31+
#[cfg(all(unix, not(target_vendor = "apple")))]
3232
pub(crate) macro weak {
3333
(fn $name:ident($($t:ty),*) -> $ret:ty) => (
3434
let ref $name: ExternWeak<unsafe extern "C" fn($($t),*) -> $ret> = {
@@ -43,7 +43,7 @@ pub(crate) macro weak {
4343
}
4444

4545
// On non-ELF targets, use the dlsym approximation of weak linkage.
46-
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos"))]
46+
#[cfg(target_vendor = "apple")]
4747
pub(crate) use self::dlsym as weak;
4848

4949
pub(crate) struct ExternWeak<F: Copy> {

0 commit comments

Comments
 (0)