diff --git a/src/backend/libc/fs/syscalls.rs b/src/backend/libc/fs/syscalls.rs index c95eaf561..7197401c6 100644 --- a/src/backend/libc/fs/syscalls.rs +++ b/src/backend/libc/fs/syscalls.rs @@ -52,7 +52,6 @@ use crate::fs::StatFs; #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] use crate::fs::Timestamps; #[cfg(not(any( - apple, target_os = "espidf", target_os = "horizon", target_os = "redox", @@ -1206,7 +1205,6 @@ pub(crate) fn chownat( } #[cfg(not(any( - apple, target_os = "espidf", target_os = "horizon", target_os = "redox", @@ -1220,13 +1218,30 @@ pub(crate) fn mknodat( mode: Mode, dev: Dev, ) -> io::Result<()> { + let dirfd = borrowed_fd(dirfd); + let pathname = c_str(path); + let mode = (mode.bits() | file_type.as_raw_mode()) as c::mode_t; + let dev = dev.try_into().map_err(|_e| io::Errno::PERM)?; + + // Apple platforms before macOS 13.0, iOS 16.0, tvOS 16.0, and watchOS 9.0 + // lack `mknodat`. + #[cfg(apple)] unsafe { - ret(c::mknodat( - borrowed_fd(dirfd), - c_str(path), - (mode.bits() | file_type.as_raw_mode()) as c::mode_t, - dev.try_into().map_err(|_e| io::Errno::PERM)?, - )) + weak! { + fn mknodat( + c::c_int, + *const ffi::c_char, + c::mode_t, + c::dev_t + ) -> c::c_int + } + let libc_mknodat = mknodat.get().ok_or(io::Errno::NOSYS)?; + ret(libc_mknodat(dirfd, pathname, mode, dev)) + } + + #[cfg(not(apple))] + unsafe { + ret(c::mknodat(dirfd, pathname, mode, dev)) } } diff --git a/src/fs/at.rs b/src/fs/at.rs index f74bd4351..8e6c86670 100644 --- a/src/fs/at.rs +++ b/src/fs/at.rs @@ -21,7 +21,6 @@ use crate::fs::RenameFlags; #[cfg(not(target_os = "espidf"))] use crate::fs::Stat; #[cfg(not(any( - apple, target_os = "espidf", target_os = "horizon", target_os = "vita", @@ -463,14 +462,21 @@ pub fn fclonefileat( /// `mknodat(dirfd, path, mode, dev)`—Creates special or normal files. /// +/// # Platform support +/// +/// On Apple platforms, this function requires macOS 13.0, iOS 16.0, +/// tvOS 16.0, or watchOS 9.0 or later. On older versions, it returns +/// [`io::Errno::NOSYS`]. +/// /// # References /// - [POSIX] /// - [Linux] +/// - [Apple] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mknodat.html /// [Linux]: https://man7.org/linux/man-pages/man2/mknodat.2.html +/// [Apple]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man2/mknodat.2 #[cfg(not(any( - apple, target_os = "espidf", target_os = "horizon", target_os = "vita", @@ -492,12 +498,19 @@ pub fn mknodat( /// `mkfifoat(dirfd, path, mode)`—Make a FIFO special file. /// +/// # Platform support +/// +/// On Apple platforms, this function requires macOS 13.0, iOS 16.0, +/// tvOS 16.0, or watchOS 9.0 or later. On older versions, it returns +/// [`io::Errno::NOSYS`]. +/// /// # References /// - [POSIX] +/// - [Apple] /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkfifoat.html +/// [Apple]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man2/mkfifoat.2 #[cfg(not(any( - apple, target_os = "espidf", target_os = "horizon", target_os = "vita",