Skip to content

Commit 68c230b

Browse files
devnexenSteveLauC
andauthored
fcntl add F_GETPATH support for apple/netbsd/dragonfly (#2142)
* fcntl add F_GETPATH support for apple/netbsd * changes from review * CHANGELOG entry --------- Co-authored-by: SteveLauC <[email protected]>
1 parent 14a2969 commit 68c230b

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ This project adheres to [Semantic Versioning](https://semver.org/).
4949
- Added `Icmp` and `IcmpV6` to `SockProtocol`.
5050
(#[2103](https://github.com/nix-rust/nix/pull/2103))
5151

52+
- Added `F_GETPATH` FcntlFlags entry on Apple/NetBSD/DragonflyBSD for `::nix::fcntl`.
53+
([#2142](https://github.com/nix-rust/nix/pull/2142))
54+
5255
- Added `Ipv6HopLimit` to `::nix::sys::socket::ControlMessage` for Linux,
5356
MacOS, FreeBSD, DragonflyBSD, Android, iOS and Haiku.
5457
([#2074](https://github.com/nix-rust/nix/pull/2074))

src/fcntl.rs

+25
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
use crate::errno::Errno;
22
use libc::{self, c_int, c_uint, size_t, ssize_t};
3+
#[cfg(any(
4+
target_os = "netbsd",
5+
target_os = "macos",
6+
target_os = "ios",
7+
target_os = "dragonfly",
8+
))]
9+
use std::ffi::CStr;
310
use std::ffi::OsString;
411
#[cfg(not(target_os = "redox"))]
512
use std::os::raw;
613
use std::os::unix::ffi::OsStringExt;
714
use std::os::unix::io::RawFd;
815
// For splice and copy_file_range
16+
#[cfg(any(
17+
target_os = "netbsd",
18+
target_os = "macos",
19+
target_os = "ios",
20+
target_os = "dragonfly",
21+
))]
22+
use std::path::PathBuf;
923
#[cfg(any(
1024
target_os = "android",
1125
target_os = "freebsd",
@@ -489,6 +503,8 @@ pub enum FcntlArg<'a> {
489503
F_GETPIPE_SZ,
490504
#[cfg(any(target_os = "linux", target_os = "android"))]
491505
F_SETPIPE_SZ(c_int),
506+
#[cfg(any(target_os = "netbsd", target_os = "dragonfly", target_os = "macos", target_os = "ios"))]
507+
F_GETPATH(&'a mut PathBuf),
492508
// TODO: Rest of flags
493509
}
494510

@@ -549,6 +565,15 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
549565
F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ),
550566
#[cfg(any(target_os = "linux", target_os = "android"))]
551567
F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size),
568+
#[cfg(any(target_os = "dragonfly", target_os = "netbsd", target_os = "macos", target_os = "ios"))]
569+
F_GETPATH(path) => {
570+
let mut buffer = vec![0; libc::PATH_MAX as usize];
571+
let res = libc::fcntl(fd, libc::F_GETPATH, buffer.as_mut_ptr());
572+
let ok_res = Errno::result(res)?;
573+
let optr = CStr::from_bytes_until_nul(&buffer).unwrap();
574+
*path = PathBuf::from(OsString::from(optr.to_str().unwrap()));
575+
return Ok(ok_res)
576+
},
552577
}
553578
};
554579

test/test_fcntl.rs

+23
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,26 @@ mod test_posix_fallocate {
561561
}
562562
}
563563
}
564+
565+
#[cfg(any(
566+
target_os = "dragonfly",
567+
target_os = "netbsd",
568+
target_os = "macos",
569+
target_os = "ios"
570+
))]
571+
#[test]
572+
fn test_f_get_path() {
573+
use nix::fcntl::*;
574+
use std::{os::unix::io::AsRawFd, path::PathBuf};
575+
576+
let tmp = NamedTempFile::new().unwrap();
577+
let fd = tmp.as_raw_fd();
578+
let mut path = PathBuf::new();
579+
let res =
580+
fcntl(fd, FcntlArg::F_GETPATH(&mut path)).expect("get path failed");
581+
assert_ne!(res, -1);
582+
assert_eq!(
583+
path.as_path().canonicalize().unwrap(),
584+
tmp.path().canonicalize().unwrap()
585+
);
586+
}

0 commit comments

Comments
 (0)