Skip to content

Commit cdce881

Browse files
committed
Expose mknodat and mkfifoat on Apple targets
Weak-link mknodat on Apple and return NOSYS when unavailable on older systems. Keep direct libc calls on other targets.
1 parent 287214b commit cdce881

2 files changed

Lines changed: 39 additions & 11 deletions

File tree

src/backend/libc/fs/syscalls.rs

Lines changed: 23 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,30 @@ 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+
// Apple platforms before macOS 13.0, iOS 16.0, tvOS 16.0, and watchOS 9.0
1227+
// lack `mknodat`.
1228+
#[cfg(apple)]
12231229
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-
))
1230+
weak! {
1231+
fn mknodat(
1232+
c::c_int,
1233+
*const ffi::c_char,
1234+
c::mode_t,
1235+
c::dev_t
1236+
) -> c::c_int
1237+
}
1238+
let libc_mknodat = mknodat.get().ok_or(io::Errno::NOSYS)?;
1239+
ret(libc_mknodat(dirfd, pathname, mode, dev))
1240+
}
1241+
1242+
#[cfg(not(apple))]
1243+
unsafe {
1244+
ret(c::mknodat(dirfd, pathname, mode, dev))
12301245
}
12311246
}
12321247

src/fs/at.rs

Lines changed: 16 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",
@@ -463,14 +462,21 @@ pub fn fclonefileat<Fd: AsFd, DstFd: AsFd, P: path::Arg>(
463462

464463
/// `mknodat(dirfd, path, mode, dev)`—Creates special or normal files.
465464
///
465+
/// # Platform support
466+
///
467+
/// On Apple platforms, this function requires macOS 13.0, iOS 16.0,
468+
/// tvOS 16.0, or watchOS 9.0 or later. On older versions, it returns
469+
/// [`io::Errno::NOSYS`].
470+
///
466471
/// # References
467472
/// - [POSIX]
468473
/// - [Linux]
474+
/// - [Apple]
469475
///
470476
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mknodat.html
471477
/// [Linux]: https://man7.org/linux/man-pages/man2/mknodat.2.html
478+
/// [Apple]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man2/mknodat.2
472479
#[cfg(not(any(
473-
apple,
474480
target_os = "espidf",
475481
target_os = "horizon",
476482
target_os = "vita",
@@ -492,12 +498,19 @@ pub fn mknodat<P: path::Arg, Fd: AsFd>(
492498

493499
/// `mkfifoat(dirfd, path, mode)`—Make a FIFO special file.
494500
///
501+
/// # Platform support
502+
///
503+
/// On Apple platforms, this function requires macOS 13.0, iOS 16.0,
504+
/// tvOS 16.0, or watchOS 9.0 or later. On older versions, it returns
505+
/// [`io::Errno::NOSYS`].
506+
///
495507
/// # References
496508
/// - [POSIX]
509+
/// - [Apple]
497510
///
498511
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkfifoat.html
512+
/// [Apple]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man2/mkfifoat.2
499513
#[cfg(not(any(
500-
apple,
501514
target_os = "espidf",
502515
target_os = "horizon",
503516
target_os = "vita",

0 commit comments

Comments
 (0)