1use std::fmt::{Debug, Formatter, Result as FmtResult};
2use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Read, Result, Write};
3
4use crate::anon_pipe::{read2, AnonPipe};
5use crate::output::Output;
6use crate::process::{ExitStatus, Process};
7use crate::stdio::StdioPipes;
8
9pub struct Child {
11 handle: Process,
12 pub stdin: Option<ChildStdin>,
14 pub stdout: Option<ChildStdout>,
16 pub stderr: Option<ChildStderr>,
18}
19
20impl Child {
21 pub fn new(handle: Process, stdio: StdioPipes) -> Self {
22 Self {
23 handle,
24 stdin: stdio.stdin.map(ChildStdin),
25 stdout: stdio.stdout.map(ChildStdout),
26 stderr: stdio.stderr.map(ChildStderr),
27 }
28 }
29
30 pub fn kill(&mut self) -> Result<()> {
32 self.handle.kill()
33 }
34
35 pub fn id(&self) -> u32 {
37 self.handle.id()
38 }
39
40 pub fn wait(&mut self) -> Result<ExitStatus> {
42 drop(self.stdin.take());
43 self.handle.wait()
44 }
45
46 pub fn try_wait(&mut self) -> Result<Option<ExitStatus>> {
48 self.handle.try_wait()
49 }
50
51 pub fn wait_with_output(mut self) -> Result<Output> {
54 drop(self.stdin.take());
55
56 let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
57 match (self.stdout.take(), self.stderr.take()) {
58 (None, None) => {}
59 (Some(mut out), None) => {
60 out.read_to_end(&mut stdout)?;
61 }
62 (None, Some(mut err)) => {
63 err.read_to_end(&mut stderr)?;
64 }
65 (Some(out), Some(err)) => {
66 read2(out.0, &mut stdout, err.0, &mut stderr)?;
67 }
68 }
69
70 Ok(Output {
71 status: self.wait()?,
72 stdout,
73 stderr,
74 })
75 }
76}
77
78pub struct ChildStdin(AnonPipe);
80
81impl std::os::fd::AsRawFd for ChildStdin {
82 #[inline]
83 fn as_raw_fd(&self) -> std::os::fd::RawFd {
84 self.0.as_raw_fd()
85 }
86}
87
88impl Write for ChildStdin {
89 fn write(&mut self, buf: &[u8]) -> Result<usize> {
90 (&*self).write(buf)
91 }
92
93 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
94 (&*self).write_vectored(bufs)
95 }
96
97 fn flush(&mut self) -> Result<()> {
98 (&*self).flush()
99 }
100
101 fn write_all(&mut self, buf: &[u8]) -> Result<()> {
102 (&*self).write_all(buf)
103 }
104}
105
106impl Write for &ChildStdin {
107 fn write(&mut self, buf: &[u8]) -> Result<usize> {
108 self.0.write(buf)
109 }
110
111 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
112 self.0.write_vectored(bufs)
113 }
114
115 fn flush(&mut self) -> Result<()> {
116 Ok(())
117 }
118
119 fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
120 while !buf.is_empty() {
121 match self.write(buf) {
122 Ok(0) => {
123 return Err(Error::new(
124 ErrorKind::WriteZero,
125 "failed to write whole buffer",
126 ))
127 }
128 Ok(n) => buf = &buf[n..],
129 Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
130 Err(e) => return Err(e),
131 }
132 }
133 Ok(())
134 }
135}
136
137impl Debug for ChildStdin {
138 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
139 f.debug_struct("ChildStdin").finish_non_exhaustive()
140 }
141}
142
143pub struct ChildStdout(AnonPipe);
145
146impl std::os::fd::AsRawFd for ChildStdout {
147 #[inline]
148 fn as_raw_fd(&self) -> std::os::fd::RawFd {
149 self.0.as_raw_fd()
150 }
151}
152
153impl Write for ChildStdout {
154 fn write(&mut self, buf: &[u8]) -> Result<usize> {
155 (&*self).write(buf)
156 }
157
158 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
159 (&*self).write_vectored(bufs)
160 }
161
162 fn flush(&mut self) -> Result<()> {
163 (&*self).flush()
164 }
165
166 fn write_all(&mut self, buf: &[u8]) -> Result<()> {
167 (&*self).write_all(buf)
168 }
169}
170
171impl Write for &ChildStdout {
172 fn write(&mut self, buf: &[u8]) -> Result<usize> {
173 self.0.write(buf)
174 }
175
176 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
177 self.0.write_vectored(bufs)
178 }
179
180 fn flush(&mut self) -> Result<()> {
181 Ok(())
182 }
183
184 fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
185 while !buf.is_empty() {
186 match self.write(buf) {
187 Ok(0) => {
188 return Err(Error::new(
189 ErrorKind::WriteZero,
190 "failed to write whole buffer",
191 ))
192 }
193 Ok(n) => buf = &buf[n..],
194 Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
195 Err(e) => return Err(e),
196 }
197 }
198 Ok(())
199 }
200}
201
202impl Read for ChildStdout {
203 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
204 (&*self).read(buf)
205 }
206
207 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
208 (&*self).read_vectored(bufs)
209 }
210
211 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
212 (&*self).read_to_end(buf)
213 }
214}
215
216impl Read for &ChildStdout {
217 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
218 self.0.read(buf)
219 }
220
221 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
222 self.0.read_vectored(bufs)
223 }
224
225 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
226 self.0.read_to_end(buf)
227 }
228}
229
230impl Debug for ChildStdout {
231 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
232 f.debug_struct("ChildStdout").finish_non_exhaustive()
233 }
234}
235
236pub struct ChildStderr(AnonPipe);
238
239impl std::os::fd::AsRawFd for ChildStderr {
240 #[inline]
241 fn as_raw_fd(&self) -> std::os::fd::RawFd {
242 self.0.as_raw_fd()
243 }
244}
245
246impl Write for ChildStderr {
247 fn write(&mut self, buf: &[u8]) -> Result<usize> {
248 (&*self).write(buf)
249 }
250
251 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
252 (&*self).write_vectored(bufs)
253 }
254
255 fn flush(&mut self) -> Result<()> {
256 (&*self).flush()
257 }
258
259 fn write_all(&mut self, buf: &[u8]) -> Result<()> {
260 (&*self).write_all(buf)
261 }
262}
263
264impl Write for &ChildStderr {
265 fn write(&mut self, buf: &[u8]) -> Result<usize> {
266 self.0.write(buf)
267 }
268
269 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
270 self.0.write_vectored(bufs)
271 }
272
273 fn flush(&mut self) -> Result<()> {
274 Ok(())
275 }
276
277 fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
278 while !buf.is_empty() {
279 match self.write(buf) {
280 Ok(0) => {
281 return Err(Error::new(
282 ErrorKind::WriteZero,
283 "failed to write whole buffer",
284 ))
285 }
286 Ok(n) => buf = &buf[n..],
287 Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
288 Err(e) => return Err(e),
289 }
290 }
291 Ok(())
292 }
293}
294
295impl Read for ChildStderr {
296 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
297 (&*self).read(buf)
298 }
299
300 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
301 (&*self).read_vectored(bufs)
302 }
303
304 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
305 (&*self).read_to_end(buf)
306 }
307}
308
309impl Read for &ChildStderr {
310 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
311 self.0.read(buf)
312 }
313
314 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
315 self.0.read_vectored(bufs)
316 }
317
318 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
319 self.0.read_to_end(buf)
320 }
321}
322
323impl Debug for ChildStderr {
324 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
325 f.debug_struct("ChildStderr").finish_non_exhaustive()
326 }
327}
328
329impl Debug for Child {
330 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
331 f.debug_struct("Child")
332 .field("stdin", &self.stdin)
333 .field("stdout", &self.stdout)
334 .field("stderr", &self.stderr)
335 .finish_non_exhaustive()
336 }
337}