@@ -38,30 +38,44 @@ use crate::sys_common::{FromInner, IntoInner};
38
38
/// > not rely on a particular capacity: an application should be designed so that a reading process
39
39
/// > consumes data as soon as it is available, so that a writing process does not remain blocked.
40
40
///
41
- /// # Examples
41
+ /// # Example
42
42
///
43
43
/// ```no_run
44
44
/// # #[cfg(miri)] fn main() {}
45
45
/// # #[cfg(not(miri))]
46
46
/// # fn main() -> std::io::Result<()> {
47
+ /// use std::io::{Read, Write, pipe};
47
48
/// 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()?;
51
51
///
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()?;
54
57
///
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);
58
71
///
59
72
/// 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)?;
62
75
/// assert_eq!(&buf, "hello");
63
76
///
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()?;
65
79
/// # Ok(())
66
80
/// # }
67
81
/// ```
0 commit comments