This is an automated email from the ASF dual-hosted git repository.

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new b8e034cd1 Ignore broken symlinks for LocalFileSystem object store 
(#2195)
b8e034cd1 is described below

commit b8e034cd10cff676d8cbbeab0d33f93b6a2aaae4
Author: Jean-Charles Campagne <[email protected]>
AuthorDate: Thu Jul 28 10:57:34 2022 +0100

    Ignore broken symlinks for LocalFileSystem object store (#2195)
    
    * Re-enable test_list_root test for MacOS
    
    * LocalFileSystem: ignore broken links in convert_walkdir_result
---
 object_store/src/local.rs | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/object_store/src/local.rs b/object_store/src/local.rs
index 798edef6f..e2f133e84 100644
--- a/object_store/src/local.rs
+++ b/object_store/src/local.rs
@@ -27,7 +27,7 @@ use futures::future::BoxFuture;
 use futures::FutureExt;
 use futures::{stream::BoxStream, StreamExt};
 use snafu::{ensure, OptionExt, ResultExt, Snafu};
-use std::fs::File;
+use std::fs::{metadata, symlink_metadata, File};
 use std::io::{Read, Seek, SeekFrom, Write};
 use std::ops::Range;
 use std::pin::Pin;
@@ -804,11 +804,36 @@ fn convert_metadata(metadata: std::fs::Metadata, 
location: Path) -> Result<Objec
 }
 
 /// Convert walkdir results and converts not-found errors into `None`.
+/// Convert broken symlinks to `None`.
 fn convert_walkdir_result(
     res: std::result::Result<walkdir::DirEntry, walkdir::Error>,
 ) -> Result<Option<walkdir::DirEntry>> {
     match res {
-        Ok(entry) => Ok(Some(entry)),
+        Ok(entry) => {
+            // To check for broken symlink: call symlink_metadata() - it does 
not traverse symlinks);
+            // if ok: check if entry is symlink; and try to read it by calling 
metadata().
+            match symlink_metadata(entry.path()) {
+                Ok(attr) => {
+                    if attr.is_symlink() {
+                        let target_metadata = metadata(entry.path());
+                        match target_metadata {
+                            Ok(_) => {
+                                // symlink is valid
+                                Ok(Some(entry))
+                            }
+                            Err(_) => {
+                                // this is a broken symlink, return None
+                                Ok(None)
+                            }
+                        }
+                    } else {
+                        Ok(Some(entry))
+                    }
+                }
+                Err(_) => Ok(None),
+            }
+        }
+
         Err(walkdir_err) => match walkdir_err.io_error() {
             Some(io_err) => match io_err.kind() {
                 io::ErrorKind::NotFound => Ok(None),
@@ -990,8 +1015,6 @@ mod tests {
     }
 
     #[tokio::test]
-    #[cfg(target_os = "linux")]
-    // macos has some magic in its root '/.VolumeIcon.icns"' which causes this 
test to fail
     async fn test_list_root() {
         let integration = LocalFileSystem::new();
         let result = integration.list_with_delimiter(None).await;

Reply via email to