@@ -38,30 +38,44 @@ use crate::sys_common::{FromInner, IntoInner};
3838/// > not rely on a particular capacity: an application should be designed so that a reading process
3939/// > consumes data as soon as it is available, so that a writing process does not remain blocked.
4040///
41- /// # Examples
41+ /// # Example
4242///
4343/// ```no_run
4444/// # #[cfg(miri)] fn main() {}
4545/// # #[cfg(not(miri))]
4646/// # fn main() -> std::io::Result<()> {
47+ /// use std::io::{Read, Write, pipe};
4748/// use std::process::Command;
48- /// use std::io::{pipe, Read, Write};
49- /// let (ping_rx, mut ping_tx) = pipe()?;
50- /// let (mut pong_rx, pong_tx) = pipe()?;
49+ /// let (ping_reader, mut ping_writer) = pipe()?;
50+ /// let (mut pong_reader, pong_writer) = pipe()?;
5151///
52- /// // Spawn a process that echoes its input.
53- /// let mut echo_server = Command::new("cat").stdin(ping_rx).stdout(pong_tx).spawn()?;
52+ /// // Spawn a child process that echoes its input.
53+ /// let mut echo_command = Command::new("cat");
54+ /// echo_command.stdin(ping_reader);
55+ /// echo_command.stdout(pong_writer);
56+ /// let mut echo_child = echo_command.spawn()?;
5457///
55- /// ping_tx.write_all(b"hello")?;
56- /// // Close to unblock echo_server's reader.
57- /// drop(ping_tx);
58+ /// // Send input to the child process. Note that because we're writing all the input before we
59+ /// // read any output, this could deadlock if the child's input and output pipe buffers both
60+ /// // filled up. Those buffers are usually at least a few KB, so "hello" is fine, but for longer
61+ /// // inputs we'd need to read and write at the same time, e.g. using threads.
62+ /// ping_writer.write_all(b"hello")?;
63+ ///
64+ /// // `cat` exits when it reads EOF from stdin, but that can't happen while any ping writer
65+ /// // remains open. We need to drop our ping writer, or read_to_string will deadlock below.
66+ /// drop(ping_writer);
67+ ///
68+ /// // The pong reader can't report EOF while any pong writer remains open. Our Command object is
69+ /// // holding a pong writer, and again read_to_string will deadlock if we don't drop it.
70+ /// drop(echo_command);
5871///
5972/// let mut buf = String::new();
60- /// // Block until echo_server's writer is closed .
61- /// pong_rx .read_to_string(&mut buf)?;
73+ /// // Block until `cat` closes its stdout (a pong writer) .
74+ /// pong_reader .read_to_string(&mut buf)?;
6275/// assert_eq!(&buf, "hello");
6376///
64- /// echo_server.wait()?;
77+ /// // At this point we know `cat` has exited, but we still need to wait to clean up the "zombie".
78+ /// echo_child.wait()?;
6579/// # Ok(())
6680/// # }
6781/// ```
0 commit comments