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;