diff --git a/CHANGELOG.md b/CHANGELOG.md index 315540c449..91ad54ee0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,10 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] - ReleaseDate -### Fixed +### Changed -- Relaxed lifetime requirements for `PollFd::new`. +- `PollFd::new` now takes a `BorrowedFd` argument, with relaxed lifetime + requirements relative to the previous version. ([#2134](https://github.com/nix-rust/nix/pull/2134)) ## [0.27.1] - 2023-08-28 diff --git a/src/poll.rs b/src/poll.rs index 5095642c1c..4fffb6ca66 100644 --- a/src/poll.rs +++ b/src/poll.rs @@ -32,19 +32,16 @@ impl<'fd> PollFd<'fd> { /// # }; /// let (r, w) = pipe().unwrap(); /// let r = unsafe { OwnedFd::from_raw_fd(r) }; - /// let pfd = PollFd::new(&r.as_fd(), PollFlags::POLLIN); + /// let pfd = PollFd::new(r.as_fd(), PollFlags::POLLIN); /// let mut fds = [pfd]; /// poll(&mut fds, -1).unwrap(); /// let mut buf = [0u8; 80]; /// read(r.as_raw_fd(), &mut buf[..]); /// ``` - // Unlike I/O functions, constructors like this must take `AsFd` by - // reference. Otherwise, an `OwnedFd` argument would be dropped at the end - // of the method, leaving the structure referencing a closed file - // descriptor. - // Different from other I/O-safe interfaces, here, we have to take `AsFd` - // by reference to prevent the case where the `fd` is closed but it is - // still in use. For example: + // Unlike I/O functions, constructors like this must take `BorrowedFd` + // instead of AsFd or &AsFd. Otherwise, an `OwnedFd` argument would be + // dropped at the end of the method, leaving the structure referencing a + // closed file descriptor. For example: // // ```rust // let (r, _) = pipe().unwrap(); @@ -52,10 +49,10 @@ impl<'fd> PollFd<'fd> { // let pollfd = PollFd::new(reader, flag); // Drops the OwnedFd // // Do something with `pollfd`, which uses the CLOSED fd. // ``` - pub fn new(fd: &Fd, events: PollFlags) -> PollFd<'fd> { + pub fn new(fd: BorrowedFd<'fd>, events: PollFlags) -> PollFd<'fd> { PollFd { pollfd: libc::pollfd { - fd: fd.as_fd().as_raw_fd(), + fd: fd.as_raw_fd(), events: events.bits(), revents: PollFlags::empty().bits(), }, diff --git a/test/test_poll.rs b/test/test_poll.rs index 045ccd3df1..eab806dde7 100644 --- a/test/test_poll.rs +++ b/test/test_poll.rs @@ -3,7 +3,10 @@ use nix::{ poll::{poll, PollFd, PollFlags}, unistd::{close, pipe, write}, }; -use std::os::unix::io::{BorrowedFd, FromRawFd, OwnedFd}; +use std::os::{ + fd::AsFd, + unix::io::{BorrowedFd, FromRawFd, OwnedFd} +}; macro_rules! loop_while_eintr { ($poll_expr: expr) => { @@ -21,7 +24,7 @@ macro_rules! loop_while_eintr { fn test_poll() { let (r, w) = pipe().unwrap(); let r = unsafe { OwnedFd::from_raw_fd(r) }; - let mut fds = [PollFd::new(&r, PollFlags::POLLIN)]; + let mut fds = [PollFd::new(r.as_fd(), PollFlags::POLLIN)]; // Poll an idle pipe. Should timeout let nfds = loop_while_eintr!(poll(&mut fds, 100)); @@ -55,7 +58,7 @@ fn test_ppoll() { let timeout = TimeSpec::milliseconds(1); let (r, w) = pipe().unwrap(); let r = unsafe { OwnedFd::from_raw_fd(r) }; - let mut fds = [PollFd::new(&r, PollFlags::POLLIN)]; + let mut fds = [PollFd::new(r.as_fd(), PollFlags::POLLIN)]; // Poll an idle pipe. Should timeout let sigset = SigSet::empty(); @@ -75,7 +78,7 @@ fn test_ppoll() { #[test] fn test_pollfd_events() { let fd_zero = unsafe { BorrowedFd::borrow_raw(0) }; - let mut pfd = PollFd::new(&fd_zero, PollFlags::POLLIN); + let mut pfd = PollFd::new(fd_zero.as_fd(), PollFlags::POLLIN); assert_eq!(pfd.events(), PollFlags::POLLIN); pfd.set_events(PollFlags::POLLOUT); assert_eq!(pfd.events(), PollFlags::POLLOUT);