diff options
author | Tom Tromey <tom@tromey.com> | 2018-07-13 10:10:52 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2018-07-13 10:10:52 -0600 |
commit | 14c6716ba0c1812c913a888c1e1ed5c7aaa50f70 (patch) | |
tree | e52e3338c6bb2803c1e46ce7076a463d8ec3b588 | |
parent | 74c2f5a41cad0323ddc7bc8658ddef4769abab31 (diff) | |
download | rust-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.rs | 17 |
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 |