proc_daemon/
ipc.rs

1//! IPC primitives (feature-gated)
2//!
3//! Minimal scaffold for cross-platform IPC channels used for control and health.
4//! Currently implements a Tokio Unix socket server/client on Unix.
5
6#[cfg(unix)]
7/// Unix-specific IPC primitives implemented with Tokio Unix sockets.
8pub mod unix {
9    use std::io;
10    use std::path::Path;
11    use tokio::net::{UnixListener, UnixStream};
12
13    /// Bind a Unix domain socket at the given path.
14    ///
15    /// # Errors
16    ///
17    /// Returns an error if the socket file cannot be removed or if binding to the
18    /// provided path fails.
19    pub async fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
20        // Remove any stale socket
21        let _ = tokio::fs::remove_file(path.as_ref()).await;
22        UnixListener::bind(path)
23    }
24
25    /// Connect to a Unix domain socket at the given path.
26    ///
27    /// # Errors
28    ///
29    /// Returns an error if the connection to the provided socket path fails.
30    pub async fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
31        UnixStream::connect(path).await
32    }
33}
34
35#[cfg(windows)]
36/// Windows-specific IPC primitives (named pipe stubs; to be implemented).
37pub mod windows {
38    //! Tokio-based Windows named pipe IPC.
39    use tokio::io::{AsyncReadExt, AsyncWriteExt};
40    use tokio::net::windows::named_pipe::{
41        ClientOptions, NamedPipeClient, NamedPipeServer, ServerOptions,
42    };
43
44    /// Create a new named pipe server at the given pipe name (e.g., \\?\pipe\proc-daemon).
45    ///
46    /// Returns a server handle that can `connect().await` to wait for a client.
47    pub fn create_server<S: AsRef<str>>(name: S) -> std::io::Result<NamedPipeServer> {
48        ServerOptions::new()
49            .first_pipe_instance(true)
50            .create(name.as_ref())
51    }
52
53    /// Wait asynchronously for a client to connect to the given server instance.
54    pub async fn server_connect(server: &NamedPipeServer) -> std::io::Result<()> {
55        server.connect().await
56    }
57
58    /// Create a new named pipe client and connect to the given pipe name.
59    pub async fn connect<S: AsRef<str>>(name: S) -> std::io::Result<NamedPipeClient> {
60        ClientOptions::new().open(name.as_ref())
61    }
62
63    /// Simple echo handler demonstrating async read/write on a server connection.
64    pub async fn echo_once(mut server: NamedPipeServer) -> std::io::Result<()> {
65        let mut buf = [0u8; 1024];
66        let n = server.read(&mut buf).await?;
67        if n > 0 {
68            server.write_all(&buf[..n]).await?;
69        }
70        server.flush().await?;
71        Ok(())
72    }
73}