diff --git a/Cargo.lock b/Cargo.lock index 557029a7..b5beedfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6514,6 +6514,7 @@ dependencies = [ "async-channel", "async-io", "bytes", + "interprocess", "log", "serde", "serde_json", diff --git a/wayvr-ipc/Cargo.toml b/wayvr-ipc/Cargo.toml index 47520dd3..a39eeb4e 100644 --- a/wayvr-ipc/Cargo.toml +++ b/wayvr-ipc/Cargo.toml @@ -12,6 +12,7 @@ anyhow.workspace = true async-channel.workspace = true async-io.workspace = true bytes.workspace = true +interprocess.workspace = true log.workspace = true serde.workspace = true smallvec.workspace = true diff --git a/wayvr-ipc/src/client.rs b/wayvr-ipc/src/client.rs index e16c9ada..3ca1106c 100644 --- a/wayvr-ipc/src/client.rs +++ b/wayvr-ipc/src/client.rs @@ -1,10 +1,11 @@ use bytes::BufMut; +use interprocess::local_socket::{self, ToNsName}; use serde::Serialize; use smallvec::SmallVec; use smol::io::AsyncReadExt; use smol::io::AsyncWriteExt; use smol::lock::Mutex; -use smol::net::unix::UnixStream; +use std::os::unix::net::UnixStream as StdUnixStream; use std::sync::{Arc, Weak}; use crate::{ @@ -65,6 +66,24 @@ pub type WayVRClientWeak = Weak>; type ReceiverMutex = Arc>; type SenderMutex = Arc>; +fn interprocess_stream_to_async( + stream: local_socket::Stream, +) -> anyhow::Result { + use std::os::unix::io::OwnedFd; + + let uds_stream: interprocess::os::unix::uds_local_socket::Stream = match stream { + local_socket::Stream::UdSocket(s) => s, + #[allow(unreachable_patterns)] + _ => anyhow::bail!("Unsupported socket type"), + }; + + let owned_fd: OwnedFd = uds_stream.into(); + let std_stream = StdUnixStream::from(owned_fd); + + smol::net::unix::UnixStream::try_from(std_stream) + .map_err(|e| anyhow::anyhow!("Failed to wrap socket for async I/O: {}", e)) +} + async fn client_runner(client: WayVRClientMutex) -> anyhow::Result<()> { loop { WayVRClient::tick(client.clone()).await?; @@ -118,14 +137,17 @@ impl WayVRClient { pub async fn new(client_name: &str) -> anyhow::Result { let printname = "/tmp/wayvr_ipc.sock"; - let stream = match UnixStream::connect(printname).await { - Ok(c) => c, - Err(e) => { - anyhow::bail!("Failed to connect to the WayVR IPC: {}", e) - } - }; - let receiver = Arc::new(Mutex::new(stream.clone())); - let sender = Arc::new(Mutex::new(stream)); + let name = printname + .to_ns_name::() + .map_err(|e| anyhow::anyhow!("Failed to create socket name: {}", e))?; + let opts = local_socket::ConnectOptions::new().name(name); + let ip_stream = opts + .connect_sync() + .map_err(|e| anyhow::anyhow!("Failed to connect to the WayVR IPC: {}", e))?; + + let async_stream = interprocess_stream_to_async(ip_stream)?; + let receiver = Arc::new(Mutex::new(async_stream.clone())); + let sender = Arc::new(Mutex::new(async_stream)); let (cancel_tx, cancel_rx) = async_channel::bounded(1);