diff --git a/changelog/2113.added.md b/changelog/2113.added.md index be654b5dd5..48ca3ac465 100644 --- a/changelog/2113.added.md +++ b/changelog/2113.added.md @@ -1 +1 @@ -Add socket option `IPV6_PKTINFO` for BSDs/Linux/Android, also `IPV6_RECVPKTINFO` for DragonFlyBSD \ No newline at end of file +Add socket option `IPV6_PKTINFO` for BSDs/Linux/Android, also `IPV6_RECVPKTINFO` for DragonFlyBSD diff --git a/changelog/2480.added.md b/changelog/2480.added.md new file mode 100644 index 0000000000..d0f1d59271 --- /dev/null +++ b/changelog/2480.added.md @@ -0,0 +1 @@ +Add fcntl constant `F_RDADVISE` for Apple target diff --git a/src/fcntl.rs b/src/fcntl.rs index a5dca8a539..515b45b4d0 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -797,6 +797,9 @@ pub enum FcntlArg<'a> { /// Return the full path without firmlinks of the fd. #[cfg(apple_targets)] F_GETPATH_NOFIRMLINK(&'a mut PathBuf), + /// Issue an advisory read async with no copy to user + #[cfg(apple_targets)] + F_RDADVISE(libc::radvisory), // TODO: Rest of flags } @@ -905,6 +908,10 @@ pub fn fcntl(fd: Fd, arg: FcntlArg) -> Result { *path = PathBuf::from(OsString::from(optr.to_str().unwrap())); return Ok(ok_res) }, + #[cfg(apple_targets)] + F_RDADVISE(rad) => { + libc::fcntl(fd, libc::F_RDADVISE, &rad) + } } }; diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index d49f49670f..f8eddd3cde 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -732,3 +732,23 @@ mod test_flock { .expect_err("Should not have been able to lock the file"); } } + +#[cfg(apple_targets)] +#[test] +fn test_f_rdadvise() { + use nix::fcntl::*; + + let contents = vec![1; 1024]; + let mut buf = [0; 1024]; + let mut tmp = NamedTempFile::new().unwrap(); + tmp.write_all(&contents).unwrap(); + let fd = open(tmp.path(), OFlag::empty(), Mode::empty()).unwrap(); + let rad = libc::radvisory { + ra_offset: 0, + ra_count: contents.len() as _, + }; + let res = fcntl(&tmp, FcntlArg::F_RDADVISE(rad)).expect("rdadivse failed"); + assert_ne!(res, -1); + assert_eq!(contents.len(), read(&fd, &mut buf).unwrap()); + assert_eq!(contents, &buf[0..contents.len()]); +}