| //@ run-pass |
| //@ ignore-cross-compile |
| |
| use std::env; |
| use std::fs::File; |
| use std::io; |
| use std::io::{Read, Write}; |
| use std::process::{Command, Stdio}; |
| use std::path::PathBuf; |
| |
| fn main() { |
| if env::args().len() > 1 { |
| child().unwrap() |
| } else { |
| parent().unwrap() |
| } |
| } |
| |
| fn parent() -> io::Result<()> { |
| let td = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); |
| let input = td.join("stdio-from-input"); |
| let output = td.join("stdio-from-output"); |
| |
| File::create(&input)?.write_all(b"foo\n")?; |
| |
| // Set up this chain: |
| // $ me <file | me | me >file |
| // ... to duplicate each line 8 times total. |
| |
| let mut child1 = Command::new(env::current_exe()?) |
| .arg("first") |
| .stdin(File::open(&input)?) // tests File::into() |
| .stdout(Stdio::piped()) |
| .spawn()?; |
| |
| let mut child3 = Command::new(env::current_exe()?) |
| .arg("third") |
| .stdin(Stdio::piped()) |
| .stdout(File::create(&output)?) // tests File::into() |
| .spawn()?; |
| |
| // Started out of order so we can test both `ChildStdin` and `ChildStdout`. |
| let mut child2 = Command::new(env::current_exe()?) |
| .arg("second") |
| .stdin(child1.stdout.take().unwrap()) // tests ChildStdout::into() |
| .stdout(child3.stdin.take().unwrap()) // tests ChildStdin::into() |
| .spawn()?; |
| |
| assert!(child1.wait()?.success()); |
| assert!(child2.wait()?.success()); |
| assert!(child3.wait()?.success()); |
| |
| let mut data = String::new(); |
| File::open(&output)?.read_to_string(&mut data)?; |
| for line in data.lines() { |
| assert_eq!(line, "foo"); |
| } |
| assert_eq!(data.lines().count(), 8); |
| Ok(()) |
| } |
| |
| fn child() -> io::Result<()> { |
| // double everything |
| let mut input = vec![]; |
| io::stdin().read_to_end(&mut input)?; |
| io::stdout().write_all(&input)?; |
| io::stdout().write_all(&input)?; |
| Ok(()) |
| } |