From b590fee1773ffe486be0b29a25fbe9c77bef968f Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sat, 30 Sep 2023 20:43:04 +0100 Subject: [PATCH 1/3] fcntl add F_GETPATH support for apple/netbsd --- src/fcntl.rs | 7 +++++++ test/test_fcntl.rs | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/fcntl.rs b/src/fcntl.rs index 1ee8c96352..6e80d1e472 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -489,6 +489,8 @@ pub enum FcntlArg<'a> { F_GETPIPE_SZ, #[cfg(any(target_os = "linux", target_os = "android"))] F_SETPIPE_SZ(c_int), + #[cfg(any(target_os = "netbsd", target_os = "macos", target_os = "ios"))] + F_GETPATH(Vec), // TODO: Rest of flags } @@ -549,6 +551,11 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result { F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ), #[cfg(any(target_os = "linux", target_os = "android"))] F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size), + #[cfg(any(target_os = "netbsd", target_os = "macos", target_os = "ios"))] + F_GETPATH(path) => { + path.resize(libc::PATH_MAX); + libc::fcntl(fd, libc::F_GETPATH, path.as_ptr()) + }, } }; diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index 45698490b6..20e6d9965d 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -561,3 +561,21 @@ mod test_posix_fallocate { } } } + +#[test] +#[cfg(any(target_os = "netbsd", target_os = "macos", target_os = "ios"))] +mod test_apple_netbsd { + use nix::fcntl::*; + use tempfile::NamedTempFile; + + #[test] + fn test_path() { + let mut tmp = NamedTempFile::new().unwrap(); + let fd = tmp.as_raw_fd(); + let mut path: Vec = Vec::new(); + let res = fcntl(fd, FcntlArg::F_GETPATH(path)).expect("get path failed"); + assert_eq!( + path.len() > 0 + ); + } +} From ed051c7c9178913324b63b77733eb1020cf535f8 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sun, 1 Oct 2023 08:40:30 +0100 Subject: [PATCH 2/3] changes from review --- src/fcntl.rs | 23 ++++++++++++++++++----- test/test_fcntl.rs | 22 ++++++++++++++-------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/fcntl.rs b/src/fcntl.rs index 6e80d1e472..4033150f06 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -6,6 +6,13 @@ use std::os::raw; use std::os::unix::ffi::OsStringExt; use std::os::unix::io::RawFd; // For splice and copy_file_range +#[cfg(any( + target_os = "netbsd", + target_os = "macos", + target_os = "ios", + target_os = "dragonfly", +))] +use std::path::PathBuf; #[cfg(any( target_os = "android", target_os = "freebsd", @@ -489,8 +496,8 @@ pub enum FcntlArg<'a> { F_GETPIPE_SZ, #[cfg(any(target_os = "linux", target_os = "android"))] F_SETPIPE_SZ(c_int), - #[cfg(any(target_os = "netbsd", target_os = "macos", target_os = "ios"))] - F_GETPATH(Vec), + #[cfg(any(target_os = "netbsd", target_os = "dragonfly", target_os = "macos", target_os = "ios"))] + F_GETPATH(&'a mut PathBuf), // TODO: Rest of flags } @@ -551,10 +558,16 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result { F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ), #[cfg(any(target_os = "linux", target_os = "android"))] F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size), - #[cfg(any(target_os = "netbsd", target_os = "macos", target_os = "ios"))] + #[cfg(any(target_os = "dragonfly", target_os = "netbsd", target_os = "macos", target_os = "ios"))] F_GETPATH(path) => { - path.resize(libc::PATH_MAX); - libc::fcntl(fd, libc::F_GETPATH, path.as_ptr()) + let mut buffer = vec![0; libc::PATH_MAX as usize]; + let res = libc::fcntl(fd, libc::F_GETPATH, buffer.as_ptr()); + let ok_res = Errno::result(res)?; + let len = buffer.iter().position(|b| *b == 0).unwrap(); + buffer.truncate(len as usize); + buffer.shrink_to_fit(); + *path = PathBuf::from(OsString::from_vec(buffer)); + ok_res }, } }; diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index 20e6d9965d..29e5154e5f 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -562,20 +562,26 @@ mod test_posix_fallocate { } } -#[test] -#[cfg(any(target_os = "netbsd", target_os = "macos", target_os = "ios"))] +#[cfg(any( + target_os = "dragonfly", + target_os = "netbsd", + target_os = "macos", + target_os = "ios" +))] mod test_apple_netbsd { use nix::fcntl::*; + use std::os::unix::io::AsRawFd; + use std::path::PathBuf; use tempfile::NamedTempFile; #[test] fn test_path() { - let mut tmp = NamedTempFile::new().unwrap(); + let tmp = NamedTempFile::new().unwrap(); let fd = tmp.as_raw_fd(); - let mut path: Vec = Vec::new(); - let res = fcntl(fd, FcntlArg::F_GETPATH(path)).expect("get path failed"); - assert_eq!( - path.len() > 0 - ); + let mut path = PathBuf::new(); + let res = + fcntl(fd, FcntlArg::F_GETPATH(&mut path)).expect("get path failed"); + assert_ne!(res, -1); + assert_eq!(path, tmp.path()); } } From 4ebb41e864b60583a766d1320d52c48c311a4bfe Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sun, 1 Oct 2023 11:06:02 +0100 Subject: [PATCH 3/3] CHANGELOG entry --- CHANGELOG.md | 3 +++ src/fcntl.rs | 17 +++++++++++------ test/test_fcntl.rs | 29 ++++++++++++++--------------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2406958e0f..e3286bc059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,9 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Added `Icmp` and `IcmpV6` to `SockProtocol`. (#[2103](https://github.com/nix-rust/nix/pull/2103)) +- Added `F_GETPATH` FcntlFlags entry on Apple/NetBSD/DragonflyBSD for `::nix::fcntl`. + ([#2142](https://github.com/nix-rust/nix/pull/2142)) + ## [0.27.1] - 2023-08-28 ### Fixed diff --git a/src/fcntl.rs b/src/fcntl.rs index 4033150f06..a711a41170 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -1,5 +1,12 @@ use crate::errno::Errno; use libc::{self, c_int, c_uint, size_t, ssize_t}; +#[cfg(any( + target_os = "netbsd", + target_os = "macos", + target_os = "ios", + target_os = "dragonfly", +))] +use std::ffi::CStr; use std::ffi::OsString; #[cfg(not(target_os = "redox"))] use std::os::raw; @@ -561,13 +568,11 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result { #[cfg(any(target_os = "dragonfly", target_os = "netbsd", target_os = "macos", target_os = "ios"))] F_GETPATH(path) => { let mut buffer = vec![0; libc::PATH_MAX as usize]; - let res = libc::fcntl(fd, libc::F_GETPATH, buffer.as_ptr()); + let res = libc::fcntl(fd, libc::F_GETPATH, buffer.as_mut_ptr()); let ok_res = Errno::result(res)?; - let len = buffer.iter().position(|b| *b == 0).unwrap(); - buffer.truncate(len as usize); - buffer.shrink_to_fit(); - *path = PathBuf::from(OsString::from_vec(buffer)); - ok_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 29e5154e5f..0faf39d237 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -568,20 +568,19 @@ mod test_posix_fallocate { target_os = "macos", target_os = "ios" ))] -mod test_apple_netbsd { +#[test] +fn test_f_get_path() { use nix::fcntl::*; - use std::os::unix::io::AsRawFd; - use std::path::PathBuf; - use tempfile::NamedTempFile; - - #[test] - fn test_path() { - let tmp = NamedTempFile::new().unwrap(); - let fd = tmp.as_raw_fd(); - let mut path = PathBuf::new(); - let res = - fcntl(fd, FcntlArg::F_GETPATH(&mut path)).expect("get path failed"); - assert_ne!(res, -1); - assert_eq!(path, tmp.path()); - } + 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(&mut path)).expect("get path failed"); + assert_ne!(res, -1); + assert_eq!( + path.as_path().canonicalize().unwrap(), + tmp.path().canonicalize().unwrap() + ); }