From: Alex Crichton Date: Sun, 6 Nov 2016 17:06:55 +0000 (-0800) Subject: Open crate files readonly first X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~22^2~13^2~9^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=27e439c588dfa6d80f03f5d792f76ec7e1621df7;p=cargo.git Open crate files readonly first This allows Cargo to work with read-only `CARGO_HOME` directories where the cache was prepared ahead of time. Closes #3256 --- diff --git a/src/cargo/sources/registry/remote.rs b/src/cargo/sources/registry/remote.rs index d470618b5..fd301b0b6 100644 --- a/src/cargo/sources/registry/remote.rs +++ b/src/cargo/sources/registry/remote.rs @@ -116,6 +116,19 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> { -> CargoResult { let filename = format!("{}-{}.crate", pkg.name(), pkg.version()); let path = Path::new(&filename); + + // Attempt to open an read-only copy first to avoid an exclusive write + // lock and also work with read-only filesystems. Note that we check the + // length of the file like below to handle interrupted downloads. + // + // If this fails then we fall through to the exclusive path where we may + // have to redownload the file. + if let Ok(dst) = self.cache_path.open_ro(path, self.config, &filename) { + let meta = try!(dst.file().metadata()); + if meta.len() > 0 { + return Ok(dst) + } + } let mut dst = try!(self.cache_path.open_rw(path, self.config, &filename)); let meta = try!(dst.file().metadata()); if meta.len() > 0 {