1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-21 18:12:23 +03:00

move uds stuff into new wezterm-uds crate

This centralizes the conditional imports and makes a home
for the IoSafe trait annotation for smol/async-io compat.
This commit is contained in:
Wez Furlong 2024-05-13 17:56:57 -07:00
parent a597803c13
commit 0fcd4a847c
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387
15 changed files with 175 additions and 66 deletions

15
Cargo.lock generated
View File

@ -6128,12 +6128,12 @@ dependencies = [
"termwiz",
"textwrap",
"thiserror",
"uds_windows",
"umask",
"url",
"wezterm-dynamic",
"wezterm-ssh",
"wezterm-term",
"wezterm-uds",
"winapi",
]
@ -6281,7 +6281,6 @@ dependencies = [
"textwrap",
"thiserror",
"tiny-skia",
"uds_windows",
"umask",
"unicode-normalization",
"unicode-segmentation",
@ -6373,10 +6372,10 @@ dependencies = [
"rcgen",
"smol",
"termwiz",
"uds_windows",
"url",
"wezterm-client",
"wezterm-term",
"wezterm-uds",
"winapi",
]
@ -6418,7 +6417,7 @@ dependencies = [
"ssh2",
"termwiz",
"thiserror",
"uds_windows",
"wezterm-uds",
"whoami",
]
@ -6469,6 +6468,14 @@ dependencies = [
"zvariant",
]
[[package]]
name = "wezterm-uds"
version = "0.1.0"
dependencies = [
"async-io",
"uds_windows",
]
[[package]]
name = "wezterm-version"
version = "0.1.0"

View File

@ -11,7 +11,8 @@ members = [
"wezterm-gui",
"wezterm-mux-server",
"wezterm-open-url",
"wezterm-ssh"
"wezterm-ssh",
"wezterm-uds",
]
resolver = "2"
exclude = [

View File

@ -37,9 +37,9 @@ url = "2"
wezterm-dynamic = { path = "../wezterm-dynamic" }
wezterm-ssh = { path = "../wezterm-ssh" }
wezterm-term = { path = "../term", features=["use_serde"] }
wezterm-uds = { path = "../wezterm-uds" }
[target."cfg(windows)".dependencies]
uds_windows = "1.1"
winapi = { version = "0.3", features = [
"winuser",
]}

View File

@ -1,6 +1,5 @@
use crate::domain::{ClientDomain, ClientDomainConfig};
use crate::pane::ClientPane;
use crate::UnixStream;
use anyhow::{anyhow, bail, Context};
use async_ossl::AsyncSslStream;
use async_trait::async_trait;
@ -34,6 +33,7 @@ use std::path::{Path, PathBuf};
use std::thread;
use std::time::Duration;
use thiserror::Error;
use wezterm_uds::UnixStream;
#[derive(Error, Debug)]
#[error("Timeout")]
@ -535,46 +535,6 @@ where
}
}
/// This wrapper makes UnixStream IoSafe on all platforms.
/// This isn't strictly needed on unix, because async-io
/// includes an impl for the std UnixStream, but on Windows
/// the uds_windows crate doesn't have an impl.
/// Here we define it for all platforms in the interest of
/// minimizing platform differences.
#[derive(Debug)]
struct IoSafeUnixStream(UnixStream);
#[cfg(unix)]
impl AsFd for IoSafeUnixStream {
fn as_fd(&self) -> BorrowedFd {
self.0.as_fd()
}
}
#[cfg(windows)]
impl AsSocket for IoSafeUnixStream {
fn as_socket(&self) -> BorrowedSocket {
self.0.as_socket()
}
}
impl Read for IoSafeUnixStream {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
self.0.read(buf)
}
}
impl Write for IoSafeUnixStream {
fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> {
self.0.write(buf)
}
fn flush(&mut self) -> Result<(), std::io::Error> {
self.0.flush()
}
}
unsafe impl async_io::IoSafe for IoSafeUnixStream {}
#[derive(Debug)]
struct Reconnectable {
config: ClientDomainConfig,
@ -842,7 +802,7 @@ impl Reconnectable {
ui.output_str("Connected!\n");
stream.set_read_timeout(Some(unix_dom.read_timeout))?;
stream.set_write_timeout(Some(unix_dom.write_timeout))?;
let stream: Box<dyn AsyncReadAndWrite> = Box::new(Async::new(IoSafeUnixStream(stream))?);
let stream: Box<dyn AsyncReadAndWrite> = Box::new(Async::new(stream)?);
self.stream.replace(stream);
Ok(())
}

View File

@ -1,7 +1,7 @@
use crate::UnixStream;
use anyhow::Context;
use std::path::{Path, PathBuf};
use std::time::{Duration, SystemTime};
use wezterm_uds::UnixStream;
/// There's a lot more code in this windows module than I thought I would need
/// to write. Ostensibly, we could get away with making a symlink by taking

View File

@ -1,8 +1,3 @@
#[cfg(unix)]
use std::os::unix::net::UnixStream;
#[cfg(windows)]
use uds_windows::UnixStream;
pub mod client;
pub mod discovery;
pub mod domain;

View File

@ -111,7 +111,6 @@ window-funcs = { path = "../lua-api-crates/window-funcs" }
[target."cfg(windows)".dependencies]
shared_library = "0.1"
uds_windows = "1.1"
winapi = { version = "0.3", features = [
"winuser",
"consoleapi",

View File

@ -26,8 +26,8 @@ smol = "2.0"
url = "2"
wezterm-client = { path = "../wezterm-client" }
wezterm-term = { path = "../term", features=["use_serde"] }
wezterm-uds = { path = "../wezterm-uds" }
termwiz = { path = "../termwiz", features=["use_serde"] }
[target."cfg(windows)".dependencies]
uds_windows = "1.1"
winapi = { version = "0.3", features = [ "winuser" ]}

View File

@ -1,5 +1,4 @@
use crate::sessionhandler::{PduSender, SessionHandler};
use crate::UnixStream;
use anyhow::Context;
use async_ossl::AsyncSslStream;
use codec::{DecodedPdu, Pdu};
@ -7,6 +6,7 @@ use futures::FutureExt;
use mux::{Mux, MuxNotification};
use smol::prelude::*;
use smol::Async;
use wezterm_uds::UnixStream;
#[cfg(unix)]
pub trait AsRawDesc: std::os::unix::io::AsRawFd + std::os::fd::AsFd {}

View File

@ -5,11 +5,6 @@ use mux::Mux;
use std::sync::Arc;
use wezterm_client::domain::{ClientDomain, ClientDomainConfig};
#[cfg(unix)]
use std::os::unix::net::{UnixListener, UnixStream};
#[cfg(windows)]
use uds_windows::{UnixListener, UnixStream};
pub mod dispatch;
pub mod local;
pub mod pki;

View File

@ -1,7 +1,7 @@
use crate::UnixListener;
use anyhow::{anyhow, Context as _};
use config::{create_user_owned_dirs, UnixDomain};
use promise::spawn::spawn_into_main_thread;
use wezterm_uds::UnixListener;
pub struct LocalListener {
listener: UnixListener,

View File

@ -35,7 +35,7 @@ libssh-rs = {version="0.3.2", features=["vendored"], optional = true}
#libssh-rs = {path="../../libssh-rs/libssh-rs", features=["vendored"], optional = true}
thiserror = "1.0"
socket2 = "0.5"
uds_windows = "1.1.0"
wezterm-uds = { path = "../wezterm-uds" }
# Not used directly, but is used to centralize the openssl vendor feature selection
async_ossl = { path = "../async_ossl" }

View File

@ -827,15 +827,14 @@ impl SessionInner {
.identity_agent()
.ok_or_else(|| anyhow!("no identity agent in config"))?;
let mut fd = {
use wezterm_uds::UnixStream;
#[cfg(unix)]
{
use std::os::unix::net::UnixStream;
FileDescriptor::new(UnixStream::connect(&identity_agent)?)
}
#[cfg(windows)]
unsafe {
use std::os::windows::io::{FromRawSocket, IntoRawSocket};
use uds_windows::UnixStream;
FileDescriptor::from_raw_socket(
UnixStream::connect(&identity_agent)?.into_raw_socket(),
)

12
wezterm-uds/Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "wezterm-uds"
version = "0.1.0"
edition = "2021"
repository = "https://github.com/wez/wezterm"
description = "Portable unix domain sockets"
license = "MIT"
documentation = "https://docs.rs/wezterm-uds"
[dependencies]
async-io = "2.3"
uds_windows = "1.1"

141
wezterm-uds/src/lib.rs Normal file
View File

@ -0,0 +1,141 @@
use std::io::{Read, Write};
#[cfg(unix)]
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(unix)]
use std::os::unix::net::UnixStream as StreamImpl;
#[cfg(windows)]
use std::os::windows::io::{
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, RawSocket,
};
use std::path::Path;
#[cfg(windows)]
use uds_windows::UnixStream as StreamImpl;
#[cfg(unix)]
use std::os::unix::net::UnixListener as ListenerImpl;
#[cfg(windows)]
use uds_windows::UnixListener as ListenerImpl;
#[cfg(unix)]
use std::os::unix::net::SocketAddr;
#[cfg(windows)]
use uds_windows::SocketAddr;
/// This wrapper makes UnixStream IoSafe on all platforms.
/// This isn't strictly needed on unix, because async-io
/// includes an impl for the std UnixStream, but on Windows
/// the uds_windows crate doesn't have an impl.
/// Here we define it for all platforms in the interest of
/// minimizing platform differences.
#[derive(Debug)]
pub struct UnixStream(StreamImpl);
#[cfg(unix)]
impl AsFd for UnixStream {
fn as_fd(&self) -> BorrowedFd {
self.0.as_fd()
}
}
#[cfg(unix)]
impl IntoRawFd for UnixStream {
fn into_raw_fd(self) -> RawFd {
self.0.into_raw_fd()
}
}
#[cfg(unix)]
impl FromRawFd for UnixStream {
unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
UnixStream(StreamImpl::from_raw_fd(fd))
}
}
#[cfg(unix)]
impl AsRawFd for UnixStream {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
#[cfg(windows)]
impl IntoRawSocket for UnixStream {
fn into_raw_socket(self) -> RawSocket {
self.0.into_raw_socket()
}
}
#[cfg(windows)]
impl AsSocket for UnixStream {
fn as_socket(&self) -> BorrowedSocket {
self.0.as_socket()
}
}
#[cfg(windows)]
impl FromRawSocket for UnixStream {
unsafe fn from_raw_socket(socket: RawSocket) -> UnixStream {
UnixStream(StreamImpl::from_raw_socket(socket))
}
}
impl Read for UnixStream {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
self.0.read(buf)
}
}
impl Write for UnixStream {
fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> {
self.0.write(buf)
}
fn flush(&mut self) -> Result<(), std::io::Error> {
self.0.flush()
}
}
unsafe impl async_io::IoSafe for UnixStream {}
impl UnixStream {
pub fn connect<P: AsRef<Path>>(path: P) -> std::io::Result<Self> {
Ok(Self(StreamImpl::connect(path)?))
}
}
impl std::ops::Deref for UnixStream {
type Target = StreamImpl;
fn deref(&self) -> &StreamImpl {
&self.0
}
}
impl std::ops::DerefMut for UnixStream {
fn deref_mut(&mut self) -> &mut StreamImpl {
&mut self.0
}
}
pub struct UnixListener(ListenerImpl);
impl UnixListener {
pub fn bind<P: AsRef<Path>>(path: P) -> std::io::Result<Self> {
Ok(Self(ListenerImpl::bind(path)?))
}
pub fn accept(&self) -> std::io::Result<(UnixStream, SocketAddr)> {
let (stream, addr) = self.0.accept()?;
Ok((UnixStream(stream), addr))
}
pub fn incoming(&self) -> impl Iterator<Item = std::io::Result<UnixStream>> + '_ {
self.0.incoming().map(|r| r.map(UnixStream))
}
}
impl std::ops::Deref for UnixListener {
type Target = ListenerImpl;
fn deref(&self) -> &ListenerImpl {
&self.0
}
}
impl std::ops::DerefMut for UnixListener {
fn deref_mut(&mut self) -> &mut ListenerImpl {
&mut self.0
}
}