From 84bb05035b51b05734eef44657cffd1fdb2950db Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Nov 2019 20:09:40 +0100 Subject: Fix: Ignore broken pipe when reporting ids This fixes a bug where a broken pipe in Runtime::report_touched() resulted in an Err(_) raised up to main() which then reported this. But as report_touched() should ignore a broken pipe (because the program will exit anyways shortly after the call), we can safely ignore this error. This also results in `ExitCode` removed from the function signature, which pushes us forward to the removal of custom error-handling implementations! Signed-off-by: Matthias Beyer --- lib/core/libimagrt/src/runtime.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/core/libimagrt/src/runtime.rs b/lib/core/libimagrt/src/runtime.rs index d8997a8b..a1a27c6c 100644 --- a/lib/core/libimagrt/src/runtime.rs +++ b/lib/core/libimagrt/src/runtime.rs @@ -24,7 +24,6 @@ use std::process::exit; use std::io::Stdin; use std::io::StdoutLock; use std::borrow::Borrow; -use std::result::Result as RResult; pub use clap::App; use clap::AppSettings; @@ -41,10 +40,8 @@ use crate::configuration::{fetch_config, override_config, InternalConfiguration} use crate::logger::ImagLogger; use crate::io::OutputProxy; -use libimagerror::exit::ExitCode; use libimagerror::errors::ErrorMsg as EM; use libimagerror::trace::*; -use libimagerror::io::ToExitCode; use libimagstore::store::Store; use libimagstore::storeid::StoreId; use libimagutil::debug_result::DebugResult; @@ -522,14 +519,14 @@ impl<'a> Runtime<'a> { .map_err(Error::from) } - pub fn report_touched(&self, id: &StoreId) -> RResult<(), ExitCode> { + pub fn report_touched(&self, id: &StoreId) -> Result<()> { let out = ::std::io::stdout(); let mut lock = out.lock(); - self.report_touched_id(id, &mut lock) + self.report_touched_id(id, &mut lock).map(|_| ()) } - pub fn report_all_touched(&self, ids: I) -> RResult<(), ExitCode> + pub fn report_all_touched(&self, ids: I) -> Result<()> where ID: Borrow + Sized, I: Iterator { @@ -537,22 +534,30 @@ impl<'a> Runtime<'a> { let mut lock = out.lock(); for id in ids { - self.report_touched_id(id.borrow(), &mut lock)?; + if !self.report_touched_id(id.borrow(), &mut lock)? { + break + } } Ok(()) } #[inline] - fn report_touched_id(&self, id: &StoreId, output: &mut StdoutLock) -> RResult<(), ExitCode> { + fn report_touched_id(&self, id: &StoreId, output: &mut StdoutLock) -> Result { use std::io::Write; if self.output_is_pipe() && !self.ignore_ids { trace!("Reporting: {} to {:?}", id, output); - writeln!(output, "{}", id).to_exit_code() - } else { - Ok(()) + if let Err(e) = writeln!(output, "{}", id) { + return if e.kind() == std::io::ErrorKind::BrokenPipe { + Ok(false) + } else { + Err(failure::Error::from(e)) + } + } } + + Ok(true) } } -- cgit v1.2.3