Skip to content

Commit c9c7d91

Browse files
committed
Take BorrowedFd as the argument for PollFd::new
&AsFd didn't work because there are 'static types, like std::fs::File, which implement AsFd. The created BorrowedFd type within the PollFd::new method would have a very brief lifetime, but the PhantomData would capture the lifetime of the std::fs::File. Taking BorrowFd<'fd> argument makes the lifetime explicit.
1 parent 8b82c46 commit c9c7d91

File tree

3 files changed

+14
-21
lines changed

3 files changed

+14
-21
lines changed

CHANGELOG.md

+2-5
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
2222

2323
([#2137](https://github.com/nix-rust/nix/pull/2137))
2424

25-
## [Unreleased] - ReleaseDate
26-
27-
### Fixed
28-
29-
- Relaxed lifetime requirements for `PollFd::new`.
25+
- `PollFd::new` now takes a `BorrowedFd` argument, with relaxed lifetime
26+
requirements relative to the previous version.
3027
([#2134](https://github.com/nix-rust/nix/pull/2134))
3128

3229
## [0.27.1] - 2023-08-28

src/poll.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -25,37 +25,33 @@ impl<'fd> PollFd<'fd> {
2525
///
2626
/// # Examples
2727
/// ```no_run
28-
/// # use std::os::fd::{AsFd, AsRawFd, FromRawFd, OwnedFd};
28+
/// # use std::os::unix::io::{AsFd, AsRawFd, FromRawFd};
2929
/// # use nix::{
3030
/// # poll::{PollFd, PollFlags, poll},
3131
/// # unistd::{pipe, read}
3232
/// # };
3333
/// let (r, w) = pipe().unwrap();
34-
/// let r = unsafe { OwnedFd::from_raw_fd(r) };
35-
/// let pfd = PollFd::new(&r.as_fd(), PollFlags::POLLIN);
34+
/// let pfd = PollFd::new(r.as_fd(), PollFlags::POLLIN);
3635
/// let mut fds = [pfd];
3736
/// poll(&mut fds, -1).unwrap();
3837
/// let mut buf = [0u8; 80];
3938
/// read(r.as_raw_fd(), &mut buf[..]);
4039
/// ```
41-
// Unlike I/O functions, constructors like this must take `AsFd` by
42-
// reference. Otherwise, an `OwnedFd` argument would be dropped at the end
43-
// of the method, leaving the structure referencing a closed file
44-
// descriptor.
45-
// Different from other I/O-safe interfaces, here, we have to take `AsFd`
46-
// by reference to prevent the case where the `fd` is closed but it is
47-
// still in use. For example:
40+
// Unlike I/O functions, constructors like this must take `BorrowedFd`
41+
// instead of AsFd or &AsFd. Otherwise, an `OwnedFd` argument would be
42+
// dropped at the end of the method, leaving the structure referencing a
43+
// closed file descriptor. For example:
4844
//
4945
// ```rust
5046
// let (r, _) = pipe().unwrap();
5147
// let reader: OwnedFd = unsafe { OwnedFd::from_raw_fd(r) };
5248
// let pollfd = PollFd::new(reader, flag); // Drops the OwnedFd
5349
// // Do something with `pollfd`, which uses the CLOSED fd.
5450
// ```
55-
pub fn new<Fd: AsFd + 'fd>(fd: &Fd, events: PollFlags) -> PollFd<'fd> {
51+
pub fn new(fd: BorrowedFd<'fd>, events: PollFlags) -> PollFd<'fd> {
5652
PollFd {
5753
pollfd: libc::pollfd {
58-
fd: fd.as_fd().as_raw_fd(),
54+
fd: fd.as_raw_fd(),
5955
events: events.bits(),
6056
revents: PollFlags::empty().bits(),
6157
},

test/test_poll.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use nix::{
33
poll::{poll, PollFd, PollFlags},
44
unistd::{pipe, write},
55
};
6-
use std::os::unix::io::BorrowedFd;
6+
use std::os::unix::io::{AsFd, BorrowedFd};
77

88
macro_rules! loop_while_eintr {
99
($poll_expr: expr) => {
@@ -20,7 +20,7 @@ macro_rules! loop_while_eintr {
2020
#[test]
2121
fn test_poll() {
2222
let (r, w) = pipe().unwrap();
23-
let mut fds = [PollFd::new(&r, PollFlags::POLLIN)];
23+
let mut fds = [PollFd::new(r.as_fd(), PollFlags::POLLIN)];
2424

2525
// Poll an idle pipe. Should timeout
2626
let nfds = loop_while_eintr!(poll(&mut fds, 100));
@@ -52,7 +52,7 @@ fn test_ppoll() {
5252

5353
let timeout = TimeSpec::milliseconds(1);
5454
let (r, w) = pipe().unwrap();
55-
let mut fds = [PollFd::new(&r, PollFlags::POLLIN)];
55+
let mut fds = [PollFd::new(r.as_fd(), PollFlags::POLLIN)];
5656

5757
// Poll an idle pipe. Should timeout
5858
let sigset = SigSet::empty();
@@ -71,7 +71,7 @@ fn test_ppoll() {
7171
#[test]
7272
fn test_pollfd_events() {
7373
let fd_zero = unsafe { BorrowedFd::borrow_raw(0) };
74-
let mut pfd = PollFd::new(&fd_zero, PollFlags::POLLIN);
74+
let mut pfd = PollFd::new(fd_zero.as_fd(), PollFlags::POLLIN);
7575
assert_eq!(pfd.events(), PollFlags::POLLIN);
7676
pfd.set_events(PollFlags::POLLOUT);
7777
assert_eq!(pfd.events(), PollFlags::POLLOUT);

0 commit comments

Comments
 (0)