Skip to content

Commit

Permalink
fcntl add F_GETPATH support for apple/netbsd/dragonfly (#2142)
Browse files Browse the repository at this point in the history
* fcntl add F_GETPATH support for apple/netbsd

* changes from review

* CHANGELOG entry

---------

Co-authored-by: SteveLauC <[email protected]>
  • Loading branch information
devnexen and SteveLauC authored Oct 3, 2023
1 parent 14a2969 commit 68c230b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))

- Added `Ipv6HopLimit` to `::nix::sys::socket::ControlMessage` for Linux,
MacOS, FreeBSD, DragonflyBSD, Android, iOS and Haiku.
([#2074](https://github.com/nix-rust/nix/pull/2074))
Expand Down
25 changes: 25 additions & 0 deletions src/fcntl.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
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;
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",
Expand Down Expand Up @@ -489,6 +503,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 = "dragonfly", target_os = "macos", target_os = "ios"))]
F_GETPATH(&'a mut PathBuf),
// TODO: Rest of flags
}

Expand Down Expand Up @@ -549,6 +565,15 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
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 = "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_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)
},
}
};

Expand Down
23 changes: 23 additions & 0 deletions test/test_fcntl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,3 +561,26 @@ mod test_posix_fallocate {
}
}
}

#[cfg(any(
target_os = "dragonfly",
target_os = "netbsd",
target_os = "macos",
target_os = "ios"
))]
#[test]
fn test_f_get_path() {
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(&mut path)).expect("get path failed");
assert_ne!(res, -1);
assert_eq!(
path.as_path().canonicalize().unwrap(),
tmp.path().canonicalize().unwrap()
);
}

0 comments on commit 68c230b

Please sign in to comment.