mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-19 00:00:09 +02:00
io: add implementations of AsFd/AsHandle/AsSocket (#5514)
This commit is contained in:
@@ -24,6 +24,19 @@ const CONST_MUTEX_NEW_PROBE: &str = r#"
|
||||
}
|
||||
"#;
|
||||
|
||||
const AS_FD_PROBE: &str = r#"
|
||||
{
|
||||
#![allow(unused_imports)]
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::prelude::AsFd as _;
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::prelude::AsSocket as _;
|
||||
#[cfg(target = "wasm32-wasi")]
|
||||
use std::os::wasi::prelude::AsFd as _;
|
||||
}
|
||||
"#;
|
||||
|
||||
const TARGET_HAS_ATOMIC_PROBE: &str = r#"
|
||||
{
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
@@ -43,6 +56,7 @@ fn main() {
|
||||
let mut enable_addr_of = false;
|
||||
let mut enable_target_has_atomic = false;
|
||||
let mut enable_const_mutex_new = false;
|
||||
let mut enable_as_fd = false;
|
||||
let mut target_needs_atomic_u64_fallback = false;
|
||||
|
||||
match AutoCfg::new() {
|
||||
@@ -117,6 +131,21 @@ fn main() {
|
||||
enable_const_mutex_new = true;
|
||||
}
|
||||
}
|
||||
|
||||
// The `AsFd` family of traits were made stable in 1.63.
|
||||
if ac.probe_rustc_version(1, 64) {
|
||||
enable_as_fd = true;
|
||||
} else if ac.probe_rustc_version(1, 63) {
|
||||
// This compiler claims to be 1.63, but there are some nightly
|
||||
// compilers that claim to be 1.63 without supporting the
|
||||
// feature. Explicitly probe to check if code using them
|
||||
// compiles.
|
||||
//
|
||||
// The oldest nightly that supports the feature is 2022-06-16.
|
||||
if ac.probe_expression(AS_FD_PROBE) {
|
||||
enable_as_fd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(e) => {
|
||||
@@ -162,6 +191,14 @@ fn main() {
|
||||
autocfg::emit("tokio_no_const_mutex_new")
|
||||
}
|
||||
|
||||
if !enable_as_fd {
|
||||
// To disable this feature on compilers that support it, you can
|
||||
// explicitly pass this flag with the following environment variable:
|
||||
//
|
||||
// RUSTFLAGS="--cfg tokio_no_as_fd"
|
||||
autocfg::emit("tokio_no_as_fd");
|
||||
}
|
||||
|
||||
if target_needs_atomic_u64_fallback {
|
||||
// To disable this feature on compilers that support it, you can
|
||||
// explicitly pass this flag with the following environment variable:
|
||||
|
||||
@@ -725,6 +725,15 @@ impl std::os::unix::io::AsRawFd for File {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(unix, not(tokio_no_as_fd)))]
|
||||
impl std::os::unix::io::AsFd for File {
|
||||
fn as_fd(&self) -> std::os::unix::io::BorrowedFd<'_> {
|
||||
unsafe {
|
||||
std::os::unix::io::BorrowedFd::borrow_raw(std::os::unix::io::AsRawFd::as_raw_fd(self))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl std::os::unix::io::FromRawFd for File {
|
||||
unsafe fn from_raw_fd(fd: std::os::unix::io::RawFd) -> Self {
|
||||
@@ -739,6 +748,17 @@ impl std::os::windows::io::AsRawHandle for File {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(windows, not(tokio_no_as_fd)))]
|
||||
impl std::os::windows::io::AsHandle for File {
|
||||
fn as_handle(&self) -> std::os::windows::io::BorrowedHandle<'_> {
|
||||
unsafe {
|
||||
std::os::windows::io::BorrowedHandle::borrow_raw(
|
||||
std::os::windows::io::AsRawHandle::as_raw_handle(self),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl std::os::windows::io::FromRawHandle for File {
|
||||
unsafe fn from_raw_handle(handle: std::os::windows::io::RawHandle) -> Self {
|
||||
|
||||
@@ -407,6 +407,13 @@ mod sys {
|
||||
self.io.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for TcpListener {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfg_unstable! {
|
||||
@@ -420,6 +427,13 @@ cfg_unstable! {
|
||||
self.io.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for TcpListener {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,4 +447,11 @@ mod sys {
|
||||
self.io.as_raw_socket()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsSocket for TcpListener {
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,14 @@ use std::fmt;
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[cfg(all(unix, not(tokio_no_as_fd)))]
|
||||
use std::os::unix::io::{AsFd, BorrowedFd};
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
|
||||
#[cfg(all(windows, not(tokio_no_as_fd)))]
|
||||
use std::os::windows::io::{AsSocket, BorrowedSocket};
|
||||
use std::time::Duration;
|
||||
|
||||
cfg_net! {
|
||||
@@ -737,6 +741,13 @@ impl AsRawFd for TcpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(unix, not(tokio_no_as_fd)))]
|
||||
impl AsFd for TcpSocket {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl FromRawFd for TcpSocket {
|
||||
/// Converts a `RawFd` to a `TcpSocket`.
|
||||
@@ -772,6 +783,13 @@ impl AsRawSocket for TcpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(windows, not(tokio_no_as_fd)))]
|
||||
impl AsSocket for TcpSocket {
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl FromRawSocket for TcpSocket {
|
||||
/// Converts a `RawSocket` to a `TcpStream`.
|
||||
|
||||
@@ -1378,6 +1378,13 @@ mod sys {
|
||||
self.io.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for TcpStream {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
@@ -1390,6 +1397,13 @@ mod sys {
|
||||
self.io.as_raw_socket()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsSocket for TcpStream {
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(tokio_unstable, tokio_wasi))]
|
||||
@@ -1402,4 +1416,11 @@ mod sys {
|
||||
self.io.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for TcpStream {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-1
@@ -1727,7 +1727,7 @@ impl fmt::Debug for UdpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(unix))]
|
||||
#[cfg(unix)]
|
||||
mod sys {
|
||||
use super::UdpSocket;
|
||||
use std::os::unix::prelude::*;
|
||||
@@ -1737,6 +1737,13 @@ mod sys {
|
||||
self.io.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for UdpSocket {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
@@ -1749,4 +1756,11 @@ mod sys {
|
||||
self.io.as_raw_socket()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsSocket for UdpSocket {
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::net::Shutdown;
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
use std::os::unix::io::{AsFd, BorrowedFd};
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use std::os::unix::net;
|
||||
use std::path::Path;
|
||||
@@ -1472,3 +1474,10 @@ impl AsRawFd for UnixDatagram {
|
||||
self.io.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for UnixDatagram {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ use crate::net::unix::{SocketAddr, UnixStream};
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
use std::os::unix::io::{AsFd, BorrowedFd};
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use std::os::unix::net;
|
||||
use std::path::Path;
|
||||
@@ -208,3 +210,10 @@ impl AsRawFd for UnixListener {
|
||||
self.io.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for UnixListener {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ use mio::unix::pipe as mio_pipe;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::os::unix::fs::{FileTypeExt, OpenOptionsExt};
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
use std::os::unix::io::{AsFd, BorrowedFd};
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use std::path::Path;
|
||||
use std::pin::Pin;
|
||||
@@ -662,6 +664,13 @@ impl AsRawFd for Sender {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for Sender {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Reading end of a Unix pipe.
|
||||
///
|
||||
/// It can be constructed from a FIFO file with [`OpenOptions::open_receiver`].
|
||||
@@ -1161,6 +1170,13 @@ impl AsRawFd for Receiver {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for Receiver {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if file is a FIFO
|
||||
fn is_fifo(file: &File) -> io::Result<bool> {
|
||||
Ok(file.metadata()?.file_type().is_fifo())
|
||||
|
||||
@@ -9,6 +9,8 @@ use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::net::Shutdown;
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
use std::os::unix::io::{AsFd, BorrowedFd};
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use std::os::unix::net;
|
||||
use std::path::Path;
|
||||
@@ -1036,3 +1038,10 @@ impl AsRawFd for UnixStream {
|
||||
self.io.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for UnixStream {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1428,6 +1428,8 @@ impl TryInto<Stdio> for ChildStderr {
|
||||
|
||||
#[cfg(unix)]
|
||||
mod sys {
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
use std::os::unix::io::{AsFd, BorrowedFd};
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
|
||||
use super::{ChildStderr, ChildStdin, ChildStdout};
|
||||
@@ -1438,21 +1440,44 @@ mod sys {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for ChildStdin {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawFd for ChildStdout {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.inner.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for ChildStdout {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawFd for ChildStderr {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.inner.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for ChildStderr {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
mod sys {
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
use std::os::windows::io::{AsHandle, BorrowedHandle};
|
||||
use std::os::windows::io::{AsRawHandle, RawHandle};
|
||||
|
||||
use super::{ChildStderr, ChildStdin, ChildStdout};
|
||||
@@ -1463,17 +1488,38 @@ mod sys {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsHandle for ChildStdin {
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawHandle for ChildStdout {
|
||||
fn as_raw_handle(&self) -> RawHandle {
|
||||
self.inner.as_raw_handle()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsHandle for ChildStdout {
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawHandle for ChildStderr {
|
||||
fn as_raw_handle(&self) -> RawHandle {
|
||||
self.inner.as_raw_handle()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsHandle for ChildStderr {
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, not(loom)))]
|
||||
|
||||
@@ -39,6 +39,8 @@ use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::future::Future;
|
||||
use std::io;
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
use std::os::unix::io::{AsFd, BorrowedFd};
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use std::pin::Pin;
|
||||
use std::process::{Child as StdChild, ExitStatus, Stdio};
|
||||
@@ -194,6 +196,13 @@ impl AsRawFd for Pipe {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for Pipe {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn convert_to_stdio(io: ChildStdio) -> io::Result<Stdio> {
|
||||
let mut fd = io.inner.into_inner()?.fd;
|
||||
|
||||
@@ -246,6 +255,13 @@ impl AsRawFd for ChildStdio {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(tokio_no_as_fd))]
|
||||
impl AsFd for ChildStdio {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncWrite for ChildStdio {
|
||||
fn poll_write(
|
||||
self: Pin<&mut Self>,
|
||||
|
||||
Reference in New Issue
Block a user