1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

tests: Use UChild in tests. Rename run_no_wait_child to run_no_wait and return UChild

tests/tail:
* test_stdin_redirect_file:. Test fails now when assert_alive()!
The follow test `tail -f < file` where file's content is `foo` fails with:
    Assertion failed. Expected 'tail' to be running but exited with status=exit status: 0

I also tried on the command line and can confirm that tail isn't runnning when following by
descriptor. The test is deactivated until the implementation is fixed.

* test_follow_stdin_descriptor
* test_follow_stdin_explicit_indefinitely.
* test_follow_single
* test_follow_non_utf8_bytes
* test_follow_multiple
* test_follow_name_multiple
* test_follow_invalid_pid
* test_single_big_args
* test_retry3
* test_retry4
* test_retry5
* test_retry7
* test_retry8
* test_retry9
* test_follow_descriptor_vs_rename1
* test_follow_descriptor_vs_rename2
* test_follow_name_retry_headers
* test_follow_name_remove
* test_follow_name_truncate1
* test_follow_name_truncate2
* test_follow_name_truncate3
* test_follow_name_truncate4
* test_follow_truncate_fast
* test_follow_name_move_create1
* test_follow_name_move_create2
* test_follow_name_move1
* test_follow_name_move2
* test_follow_name_move_retry1
* test_follow_name_move_retry2
* test_follow_inotify_only_regular
* test_fifo
* test_illegal_seek

tests/cat:
* test_dev_full
* test_dev_full_show_all
* test_dev_random
* test_fifo_symlink

tests/dd:
* test_random_73k_test_lazy_fullblock
* test_sync_delayed_reader

tests/factor:
* test_parallel

tests/rm:
* test_rm_force_prompts_order
* test_rm_descend_directory
* test_rm_prompts

tests/seq:
* the helper run method

tests/sort:
* test_sigpipe_panic

tests/tee:
* the helper run_tee method

tests/tty:
* test_tty module

tests/yes:
* the helper run method
This commit is contained in:
Joining7943 2022-11-18 01:25:43 +01:00
parent 040a5e8301
commit 982fb682e9
11 changed files with 519 additions and 474 deletions

View file

@ -1,12 +1,11 @@
// spell-checker:ignore NOFILE // spell-checker:ignore NOFILE
use crate::common::util::*; use crate::common::util::*;
use std::fs::OpenOptions;
#[cfg(unix)]
use std::io::Read;
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
use rlimit::Resource; use rlimit::Resource;
use std::fs::OpenOptions;
#[cfg(not(windows))]
use std::process::Stdio;
#[test] #[test]
fn test_output_simple() { fn test_output_simple() {
@ -87,8 +86,7 @@ fn test_fifo_symlink() {
pipe.write_all(&data).unwrap(); pipe.write_all(&data).unwrap();
}); });
let output = proc.wait_with_output().unwrap(); proc.wait().unwrap().stdout_only_bytes(data2);
assert_eq!(&output.stdout, &data2);
thread.join().unwrap(); thread.join().unwrap();
} }
@ -395,17 +393,19 @@ fn test_squeeze_blank_before_numbering() {
#[test] #[test]
#[cfg(unix)] #[cfg(unix)]
fn test_dev_random() { fn test_dev_random() {
let mut buf = [0; 2048];
#[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(any(target_os = "linux", target_os = "android"))]
const DEV_RANDOM: &str = "/dev/urandom"; const DEV_RANDOM: &str = "/dev/urandom";
#[cfg(not(any(target_os = "linux", target_os = "android")))] #[cfg(not(any(target_os = "linux", target_os = "android")))]
const DEV_RANDOM: &str = "/dev/random"; const DEV_RANDOM: &str = "/dev/random";
let mut proc = new_ucmd!().args(&[DEV_RANDOM]).run_no_wait(); let mut proc = new_ucmd!()
let mut proc_stdout = proc.stdout.take().unwrap(); .set_stdout(Stdio::piped())
proc_stdout.read_exact(&mut buf).unwrap(); .args(&[DEV_RANDOM])
.run_no_wait();
proc.make_assertion_with_delay(100).is_alive();
let buf = proc.stdout_exact_bytes(2048);
let num_zeroes = buf.iter().fold(0, |mut acc, &n| { let num_zeroes = buf.iter().fold(0, |mut acc, &n| {
if n == 0 { if n == 0 {
acc += 1; acc += 1;
@ -415,7 +415,7 @@ fn test_dev_random() {
// The probability of more than 512 zero bytes is essentially zero if the // The probability of more than 512 zero bytes is essentially zero if the
// output is truly random. // output is truly random.
assert!(num_zeroes < 512); assert!(num_zeroes < 512);
proc.kill().unwrap(); proc.kill();
} }
/// Reading from /dev/full should return an infinite amount of zero bytes. /// Reading from /dev/full should return an infinite amount of zero bytes.
@ -423,29 +423,35 @@ fn test_dev_random() {
#[test] #[test]
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))] #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
fn test_dev_full() { fn test_dev_full() {
let mut buf = [0; 2048]; let mut proc = new_ucmd!()
let mut proc = new_ucmd!().args(&["/dev/full"]).run_no_wait(); .set_stdout(Stdio::piped())
let mut proc_stdout = proc.stdout.take().unwrap(); .args(&["/dev/full"])
.run_no_wait();
let expected = [0; 2048]; let expected = [0; 2048];
proc_stdout.read_exact(&mut buf).unwrap(); proc.make_assertion_with_delay(100)
assert_eq!(&buf[..], &expected[..]); .is_alive()
proc.kill().unwrap(); .with_exact_output(2048, 0)
.stdout_only_bytes(expected);
proc.kill();
} }
#[test] #[test]
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))] #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
fn test_dev_full_show_all() { fn test_dev_full_show_all() {
let mut buf = [0; 2048]; let buf_len = 2048;
let mut proc = new_ucmd!().args(&["-A", "/dev/full"]).run_no_wait(); let mut proc = new_ucmd!()
let mut proc_stdout = proc.stdout.take().unwrap(); .set_stdout(Stdio::piped())
proc_stdout.read_exact(&mut buf).unwrap(); .args(&["-A", "/dev/full"])
.run_no_wait();
let expected: Vec<u8> = (0..buf.len()) let expected: Vec<u8> = (0..buf_len)
.map(|n| if n & 1 == 0 { b'^' } else { b'@' }) .map(|n| if n & 1 == 0 { b'^' } else { b'@' })
.collect(); .collect();
assert_eq!(&buf[..], &expected[..]); proc.make_assertion_with_delay(100)
proc.kill().unwrap(); .is_alive()
.with_exact_output(buf_len, 0)
.stdout_only_bytes(expected);
proc.kill();
} }
#[test] #[test]

View file

@ -1036,11 +1036,12 @@ fn test_random_73k_test_lazy_fullblock() {
sleep(Duration::from_millis(10)); sleep(Duration::from_millis(10));
} }
} }
let output = child.wait_with_output().unwrap(); child
assert!(output.status.success()); .wait()
.unwrap()
assert_eq!(&output.stdout, &data); .success()
assert_eq!(&output.stderr, b"142+1 records in\n72+1 records out\n"); .stdout_is_bytes(&data)
.stderr_is("142+1 records in\n72+1 records out\n");
} }
#[test] #[test]
@ -1381,9 +1382,6 @@ fn test_sync_delayed_reader() {
sleep(Duration::from_millis(10)); sleep(Duration::from_millis(10));
} }
} }
let output = child.wait_with_output().unwrap();
assert!(output.status.success());
// Expected output is 0xFFFFFFFF00000000FFFFFFFF00000000... // Expected output is 0xFFFFFFFF00000000FFFFFFFF00000000...
let mut expected: [u8; 8 * 16] = [0; 8 * 16]; let mut expected: [u8; 8 * 16] = [0; 8 * 16];
for i in 0..8 { for i in 0..8 {
@ -1391,8 +1389,13 @@ fn test_sync_delayed_reader() {
expected[16 * i + j] = 0xF; expected[16 * i + j] = 0xF;
} }
} }
assert_eq!(&output.stdout, &expected);
assert_eq!(&output.stderr, b"0+8 records in\n4+0 records out\n"); child
.wait()
.unwrap()
.success()
.stdout_is_bytes(expected)
.stderr_is("0+8 records in\n4+0 records out\n");
} }
/// Test for making a sparse copy of the input file. /// Test for making a sparse copy of the input file.

View file

@ -52,7 +52,7 @@ fn test_parallel() {
.open(tmp_dir.plus("output")) .open(tmp_dir.plus("output"))
.unwrap(); .unwrap();
for mut child in (0..10) for child in (0..10)
.map(|_| { .map(|_| {
new_ucmd!() new_ucmd!()
.set_stdout(output.try_clone().unwrap()) .set_stdout(output.try_clone().unwrap())
@ -61,7 +61,7 @@ fn test_parallel() {
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
{ {
assert_eq!(child.wait().unwrap().code().unwrap(), 0); child.wait().unwrap().success();
} }
let result = TestScenario::new(util_name!()) let result = TestScenario::new(util_name!())

View file

@ -357,8 +357,6 @@ fn test_rm_interactive_never() {
fn test_rm_descend_directory() { fn test_rm_descend_directory() {
// This test descends into each directory and deletes the files and folders inside of them // This test descends into each directory and deletes the files and folders inside of them
// This test will have the rm process asks 6 question and us answering Y to them will delete all the files and folders // This test will have the rm process asks 6 question and us answering Y to them will delete all the files and folders
use std::io::Write;
use std::process::Child;
// Needed for talking with stdin on platforms where CRLF or LF matters // Needed for talking with stdin on platforms where CRLF or LF matters
const END_OF_LINE: &str = if cfg!(windows) { "\r\n" } else { "\n" }; const END_OF_LINE: &str = if cfg!(windows) { "\r\n" } else { "\n" };
@ -375,24 +373,15 @@ fn test_rm_descend_directory() {
at.touch(file_1); at.touch(file_1);
at.touch(file_2); at.touch(file_2);
let mut child: Child = scene.ucmd().arg("-ri").arg("a").run_no_wait(); let mut child = scene.ucmd().arg("-ri").arg("a").run_no_wait();
child.write_in(yes.as_bytes()).unwrap();
child.write_in(yes.as_bytes()).unwrap();
child.write_in(yes.as_bytes()).unwrap();
child.write_in(yes.as_bytes()).unwrap();
child.write_in(yes.as_bytes()).unwrap();
child.write_in(yes.as_bytes()).unwrap();
// Needed so that we can talk to the rm program child.wait().unwrap();
let mut child_stdin = child.stdin.take().unwrap();
child_stdin.write_all(yes.as_bytes()).unwrap();
child_stdin.flush().unwrap();
child_stdin.write_all(yes.as_bytes()).unwrap();
child_stdin.flush().unwrap();
child_stdin.write_all(yes.as_bytes()).unwrap();
child_stdin.flush().unwrap();
child_stdin.write_all(yes.as_bytes()).unwrap();
child_stdin.flush().unwrap();
child_stdin.write_all(yes.as_bytes()).unwrap();
child_stdin.flush().unwrap();
child_stdin.write_all(yes.as_bytes()).unwrap();
child_stdin.flush().unwrap();
child.wait_with_output().unwrap();
assert!(!at.dir_exists("a/b")); assert!(!at.dir_exists("a/b"));
assert!(!at.dir_exists("a")); assert!(!at.dir_exists("a"));
@ -404,7 +393,6 @@ fn test_rm_descend_directory() {
#[test] #[test]
fn test_rm_prompts() { fn test_rm_prompts() {
use std::io::Write; use std::io::Write;
use std::process::Child;
// Needed for talking with stdin on platforms where CRLF or LF matters // Needed for talking with stdin on platforms where CRLF or LF matters
const END_OF_LINE: &str = if cfg!(windows) { "\r\n" } else { "\n" }; const END_OF_LINE: &str = if cfg!(windows) { "\r\n" } else { "\n" };
@ -457,21 +445,15 @@ fn test_rm_prompts() {
.arg(file_2) .arg(file_2)
.succeeds(); .succeeds();
let mut child: Child = scene.ucmd().arg("-ri").arg("a").run_no_wait(); let mut child = scene.ucmd().arg("-ri").arg("a").run_no_wait();
let mut child_stdin = child.stdin.take().unwrap();
for _ in 0..9 { for _ in 0..9 {
child_stdin.write_all(yes.as_bytes()).unwrap(); child.write_in(yes.as_bytes()).unwrap();
child_stdin.flush().unwrap();
} }
let output = child.wait_with_output().unwrap(); let result = child.wait().unwrap();
let mut trimmed_output = Vec::new(); let mut trimmed_output = Vec::new();
for string in String::from_utf8(output.stderr) for string in result.stderr_str().split("rm: ") {
.expect("Couldn't convert output.stderr to string")
.split("rm: ")
{
if !string.is_empty() { if !string.is_empty() {
let trimmed_string = format!("rm: {}", string).trim().to_string(); let trimmed_string = format!("rm: {}", string).trim().to_string();
trimmed_output.push(trimmed_string); trimmed_output.push(trimmed_string);
@ -491,9 +473,6 @@ fn test_rm_prompts() {
#[test] #[test]
fn test_rm_force_prompts_order() { fn test_rm_force_prompts_order() {
use std::io::Write;
use std::process::Child;
// Needed for talking with stdin on platforms where CRLF or LF matters // Needed for talking with stdin on platforms where CRLF or LF matters
const END_OF_LINE: &str = if cfg!(windows) { "\r\n" } else { "\n" }; const END_OF_LINE: &str = if cfg!(windows) { "\r\n" } else { "\n" };
@ -507,15 +486,11 @@ fn test_rm_force_prompts_order() {
at.touch(empty_file); at.touch(empty_file);
// This should cause rm to prompt to remove regular empty file // This should cause rm to prompt to remove regular empty file
let mut child: Child = scene.ucmd().arg("-fi").arg(empty_file).run_no_wait(); let mut child = scene.ucmd().arg("-fi").arg(empty_file).run_no_wait();
child.write_in(yes.as_bytes()).unwrap();
let mut child_stdin = child.stdin.take().unwrap(); let result = child.wait().unwrap();
child_stdin.write_all(yes.as_bytes()).unwrap(); let string_output = result.stderr_str();
child_stdin.flush().unwrap();
let output = child.wait_with_output().unwrap();
let string_output =
String::from_utf8(output.stderr).expect("Couldn't convert output.stderr to string");
assert_eq!( assert_eq!(
string_output.trim(), string_output.trim(),
"rm: remove regular empty file 'empty'?" "rm: remove regular empty file 'empty'?"

View file

@ -1,6 +1,6 @@
// spell-checker:ignore lmnop xlmnop // spell-checker:ignore lmnop xlmnop
use crate::common::util::*; use crate::common::util::*;
use std::io::Read; use std::process::Stdio;
#[test] #[test]
fn test_invalid_arg() { fn test_invalid_arg() {
@ -595,12 +595,10 @@ fn test_width_floats() {
/// Run `seq`, capture some of the output, close the pipe, and verify it. /// Run `seq`, capture some of the output, close the pipe, and verify it.
fn run(args: &[&str], expected: &[u8]) { fn run(args: &[&str], expected: &[u8]) {
let mut cmd = new_ucmd!(); let mut cmd = new_ucmd!();
let mut child = cmd.args(args).run_no_wait(); let mut child = cmd.args(args).set_stdout(Stdio::piped()).run_no_wait();
let mut stdout = child.stdout.take().unwrap(); let buf = child.stdout_exact_bytes(expected.len());
let mut buf = vec![0; expected.len()]; child.close_stdout();
stdout.read_exact(&mut buf).unwrap(); child.wait().unwrap().success();
drop(stdout);
assert!(child.wait().unwrap().success());
assert_eq!(buf.as_slice(), expected); assert_eq!(buf.as_slice(), expected);
} }

View file

@ -976,7 +976,7 @@ fn test_sigpipe_panic() {
let mut child = cmd.args(&["ext_sort.txt"]).run_no_wait(); let mut child = cmd.args(&["ext_sort.txt"]).run_no_wait();
// Dropping the stdout should not lead to an error. // Dropping the stdout should not lead to an error.
// The "Broken pipe" error should be silently ignored. // The "Broken pipe" error should be silently ignored.
drop(child.stdout.take()); child.close_stdout();
assert_eq!( assert_eq!(
String::from_utf8(child.wait_with_output().unwrap().stderr), String::from_utf8(child.wait_with_output().unwrap().stderr),
Ok(String::new()) Ok(String::new())
@ -1137,7 +1137,7 @@ fn test_tmp_files_deleted_on_sigint() {
"--buffer-size=1", // with a small buffer size `sort` will be forced to create a temporary directory very soon. "--buffer-size=1", // with a small buffer size `sort` will be forced to create a temporary directory very soon.
"--temporary-directory=tmp_dir", "--temporary-directory=tmp_dir",
]); ]);
let mut child = ucmd.run_no_wait(); let child = ucmd.run_no_wait();
// wait a short amount of time so that `sort` can create a temporary directory. // wait a short amount of time so that `sort` can create a temporary directory.
let mut timeout = Duration::from_millis(100); let mut timeout = Duration::from_millis(100);
for _ in 0..5 { for _ in 0..5 {
@ -1152,7 +1152,7 @@ fn test_tmp_files_deleted_on_sigint() {
// kill sort with SIGINT // kill sort with SIGINT
signal::kill(Pid::from_raw(child.id() as i32), signal::SIGINT).unwrap(); signal::kill(Pid::from_raw(child.id() as i32), signal::SIGINT).unwrap();
// wait for `sort` to exit // wait for `sort` to exit
assert_eq!(child.wait().unwrap().code(), Some(2)); child.wait().unwrap().code_is(2);
// `sort` should have deleted the temporary directory again. // `sort` should have deleted the temporary directory again.
assert!(read_dir(at.plus("tmp_dir")).unwrap().next().is_none()); assert!(read_dir(at.plus("tmp_dir")).unwrap().next().is_none());
} }

File diff suppressed because it is too large Load diff

View file

@ -111,9 +111,7 @@ mod linux_only {
use crate::common::util::*; use crate::common::util::*;
use std::fs::File; use std::fs::File;
use std::io::Write;
use std::process::Output; use std::process::Output;
use std::thread;
fn make_broken_pipe() -> File { fn make_broken_pipe() -> File {
use libc::c_int; use libc::c_int;
@ -133,22 +131,9 @@ mod linux_only {
fn run_tee(proc: &mut UCommand) -> (String, Output) { fn run_tee(proc: &mut UCommand) -> (String, Output) {
let content = (1..=100000).map(|x| format!("{}\n", x)).collect::<String>(); let content = (1..=100000).map(|x| format!("{}\n", x)).collect::<String>();
let output = proc
let mut prog = proc.run_no_wait(); .run_no_wait()
.pipe_in_and_wait_with_output(content.as_bytes());
let mut stdin = prog
.stdin
.take()
.unwrap_or_else(|| panic!("Could not take child process stdin"));
let c = content.clone();
let thread = thread::spawn(move || {
let _ = stdin.write_all(c.as_bytes());
});
let output = prog.wait_with_output().unwrap();
thread.join().unwrap();
(content, output) (content, output)
} }

View file

@ -26,37 +26,29 @@ fn test_dev_null_silent() {
#[test] #[test]
fn test_close_stdin() { fn test_close_stdin() {
let mut child = new_ucmd!().run_no_wait(); let mut child = new_ucmd!().run_no_wait();
drop(child.stdin.take()); child.close_stdin();
let output = child.wait_with_output().unwrap(); child.wait().unwrap().code_is(1).stdout_is("not a tty\n");
assert_eq!(output.status.code(), Some(1));
assert_eq!(std::str::from_utf8(&output.stdout), Ok("not a tty\n"));
} }
#[test] #[test]
fn test_close_stdin_silent() { fn test_close_stdin_silent() {
let mut child = new_ucmd!().arg("-s").run_no_wait(); let mut child = new_ucmd!().arg("-s").run_no_wait();
drop(child.stdin.take()); child.close_stdin();
let output = child.wait_with_output().unwrap(); child.wait().unwrap().code_is(1).no_stdout();
assert_eq!(output.status.code(), Some(1));
assert!(output.stdout.is_empty());
} }
#[test] #[test]
fn test_close_stdin_silent_long() { fn test_close_stdin_silent_long() {
let mut child = new_ucmd!().arg("--silent").run_no_wait(); let mut child = new_ucmd!().arg("--silent").run_no_wait();
drop(child.stdin.take()); child.close_stdin();
let output = child.wait_with_output().unwrap(); child.wait().unwrap().code_is(1).no_stdout();
assert_eq!(output.status.code(), Some(1));
assert!(output.stdout.is_empty());
} }
#[test] #[test]
fn test_close_stdin_silent_alias() { fn test_close_stdin_silent_alias() {
let mut child = new_ucmd!().arg("--quiet").run_no_wait(); let mut child = new_ucmd!().arg("--quiet").run_no_wait();
drop(child.stdin.take()); child.close_stdin();
let output = child.wait_with_output().unwrap(); child.wait().unwrap().code_is(1).no_stdout();
assert_eq!(output.status.code(), Some(1));
assert!(output.stdout.is_empty());
} }
#[test] #[test]

View file

@ -1,5 +1,4 @@
use std::io::Read; use std::process::{ExitStatus, Stdio};
use std::process::ExitStatus;
#[cfg(unix)] #[cfg(unix)]
use std::os::unix::process::ExitStatusExt; use std::os::unix::process::ExitStatusExt;
@ -19,12 +18,10 @@ fn check_termination(result: &ExitStatus) {
/// Run `yes`, capture some of the output, close the pipe, and verify it. /// Run `yes`, capture some of the output, close the pipe, and verify it.
fn run(args: &[&str], expected: &[u8]) { fn run(args: &[&str], expected: &[u8]) {
let mut cmd = new_ucmd!(); let mut cmd = new_ucmd!();
let mut child = cmd.args(args).run_no_wait(); let mut child = cmd.args(args).set_stdout(Stdio::piped()).run_no_wait();
let mut stdout = child.stdout.take().unwrap(); let buf = child.stdout_exact_bytes(expected.len());
let mut buf = vec![0; expected.len()]; child.close_stdout();
stdout.read_exact(&mut buf).unwrap(); check_termination(&child.wait_with_output().unwrap().status);
drop(stdout);
check_termination(&child.wait().unwrap());
assert_eq!(buf.as_slice(), expected); assert_eq!(buf.as_slice(), expected);
} }

View file

@ -1118,28 +1118,15 @@ impl UCommand {
self self
} }
// TODO: Accept a parameter `delay` which returns delayed from this method. Most use cases are // TODO: Add convenience method run_no_wait_with_delay which accept a parameter `delay` which
// with some kind of post delay. Without any delay, the output may be empty because we return // returns delayed from run_no_wait. A lot of use cases are with some kind of post delay.
// immediately. Most of the time a delay of 1ms was already sufficient. // Without any delay, the output may be empty because we return immediately.
// TODO: rename this method after refactoring the tests to run_no_wait and merge with it
pub fn run_no_wait_child(&mut self) -> UChild {
let child = self.run_no_wait();
UChild::new(
child,
self.bin_path.clone(),
self.util_name.clone(),
self.tmpd.clone(),
self.captured_stdout.take(),
self.captured_stderr.take(),
self.ignore_stdin_write_error,
)
}
/// Spawns the command, feeds the stdin if any, and returns the /// Spawns the command, feeds the stdin if any, and returns the
/// child process immediately. Do not use this method directly /// child process immediately. Do not use this method directly
/// if you want to have stderr redirected to stdout. Use /// if you want to have stderr redirected to stdout. Use
/// [`UCommand::run_no_wait_stderr_to_stdout`] instead. /// [`UCommand::run_no_wait_stderr_to_stdout`] instead.
pub fn run_no_wait(&mut self) -> Child { pub fn run_no_wait(&mut self) -> UChild {
assert!(!self.has_run, "{}", ALREADY_RUN); assert!(!self.has_run, "{}", ALREADY_RUN);
self.has_run = true; self.has_run = true;
log_info("run", &self.comm_string); log_info("run", &self.comm_string);
@ -1204,7 +1191,15 @@ impl UCommand {
} }
} }
child UChild::new(
child,
self.bin_path.clone(),
self.util_name.clone(),
self.tmpd.clone(),
self.captured_stdout.take(),
self.captured_stderr.take(),
self.ignore_stdin_write_error,
)
} }
/// Spawns the command, feeds the stdin if any, waits for the result /// Spawns the command, feeds the stdin if any, waits for the result
@ -1212,8 +1207,8 @@ impl UCommand {
/// It is recommended that you instead use succeeds() or fails() /// It is recommended that you instead use succeeds() or fails()
pub fn run(&mut self) -> CmdResult { pub fn run(&mut self) -> CmdResult {
match self.bytes_into_stdin.take() { match self.bytes_into_stdin.take() {
Some(input) => self.run_no_wait_child().pipe_in_and_wait(input), Some(input) => self.run_no_wait().pipe_in_and_wait(input),
None => self.run_no_wait_child().wait().unwrap(), None => self.run_no_wait().wait().unwrap(),
} }
} }
@ -1223,7 +1218,7 @@ impl UCommand {
/// with succeeds() or fails() /// with succeeds() or fails()
pub fn run_piped_stdin<T: Into<Vec<u8>>>(&mut self, input: T) -> CmdResult { pub fn run_piped_stdin<T: Into<Vec<u8>>>(&mut self, input: T) -> CmdResult {
self.bytes_into_stdin = None; self.bytes_into_stdin = None;
self.run_no_wait_child().pipe_in_and_wait(input) self.run_no_wait().pipe_in_and_wait(input)
} }
/// Spawns the command, feeds the stdin if any, waits for the result, /// Spawns the command, feeds the stdin if any, waits for the result,