mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
Terminate on elimination of all writers in tee
tee is supposed to exit when there is nothing left to write to. For finite inputs, it can be hard to determine whether this functions correctly, but for tee of infinite streams, it is very important to exit when there is nothing more to write to.
This commit is contained in:
parent
5c13e88f8b
commit
607bf3ca4d
1 changed files with 17 additions and 4 deletions
|
@ -199,10 +199,18 @@ fn tee(options: &Options) -> Result<()> {
|
|||
inner: Box::new(stdin()) as Box<dyn Read>,
|
||||
};
|
||||
|
||||
// TODO: replaced generic 'copy' call to be able to stop copying
|
||||
// if all outputs are closed (due to errors)
|
||||
if copy(input, &mut output).is_err() || output.flush().is_err() || output.error_occurred() {
|
||||
Err(Error::new(ErrorKind::Other, ""))
|
||||
let res = match copy(input, &mut output) {
|
||||
// ErrorKind::Other is raised by MultiWriter when all writers
|
||||
// have exited, so that copy will abort. It's equivalent to
|
||||
// success of this part (if there was an error that should
|
||||
// cause a failure from any writer, that error would have been
|
||||
// returned instead).
|
||||
Err(e) if e.kind() != ErrorKind::Other => Err(e),
|
||||
_ => Ok(()),
|
||||
};
|
||||
|
||||
if res.is_err() || output.flush().is_err() || output.error_occurred() {
|
||||
Err(Error::from(ErrorKind::Other))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -313,6 +321,11 @@ impl Write for MultiWriter {
|
|||
self.ignored_errors += errors;
|
||||
if let Some(e) = aborted {
|
||||
Err(e)
|
||||
} else if self.writers.is_empty() {
|
||||
// This error kind will never be raised by the standard
|
||||
// library, so we can use it for early termination of
|
||||
// `copy`
|
||||
Err(Error::from(ErrorKind::Other))
|
||||
} else {
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue