From 87e87d87cdf91d7e8a3f385b0a5beb96ddbd8824 Mon Sep 17 00:00:00 2001 From: Pierre Peltier Date: Wed, 11 Dec 2019 10:46:41 +0100 Subject: Do not panic if the pipes a closed before all the output is written --- src/core.rs | 10 +++++----- src/main.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ src/meta/mod.rs | 13 +++++++------ 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/core.rs b/src/core.rs index 60c73e7..6a120b3 100644 --- a/src/core.rs +++ b/src/core.rs @@ -3,7 +3,7 @@ use crate::display; use crate::flags::{Display, Flags, IconTheme, Layout, WhenFlag}; use crate::icon::{self, Icons}; use crate::meta::Meta; -use crate::sort; +use crate::{print_error, print_output, sort}; use std::fs; use std::path::PathBuf; @@ -84,14 +84,14 @@ impl Core { for path in paths { if let Err(err) = fs::canonicalize(&path) { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } let mut meta = match Meta::from_path(&path) { Ok(meta) => meta, Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } }; @@ -107,7 +107,7 @@ impl Core { meta_list.push(meta); } Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } }; @@ -140,6 +140,6 @@ impl Core { display::grid(&metas, &self.flags, &self.colors, &self.icons) }; - print!("{}", output); + print_output!("{}", output); } } diff --git a/src/main.rs b/src/main.rs index 87440b6..5251884 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,6 +38,49 @@ use crate::core::Core; use crate::flags::Flags; use std::path::PathBuf; +/// Macro used to avoid panicking when the lsd method is used with a pipe and +/// stderr close before our program. +#[macro_export] +macro_rules! print_error { + ($($arg:tt)*) => { + use std::io::Write; + + let stderr = std::io::stderr(); + + { + let mut handle = stderr.lock(); + // We can write on stderr, so we simply ignore the error and don't print + // and stop with success. + let res = handle.write_all(std::format!($($arg)*).as_bytes()); + if res.is_err() { + std::process::exit(0); + } + } + }; +} + +/// Macro used to avoid panicking when the lsd method is used with a pipe and +/// stdout close before our program. +#[macro_export] +macro_rules! print_output { + ($($arg:tt)*) => { + use std::io::Write; + + let stderr = std::io::stdout(); + + + { + let mut handle = stderr.lock(); + // We can write on stdout, so we simply ignore the error and don't print + // and stop with success. + let res = handle.write_all(std::format!($($arg)*).as_bytes()); + if res.is_err() { + std::process::exit(0); + } + } + }; +} + fn main() { let matches = app::build().get_matches_from(wild::args_os()); diff --git a/src/meta/mod.rs b/src/meta/mod.rs index 4f51191..69bc34f 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -20,6 +20,7 @@ pub use self::size::Size; pub use self::symlink::SymLink; pub use crate::flags::Display; pub use crate::icon::Icons; +use crate::print_error; use std::fs; use std::fs::read_link; @@ -65,7 +66,7 @@ impl Meta { let entries = match self.path.read_dir() { Ok(entries) => entries, Err(err) => { - eprintln!("cannot access '{}': {}", self.path.display(), err); + print_error!("cannot access '{}': {}", self.path.display(), err); return Ok(None); } }; @@ -112,7 +113,7 @@ impl Meta { let mut entry_meta = match Self::from_path(&path) { Ok(res) => res, Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } }; @@ -120,7 +121,7 @@ impl Meta { match entry_meta.recurse_into(depth - 1, display, ignore_globs) { Ok(content) => entry_meta.content = content, Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } }; @@ -158,7 +159,7 @@ impl Meta { let metadata = match metadata { Ok(meta) => meta, Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); return 0; } }; @@ -171,7 +172,7 @@ impl Meta { let entries = match path.read_dir() { Ok(entries) => entries, Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); return size; } }; @@ -179,7 +180,7 @@ impl Meta { let path = match entry { Ok(entry) => entry.path(), Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } }; -- cgit v1.2.3