From 59874d639cade4c36a81acaf603372f594fba2d6 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Tue, 18 Aug 2020 11:06:01 +0100 Subject: [PATCH 1/2] tests: add test case for UnixStream::into_raw_fd Signed-off-by: Yuxuan Shui --- tests/uds.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/uds.rs b/tests/uds.rs index d081bdaee..5375a3ca2 100644 --- a/tests/uds.rs +++ b/tests/uds.rs @@ -29,7 +29,7 @@ fn send_recv() -> io::Result<()> { } #[test] -fn into_raw_fd() -> io::Result<()> { +fn into_raw_fd_datagram() -> io::Result<()> { use async_std::os::unix::io::{FromRawFd, IntoRawFd}; task::block_on(async { let (socket1, socket2) = UnixDatagram::pair().unwrap(); @@ -45,6 +45,23 @@ fn into_raw_fd() -> io::Result<()> { }) } +#[test] +fn into_raw_fd_stream() -> io::Result<()> { + use async_std::os::unix::io::{FromRawFd, IntoRawFd}; + task::block_on(async { + let (mut socket1, socket2) = UnixStream::pair().unwrap(); + socket1.write(JULIUS_CAESAR).await?; + + let mut buf = vec![0; 1024]; + + let mut socket2 = unsafe { UnixStream::from_raw_fd(socket2.into_raw_fd()) }; + let n = socket2.read(&mut buf).await?; + assert_eq!(&buf[..n], JULIUS_CAESAR); + + Ok(()) + }) +} + const PING: &[u8] = b"ping"; const PONG: &[u8] = b"pong"; const TEST_TIMEOUT: Duration = Duration::from_secs(3); From b0ac73cb57c2b4488a5738b702d5215d96897601 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Tue, 18 Aug 2020 11:06:34 +0100 Subject: [PATCH 2/2] os/unix/stream: stop into_raw_fd from closing the fd `UnixStream::into_raw_fd` calls `as_raw_fd`, which doesn't take the ownership of the file descriptor, so the file descriptor is closed when `self` is dropped upon returning from the function. Because `UnixStream` uses a `Arc` to support Clone, there could be an arbitrary number of instances around. We cannot take ownership of the descriptor from all of the instances. Therefore we have no choice but to duplicate the file descriptor and return that. Fixes #855 Signed-off-by: Yuxuan Shui --- CHANGELOG.md | 4 ++++ src/os/unix/net/stream.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85a156f7b..681fa8dd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://book.async.rs/overview ## [Unreleased] +## Fixed + +- Ensure `UnixStream::into_raw_fd` doesn't close the file descriptor ([#855](https://github.com/async-rs/async-std/issues/855)) + # [1.6.3] - 2020-07-31 ## Added diff --git a/src/os/unix/net/stream.rs b/src/os/unix/net/stream.rs index 3b2fe36f4..08e05e947 100644 --- a/src/os/unix/net/stream.rs +++ b/src/os/unix/net/stream.rs @@ -252,6 +252,6 @@ impl FromRawFd for UnixStream { impl IntoRawFd for UnixStream { fn into_raw_fd(self) -> RawFd { - self.as_raw_fd() + (*self.watcher).get_ref().try_clone().unwrap().into_raw_fd() } }