summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2018-07-13 10:10:52 -0600
committerTom Tromey <tom@tromey.com>2018-07-13 10:10:52 -0600
commit14c6716ba0c1812c913a888c1e1ed5c7aaa50f70 (patch)
treee52e3338c6bb2803c1e46ce7076a463d8ec3b588
parent74c2f5a41cad0323ddc7bc8658ddef4769abab31 (diff)
downloadrust-installer-14c6716ba0c1812c913a888c1e1ed5c7aaa50f70.tar.gz
Copy symlinks
lldb includes some symlinks in its install tree, and so generator must copy these symlinks as well. I believe only file symlinks are needed.
-rw-r--r--src/util.rs17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/util.rs b/src/util.rs
index d5beed1..a5ae36c 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -18,6 +18,11 @@ use walkdir::WalkDir;
use std::os::unix::fs::OpenOptionsExt;
// FIXME: what about Windows? Are default ACLs executable?
+#[cfg(unix)]
+use std::os::unix::fs::symlink as symlink_file;
+#[cfg(windows)]
+use std::os::windows::fs::symlink_file;
+
use errors::*;
/// Convert a `&Path` to a UTF-8 `&str`
@@ -29,9 +34,15 @@ pub fn path_to_str(path: &Path) -> Result<&str> {
/// Wrap `fs::copy` with a nicer error message
pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> Result<u64> {
- fs::copy(&from, &to)
- .chain_err(|| format!("failed to copy '{}' to '{}'",
- from.as_ref().display(), to.as_ref().display()))
+ if fs::symlink_metadata(&from)?.file_type().is_symlink() {
+ let link = fs::read_link(&from)?;
+ symlink_file(link, &to)?;
+ Ok(0)
+ } else {
+ fs::copy(&from, &to)
+ .chain_err(|| format!("failed to copy '{}' to '{}'",
+ from.as_ref().display(), to.as_ref().display()))
+ }
}
/// Wrap `fs::create_dir` with a nicer error message