Skip to content

Commit

Permalink
Add AsyncFd::try_clone
Browse files Browse the repository at this point in the history
Duplicates the underlying file descriptor.
  • Loading branch information
Thomasdezeeuw committed Jan 1, 2024
1 parent 1178145 commit 2fc6e63
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,17 @@ impl AsyncFd {
AsyncFd::new(OwnedFd::from_raw_fd(fd), sq)
}

/// Creates a new independently owned `AsyncFd` that shares the same
/// underlying file descriptor as the existing `AsyncFd`.
#[doc(alias = "dup")]
#[doc(alias = "dup2")]
#[doc(alias = "F_DUPFD")]
#[doc(alias = "F_DUPFD_CLOEXEC")]
pub fn try_clone(&self) -> io::Result<AsyncFd> {
let fd = self.fd.try_clone()?;
Ok(AsyncFd::new(fd, self.sq.clone()))
}

/// Returns the `RawFd` of this `AsyncFd`.
fn fd(&self) -> RawFd {
self.fd.as_raw_fd()
Expand Down
19 changes: 19 additions & 0 deletions tests/async_fd/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ use crate::util::{
const BUF_SIZE: usize = 4096;
const NO_OFFSET: u64 = u64::MAX;

#[test]
fn try_clone() {
let sq = test_queue();
let waker = Waker::new();

let (r, w) = pipe2(sq).expect("failed to create pipe");
let w2 = w.try_clone().expect("failed to clone fd");

const DATA: &[u8] = b"hello world";
waker.block_on(w.write(&DATA[..5])).unwrap();
waker.block_on(w2.write(&DATA[5..])).unwrap();

let buf = BadReadBuf {
data: Vec::with_capacity(30),
};
let buf = waker.block_on(r.read_n(buf, DATA.len())).unwrap();
assert_eq!(&buf.data, DATA);
}

#[test]
fn read_read_buf_pool() {
require_kernel!(5, 19);
Expand Down

0 comments on commit 2fc6e63

Please sign in to comment.