diff --git a/src/uu/tee/src/tee.rs b/src/uu/tee/src/tee.rs index 3ba565fe4f3..c176e7983b7 100644 --- a/src/uu/tee/src/tee.rs +++ b/src/uu/tee/src/tee.rs @@ -13,6 +13,10 @@ use uucore::display::Quotable; use uucore::error::{UResult, strip_errno}; use uucore::translate; +// This error kind will never be raised by std +// Use it for termination when all writers exited +use ErrorKind::Other as AllWriterExited; + mod cli; pub use crate::cli::uu_app; use crate::cli::{Options, OutputErrorMode, options}; @@ -59,14 +63,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { fn tee(options: &Options) -> Result<()> { #[cfg(unix)] { - // ErrorKind::Other is raised by MultiWriter when all writers have exited. - // This is therefore just a clever way to stop all writers - if options.ignore_interrupts { - ignore_interrupts().map_err(|_| Error::from(ErrorKind::Other))?; + ignore_interrupts().map_err(|_| Error::from(AllWriterExited))?; } if options.output_error.is_some() { - disable_pipe_errors().map_err(|_| Error::from(ErrorKind::Other))?; + disable_pipe_errors().map_err(|_| Error::from(AllWriterExited))?; } } let mut writers: Vec = options @@ -97,17 +98,12 @@ fn tee(options: &Options) -> Result<()> { // We cannot use std::io::copy here as it doesn't flush the output buffer let res = match output.copy_unbuffered(input) { - // 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), + Err(e) if e.kind() != AllWriterExited => Err(e), _ => Ok(()), }; if had_open_errors || res.is_err() || output.error_occurred() { - Err(Error::from(ErrorKind::Other)) + Err(Error::from(AllWriterExited)) } else { Ok(()) } @@ -203,6 +199,7 @@ impl MultiWriter { self.writers .retain_mut(|writer| match writer.inner.write_all(buf) { Ok(()) => true, + // if let guard needs Rust 1.95+ Err(e) => { if let Err(e) = process_error(mode, e, writer, &mut self.ignored_errors) { self.aborted.get_or_insert(e); @@ -210,17 +207,11 @@ impl MultiWriter { false } }); - self.aborted.take().map_or( - 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(()) - }, - Err, - ) + match self.aborted.take() { + Some(e) => Err(e), + None if self.writers.is_empty() => Err(Error::from(AllWriterExited)), + None => Ok(()), + } } }