summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Peltier <pierre.peltier@adevinta.com>2019-12-11 10:46:41 +0100
committerPierre Peltier <8608160+Peltoche@users.noreply.github.com>2020-01-07 16:40:58 +0100
commit87e87d87cdf91d7e8a3f385b0a5beb96ddbd8824 (patch)
tree0f1f6067a28d596c41fcb714abe11967ebccb8c0
parent748a2722a2688b44d8d70d3f87899dccbf66f937 (diff)
Do not panic if the pipes a closed before all the output is written
-rw-r--r--src/core.rs10
-rw-r--r--src/main.rs43
-rw-r--r--src/meta/mod.rs13
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;
}
};