diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index fd2e4bb5e13..41c4bfdb269 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -11,9 +11,7 @@ use log::{trace, warn}; use crate::core::source::MaybePackage; use crate::core::{Dependency, Package, PackageId, Source, SourceId, Summary}; use crate::ops; -use crate::util::paths; -use crate::util::Config; -use crate::util::{internal, CargoResult}; +use crate::util::{internal, paths, CargoResult, CargoResultExt, Config}; pub struct PathSource<'cfg> { source_id: SourceId, @@ -455,7 +453,10 @@ impl<'cfg> PathSource<'cfg> { // // TODO: drop `collect` and sort after transition period and dropping warning tests. // See rust-lang/cargo#4268 and rust-lang/cargo#4270. - let mut entries: Vec = fs::read_dir(path)?.map(|e| e.unwrap().path()).collect(); + let mut entries: Vec = fs::read_dir(path) + .chain_err(|| format!("cannot read {:?}", path))? + .map(|e| e.unwrap().path()) + .collect(); entries.sort_unstable_by(|a, b| a.as_os_str().cmp(b.as_os_str())); for path in entries { let name = path.file_name().and_then(|s| s.to_str()); diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index 106f1b1c8fa..3303327fea9 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -3720,9 +3720,7 @@ fn using_rerun_if_changed_does_not_rebuild() { .build(); p.cargo("build").run(); - p.cargo("build") - .with_stderr("[FINISHED] [..]") - .run(); + p.cargo("build").with_stderr("[FINISHED] [..]").run(); } #[test] @@ -3807,3 +3805,32 @@ fn links_interrupted_can_restart() { .with_stderr_contains("[RUNNING] [..]/foo-[..]/build-script-build[..]") .run(); } + +#[test] +#[cfg(unix)] +fn build_script_scan_eacces() { + // build.rs causes a scan of the whole project, which can be a problem if + // a directory is not accessible. + use std::os::unix::fs::PermissionsExt; + let p = project() + .file("src/lib.rs", "") + .file("build.rs", "fn main() {}") + .file("secrets/stuff", "") + .build(); + let path = p.root().join("secrets"); + fs::set_permissions(&path, fs::Permissions::from_mode(0)).unwrap(); + // "Caused by" is a string from libc such as the following: + // Permission denied (os error 13) + p.cargo("build") + .with_stderr( + "\ +[ERROR] cannot read \"[..]/foo/secrets\" + +Caused by: + [..] +", + ) + .with_status(101) + .run(); + fs::set_permissions(&path, fs::Permissions::from_mode(0o755)).unwrap(); +}