Explorar o código

Merge pull request #319 from eza-community/cafk-exit-13

fix(file): exit 13 on os error 13
Christina Sørensen %!s(int64=2) %!d(string=hai) anos
pai
achega
86ad5270c4
Modificáronse 4 ficheiros con 19 adicións e 2 borrados
  1. 1 0
      src/fs/dir.rs
  2. 2 0
      src/fs/file.rs
  3. 13 2
      src/main.rs
  4. 3 0
      src/output/details.rs

+ 1 - 0
src/fs/dir.rs

@@ -42,6 +42,7 @@ impl Dir {
                           .map(|result| result.map(|entry| entry.path()))
                           .collect::<Result<_, _>>()?;
 
+        info!("Read directory success {:?}", &path);
         Ok(Self { contents, path })
     }
 

+ 2 - 0
src/fs/file.rs

@@ -204,6 +204,7 @@ impl<'dir> File<'dir> {
     /// Returns an IO error upon failure, but this shouldn’t be used to check
     /// if a `File` is a directory or not! For that, just use `is_directory()`.
     pub fn to_dir(&self) -> io::Result<Dir> {
+        trace!("to_dir: reading dir");
         Dir::read_dir(self.path.clone())
     }
 
@@ -531,6 +532,7 @@ impl<'dir> File<'dir> {
     /// but as mentioned in the size function comment above, different filesystems
     /// make it difficult to get any info about a dir by it's size, so this may be it.
     fn is_empty_directory(&self) -> bool {
+        trace!("is_empty_directory: reading dir");
         match Dir::read_dir(self.path.clone()) {
             // . & .. are skipped, if the returned iterator has .next(), it's not empty
             Ok(has_files) => has_files.files(super::DotFilter::Dotfiles, None, false, false).next().is_none(),

+ 13 - 2
src/main.rs

@@ -27,6 +27,7 @@ use std::env;
 use std::ffi::{OsStr, OsString};
 use std::io::{self, Write, ErrorKind};
 use std::path::{Component, PathBuf};
+use std::process::exit;
 
 use ansiterm::{ANSIStrings, Style};
 
@@ -87,8 +88,6 @@ lazy_static! {
 }
 
 fn main() {
-    use std::process::exit;
-
     #[cfg(unix)]
     unsafe {
         libc::signal(libc::SIGPIPE, libc::SIG_DFL);
@@ -118,8 +117,11 @@ fn main() {
             let theme = options.theme.to_theme(terminal_size::terminal_size().is_some());
             let exa = Exa { options, writer, input_paths, theme, console_width, git };
 
+
+            info!("matching on exa.run");
             match exa.run() {
                 Ok(exit_status) => {
+                    trace!("exa.run: exit Ok(exit_status)");
                     exit(exit_status);
                 }
 
@@ -130,6 +132,7 @@ fn main() {
 
                 Err(e) => {
                     eprintln!("{e}");
+                    trace!("exa.run: exit RUNTIME_ERROR");
                     exit(exits::RUNTIME_ERROR);
                 }
             }
@@ -225,8 +228,13 @@ impl<'args> Exa<'args> {
 
                 Ok(f) => {
                     if f.points_to_directory() && ! self.options.dir_action.treat_dirs_as_files() {
+                        trace!("matching on to_dir");
                         match f.to_dir() {
                             Ok(d)   => dirs.push(d),
+                            Err(e) if e.kind() == ErrorKind::PermissionDenied => {
+                                warn!("Permission Denied: {e}");
+                                exit(exits::PERMISSION_DENIED);
+                            },
                             Err(e)  => writeln!(io::stderr(), "{file_path:?}: {e}")?,
                         }
                     }
@@ -378,4 +386,7 @@ mod exits {
 
     /// Exit code for when the command-line options are invalid.
     pub const OPTIONS_ERROR: i32 = 3;
+
+    /// Exit code for missing file permissions
+    pub const PERMISSION_DENIED: i32 = 13;
 }

+ 3 - 0
src/output/details.rs

@@ -68,6 +68,8 @@ use std::vec::IntoIter as VecIntoIter;
 use ansiterm::Style;
 use scoped_threadpool::Pool;
 
+use log::*;
+
 use crate::fs::{Dir, File};
 use crate::fs::dir_action::RecurseOptions;
 use crate::fs::feature::git::GitCache;
@@ -261,6 +263,7 @@ impl<'a> Render<'a> {
                     let mut dir = None;
                     if let Some(r) = self.recurse {
                         if file.is_directory() && r.tree && ! r.is_too_deep(depth.0) {
+                            trace!("matching on to_dir");
                             match file.to_dir() {
                                 Ok(d) => {
                                     dir = Some(d);