[−][src]Crate io_mux
A Mux provides a single receive end and multiple send ends. Data sent to any of the send ends comes out the receive end, in order, tagged by the sender.
Each send end works as a file descriptor. For instance, with io-mux
you can collect stdout and
stderr from a process, and highlight any error output from stderr, while preserving the relative
order of data across both stdout and stderr.
Example
let mut mux = io_mux::Mux::new()?; let mut child = std::process::Command::new("sh") .arg("-c") .arg("echo out1 && echo err1 1>&2 && echo out2") .stdout(mux.make_untagged_sender()?) .stderr(mux.make_tagged_sender("e")?) .spawn()?; let mut done_sender = mux.make_tagged_sender("d")?; std::thread::spawn(move || match child.wait() { Ok(status) if status.success() => { let _ = write!(done_sender, "Done\n"); } Ok(status) => { let _ = write!(done_sender, "Child process failed\n"); } Err(e) => { let _ = write!(done_sender, "Error: {:?}\n", e); } }); loop { let tagged_data = mux.read()?; if let Some(tag) = tagged_data.tag { print!("{}: ", tag); if tag == "d" { break; } } std::io::stdout().write_all(tagged_data.data)?; }
Internals
Internally, Mux
creates a UNIX datagram socket for the receive end, and a separate UNIX datagram
socket for each sender. Datagram sockets support recvfrom
, which provides the address of the
sender, so Mux::read
can use the sender address as the tag for the packet received.
However, datagram sockets require reading an entire datagram with each recvfrom
call, so
Mux::read
needs to find out the size of the next datagram before calling recvfrom
. Finding the
next datagram size requires an OS-specific mechanism, currently only implemented on Linux systems.
Mux
creates UNIX sockets within a temporary directory, removed when dropping the Mux
.
Note that Mux::read
cannot provide any indication of end-of-file. When using Mux
, you will need
to have some other indication that no further output will arrive, such as the exit of the child
process producing output.
Structs
Mux | A |
MuxSender | A send end of a |
TaggedData | Data received through a mux, along with the tag if any. |