wasi_net/process/
stdio.rs

1use crate::backend::StdioMode;
2
3/// Describes what to do with a standard I/O stream for a child process when
4/// passed to the [`stdin`], [`stdout`], and [`stderr`] methods of [`Command`].
5///
6/// [`stdin`]: Command::stdin
7/// [`stdout`]: Command::stdout
8/// [`stderr`]: Command::stderr
9#[derive(Debug, Clone)]
10pub struct Stdio {
11    pub(super) mode: StdioMode,
12}
13
14impl Stdio {
15    /// A new pipe should be arranged to connect the parent and child processes.
16    ///
17    /// # Examples
18    ///
19    /// With stdout:
20    ///
21    /// ```no_run
22    /// use std::process::{Command, Stdio};
23    ///
24    /// let output = Command::new("echo")
25    ///     .arg("Hello, world!")
26    ///     .stdout(Stdio::piped())
27    ///     .output()
28    ///     .expect("Failed to execute command");
29    ///
30    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "Hello, world!\n");
31    /// // Nothing echoed to console
32    /// ```
33    ///
34    /// With stdin:
35    ///
36    /// ```no_run
37    /// use std::io::Write;
38    /// use std::process::{Command, Stdio};
39    ///
40    /// let mut child = Command::new("rev")
41    ///     .stdin(Stdio::piped())
42    ///     .stdout(Stdio::piped())
43    ///     .spawn()
44    ///     .expect("Failed to spawn child process");
45    ///
46    /// let mut stdin = child.stdin.take().expect("Failed to open stdin");
47    /// std::thread::spawn(move || {
48    ///     stdin.write_all("Hello, world!".as_bytes()).expect("Failed to write to stdin");
49    /// });
50    ///
51    /// let output = child.wait_with_output().expect("Failed to read stdout");
52    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "!dlrow ,olleH");
53    /// ```
54    ///
55    /// Writing more than a pipe buffer's worth of input to stdin without also reading
56    /// stdout and stderr at the same time may cause a deadlock.
57    /// This is an issue when running any program that doesn't guarantee that it reads
58    /// its entire stdin before writing more than a pipe buffer's worth of output.
59    /// The size of a pipe buffer varies on different targets.
60    ///
61    pub fn piped() -> Stdio {
62        Stdio { mode: StdioMode::Piped }
63    }
64
65    /// The child inherits from the corresponding parent descriptor.
66    ///
67    /// # Examples
68    ///
69    /// With stdout:
70    ///
71    /// ```no_run
72    /// use std::process::{Command, Stdio};
73    ///
74    /// let output = Command::new("echo")
75    ///     .arg("Hello, world!")
76    ///     .stdout(Stdio::inherit())
77    ///     .output()
78    ///     .expect("Failed to execute command");
79    ///
80    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "");
81    /// // "Hello, world!" echoed to console
82    /// ```
83    ///
84    /// With stdin:
85    ///
86    /// ```no_run
87    /// use std::process::{Command, Stdio};
88    /// use std::io::{self, Write};
89    ///
90    /// let output = Command::new("rev")
91    ///     .stdin(Stdio::inherit())
92    ///     .stdout(Stdio::piped())
93    ///     .output()
94    ///     .expect("Failed to execute command");
95    ///
96    /// print!("You piped in the reverse of: ");
97    /// io::stdout().write_all(&output.stdout).unwrap();
98    /// ```
99    pub fn inherit() -> Stdio {
100        Stdio { mode: StdioMode::Inherit }
101    }
102
103    /// This stream will be ignored. This is the equivalent of attaching the
104    /// stream to `/dev/null`.
105    ///
106    /// # Examples
107    ///
108    /// With stdout:
109    ///
110    /// ```no_run
111    /// use std::process::{Command, Stdio};
112    ///
113    /// let output = Command::new("echo")
114    ///     .arg("Hello, world!")
115    ///     .stdout(Stdio::null())
116    ///     .output()
117    ///     .expect("Failed to execute command");
118    ///
119    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "");
120    /// // Nothing echoed to console
121    /// ```
122    ///
123    /// With stdin:
124    ///
125    /// ```no_run
126    /// use std::process::{Command, Stdio};
127    ///
128    /// let output = Command::new("rev")
129    ///     .stdin(Stdio::null())
130    ///     .stdout(Stdio::piped())
131    ///     .output()
132    ///     .expect("Failed to execute command");
133    ///
134    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "");
135    /// // Ignores any piped-in input
136    /// ```
137    pub fn null() -> Stdio {
138        Stdio { mode: StdioMode::Null }
139    }
140}