Skip to content

Commit c9532b1

Browse files
committed
[feat: expose mknodat/mkfifoat on Apple targets (#1625)]
macOS 13 and corresponding Apple platforms added mknodat/mkfifoat. These APIs were previously excluded with cfg(not(apple)). On Apple, resolve mknodat at runtime with the same weak-linking pattern used for linkat/unlinkat/renameat. If the symbol is absent (macOS < 13 and older Apple OS variants), return NOSYS so a binary built against a newer SDK can still run on older systems. Other targets keep calling libc mknodat directly. mkfifoat goes through the same path. Also import Dev and FileType on Apple so the public wrappers compile, add XNU man-page references, and shrink the unsafe block around the syscall.
1 parent 287214b commit c9532b1

2 files changed

Lines changed: 26 additions & 11 deletions

File tree

‎src/backend/libc/fs/syscalls.rs‎

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ use crate::fs::StatFs;
5252
#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
5353
use crate::fs::Timestamps;
5454
#[cfg(not(any(
55-
apple,
5655
target_os = "espidf",
5756
target_os = "horizon",
5857
target_os = "redox",
@@ -1206,7 +1205,6 @@ pub(crate) fn chownat(
12061205
}
12071206

12081207
#[cfg(not(any(
1209-
apple,
12101208
target_os = "espidf",
12111209
target_os = "horizon",
12121210
target_os = "redox",
@@ -1220,13 +1218,29 @@ pub(crate) fn mknodat(
12201218
mode: Mode,
12211219
dev: Dev,
12221220
) -> io::Result<()> {
1221+
let dirfd = borrowed_fd(dirfd);
1222+
let pathname = c_str(path);
1223+
let mode = (mode.bits() | file_type.as_raw_mode()) as c::mode_t;
1224+
let dev = dev.try_into().map_err(|_e| io::Errno::PERM)?;
1225+
1226+
// macOS < 13.0 lacks `mknodat`.
1227+
#[cfg(apple)]
12231228
unsafe {
1224-
ret(c::mknodat(
1225-
borrowed_fd(dirfd),
1226-
c_str(path),
1227-
(mode.bits() | file_type.as_raw_mode()) as c::mode_t,
1228-
dev.try_into().map_err(|_e| io::Errno::PERM)?,
1229-
))
1229+
weak! {
1230+
fn mknodat(
1231+
c::c_int,
1232+
*const ffi::c_char,
1233+
c::mode_t,
1234+
c::dev_t
1235+
) -> c::c_int
1236+
}
1237+
let libc_mknodat = mknodat.get().ok_or(io::Errno::NOSYS)?;
1238+
ret(libc_mknodat(dirfd, pathname, mode, dev))
1239+
}
1240+
1241+
#[cfg(not(apple))]
1242+
unsafe {
1243+
ret(c::mknodat(dirfd, pathname, mode, dev))
12301244
}
12311245
}
12321246

‎src/fs/at.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use crate::fs::RenameFlags;
2121
#[cfg(not(target_os = "espidf"))]
2222
use crate::fs::Stat;
2323
#[cfg(not(any(
24-
apple,
2524
target_os = "espidf",
2625
target_os = "horizon",
2726
target_os = "vita",
@@ -466,11 +465,12 @@ pub fn fclonefileat<Fd: AsFd, DstFd: AsFd, P: path::Arg>(
466465
/// # References
467466
/// - [POSIX]
468467
/// - [Linux]
468+
/// - [Apple]
469469
///
470470
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mknodat.html
471471
/// [Linux]: https://man7.org/linux/man-pages/man2/mknodat.2.html
472+
/// [Apple]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man2/mknodat.2
472473
#[cfg(not(any(
473-
apple,
474474
target_os = "espidf",
475475
target_os = "horizon",
476476
target_os = "vita",
@@ -494,10 +494,11 @@ pub fn mknodat<P: path::Arg, Fd: AsFd>(
494494
///
495495
/// # References
496496
/// - [POSIX]
497+
/// - [Apple]
497498
///
498499
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkfifoat.html
500+
/// [Apple]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man2/mkfifoat.2
499501
#[cfg(not(any(
500-
apple,
501502
target_os = "espidf",
502503
target_os = "horizon",
503504
target_os = "vita",

0 commit comments

Comments
 (0)