From 4147ed90d6431ec175c8a0acce652753781aa6a4 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Wed, 4 Oct 2023 22:45:21 +0100 Subject: [PATCH] fcntl adding few apple extensions --- changelog/2155.added.md | 2 ++ src/fcntl.rs | 15 +++++++++++++++ test/test_fcntl.rs | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 changelog/2155.added.md diff --git a/changelog/2155.added.md b/changelog/2155.added.md new file mode 100644 index 0000000000..5a550c925c --- /dev/null +++ b/changelog/2155.added.md @@ -0,0 +1,2 @@ +Added `F_GETPATH_NOFIRMLINK` and `F_BARRIERFSYNC` FcntlFlags entry +on Apple for `::nix::fcntl`. diff --git a/src/fcntl.rs b/src/fcntl.rs index 0a0acd026a..2ecd0735c6 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -504,6 +504,8 @@ pub enum FcntlArg<'a> { F_GET_SEALS, #[cfg(any(target_os = "macos", target_os = "ios"))] F_FULLFSYNC, + #[cfg(any(target_os = "macos", target_os = "ios"))] + F_BARRIERFSYNC, #[cfg(any(target_os = "linux", target_os = "android"))] F_GETPIPE_SZ, #[cfg(any(target_os = "linux", target_os = "android"))] @@ -512,6 +514,8 @@ pub enum FcntlArg<'a> { F_GETPATH(&'a mut PathBuf), #[cfg(all(target_os = "freebsd", target_arch = "x86_64"))] F_KINFO(&'a mut PathBuf), + #[cfg(any(target_os = "macos", target_os = "ios"))] + F_GETPATH_NOFIRMLINK(&'a mut PathBuf), // TODO: Rest of flags } @@ -568,6 +572,8 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result { F_GET_SEALS => libc::fcntl(fd, libc::F_GET_SEALS), #[cfg(any(target_os = "macos", target_os = "ios"))] F_FULLFSYNC => libc::fcntl(fd, libc::F_FULLFSYNC), + #[cfg(any(target_os = "macos", target_os = "ios"))] + F_BARRIERFSYNC => libc::fcntl(fd, libc::F_BARRIERFSYNC), #[cfg(any(target_os = "linux", target_os = "android"))] F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ), #[cfg(any(target_os = "linux", target_os = "android"))] @@ -593,6 +599,15 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result { *path = PathBuf::from(OsString::from(optr.to_str().unwrap())); return Ok(ok_res) }, + #[cfg(any(target_os = "macos", target_os = "ios"))] + F_GETPATH_NOFIRMLINK(path) => { + let mut buffer = vec![0; libc::PATH_MAX as usize]; + let res = libc::fcntl(fd, libc::F_GETPATH_NOFIRMLINK, buffer.as_mut_ptr()); + let ok_res = Errno::result(res)?; + let optr = CStr::from_bytes_until_nul(&buffer).unwrap(); + *path = PathBuf::from(OsString::from(optr.to_str().unwrap())); + return Ok(ok_res) + }, } }; diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index cb18b2e7d9..1c5cb4f9b3 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -585,6 +585,38 @@ fn test_f_get_path() { ); } +#[cfg(any(target_os = "macos", target_os = "ios"))] +#[test] +fn test_f_get_path_nofirmlink() { + use nix::fcntl::*; + use std::{os::unix::io::AsRawFd, path::PathBuf}; + + let tmp = NamedTempFile::new().unwrap(); + let fd = tmp.as_raw_fd(); + let mut path = PathBuf::new(); + let res = fcntl(fd, FcntlArg::F_GETPATH_NOFIRMLINK(&mut path)) + .expect("get path failed"); + let mut tmpstr = String::from("/System/Volumes/Data"); + tmpstr.push_str( + &tmp.path() + .canonicalize() + .unwrap() + .into_os_string() + .into_string() + .unwrap(), + ); + assert_ne!(res, -1); + assert_eq!( + path.as_path() + .canonicalize() + .unwrap() + .into_os_string() + .into_string() + .unwrap(), + tmpstr + ); +} + #[cfg(all(target_os = "freebsd", target_arch = "x86_64"))] #[test] fn test_f_kinfo() {