diff --git a/tokio/src/fs/try_exists.rs b/tokio/src/fs/try_exists.rs index d7e5154f3e4..4bfaf041d01 100644 --- a/tokio/src/fs/try_exists.rs +++ b/tokio/src/fs/try_exists.rs @@ -1,4 +1,6 @@ use crate::fs::asyncify; + +use std::io; use std::path::Path; /// Returns `Ok(true)` if the path points at an existing entity. @@ -6,9 +8,9 @@ use std::path::Path; /// This function will traverse symbolic links to query information about the /// destination file. In case of broken symbolic links this will return `Ok(false)`. /// -/// This is the async equivalent of [`std::fs::try_exists`][std]. +/// This is the async equivalent of [`std::path::Path::try_exists`][std]. /// -/// [std]: fn@std::fs::try_exists +/// [std]: fn@std::path::Path::try_exists /// /// # Examples /// @@ -21,11 +23,7 @@ use std::path::Path; /// # } /// ``` -pub async fn try_exists(path: impl AsRef) -> Result { +pub async fn try_exists(path: impl AsRef) -> io::Result { let path = path.as_ref().to_owned(); - match asyncify(move || std::fs::metadata(path)).await { - Ok(_) => Ok(true), - Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(false), - Err(error) => Err(error), - } + asyncify(move || path.as_path().try_exists()).await } diff --git a/tokio/tests/fs_try_exists.rs b/tokio/tests/fs_try_exists.rs new file mode 100644 index 00000000000..3a0b61e4b4e --- /dev/null +++ b/tokio/tests/fs_try_exists.rs @@ -0,0 +1,41 @@ +#![warn(rust_2018_idioms)] +#![cfg(all(feature = "full", not(tokio_wasi)))] // Wasi does not support file operations + +use std::os::unix::prelude::PermissionsExt; + +use tempfile::tempdir; +use tokio::fs; + +#[tokio::test] +async fn try_exists() { + let dir = tempdir().unwrap(); + + let existing_path = dir.path().join("foo.txt"); + fs::write(&existing_path, b"Hello File!").await.unwrap(); + let nonexisting_path = dir.path().join("bar.txt"); + + assert_eq!(fs::try_exists(existing_path).await.unwrap(), true); + assert_eq!(fs::try_exists(nonexisting_path).await.unwrap(), false); + + let permission_denied_directory_path = dir.path().join("baz"); + fs::create_dir(&permission_denied_directory_path) + .await + .unwrap(); + let permission_denied_file_path = permission_denied_directory_path.join("baz.txt"); + fs::write(&permission_denied_file_path, b"Hello File!") + .await + .unwrap(); + let mut perms = tokio::fs::metadata(&permission_denied_directory_path) + .await + .unwrap() + .permissions(); + perms.set_mode(0o244); + fs::set_permissions(&permission_denied_directory_path, perms) + .await + .unwrap(); + let permission_denied_result = fs::try_exists(permission_denied_file_path).await; + assert_eq!( + permission_denied_result.err().unwrap().kind(), + std::io::ErrorKind::PermissionDenied + ); +}