Codex Handbook
stdio-to-uds/src/lib.rs 46 lines
#![deny(clippy::print_stdout)]use std::io;use std::path::Path;use anyhow::Context;use codex_uds::UnixStream;use tokio::io::AsyncWriteExt;/// Connects to the Unix Domain Socket at `socket_path` and relays data between/// standard input/output and the socket.pub async fn run(socket_path: &Path) -> anyhow::Result<()> {    let stream = UnixStream::connect(socket_path)        .await        .with_context(|| format!("failed to connect to socket at {}", socket_path.display()))?;    let (mut socket_reader, mut socket_writer) = tokio::io::split(stream);    let copy_socket_to_stdout = async {        let mut stdout = tokio::io::stdout();        tokio::io::copy(&mut socket_reader, &mut stdout).await?;        stdout.flush().await?;        Ok(())    };    let copy_stdin_to_socket = async {        let mut stdin = tokio::io::stdin();        tokio::io::copy(&mut stdin, &mut socket_writer)            .await            .context("failed to copy data from stdin to socket")?;        // The peer can close immediately after sending its response; in that        // race, half-closing our write side can report NotConnected on some        // platforms.        if let Err(err) = socket_writer.shutdown().await            && err.kind() != io::ErrorKind::NotConnected        {            return Err(err).context("failed to shutdown socket writer");        }        anyhow::Ok(())    };    tokio::try_join!(copy_stdin_to_socket, copy_socket_to_stdout)        .context("failed to relay data between stdio and socket")?;    Ok(())}