Hi! I've stumbled upon a strange problem, that I can't solve.
I have a program that accepts input from stdin
and outputs to stdout
. I want to pipe those streams with my R: impl Read
for stdin
and W: impl Write
for stdout
.
I found a method std::io::copy
, and used my streams as stdout
/stdin
, however the Child
program never ends! I even included \x04
- but it didn't work either.
Here is the code (an MWE, this code has function pass_stream
, which does what I want, it passes string "Hello, World!\x04"
to stdin
of cat
and reads from stdout
of cat):
use std::io::{Cursor, Read, Write};
use std::process::{Command, Stdio};
fn main() {
let mut input_cursor = Cursor::new("Hello, World!\x04");
let mut output_vec: Vec<u8> = Vec::new();
let mut output_cursor = std::io::Cursor::new(&mut output_vec);
pass_streams("cat", &mut input_cursor, &mut output_cursor);
println!("{}", String::from_utf8(output_vec).unwrap());
}
fn pass_streams<'r, 'w, R, W>(cmd: &'static str, input: &'r mut R, output: &'w mut W)
where
R: Read,
W: Write,
{
let mut child = Command::new(cmd)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap();
let mut child_input = child.stdin.take().unwrap();
let mut child_output = child.stdout.take().unwrap();
std::io::copy(input, &mut child_input).unwrap();
child_input.flush().unwrap(); // Unnecessary?
child.wait().unwrap();
println!("Start copying stdout");
std::io::copy(&mut child_output, output).unwrap();
println!("End copying stdout");
}
Playground link: Rust Playground
The output is:
Start copying stdout
And the program never ends.
I know, there could be other ways to solve the problem, I can use wait_with_output
probably, but still how to use it solely with Read
and Write
?
It seems that I miss a tiny bit, but I can't google it..