Do not panic if the pipes a closed before all the output is written

This commit is contained in:
Pierre Peltier 2019-12-11 10:46:41 +01:00 committed by Pierre Peltier
parent 748a2722a2
commit 87e87d87cd
3 changed files with 55 additions and 11 deletions

View file

@ -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);
}
}

View file

@ -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());

View file

@ -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;
}
};