Skip to content

Commit 79d357c

Browse files
committed
Try symlinking proxies first
Fallback to hardlinking if that doesn't work
1 parent ccc668c commit 79d357c

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

src/cli/self_update.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -731,8 +731,8 @@ pub(crate) fn install_proxies(process: &Process) -> Result<()> {
731731
let mut tool_handles = Vec::new();
732732
let mut link_afterwards = Vec::new();
733733

734-
// Try to hardlink all the Rust exes to the rustup exe. Some systems,
735-
// like Android, does not support hardlinks, so we fallback to symlinks.
734+
// Try to symlink all the Rust exes to the rustup exe. Some systems,
735+
// like Windows, do not always support symlinks, so we fallback to hard links.
736736
//
737737
// Note that this function may not be running in the context of a fresh
738738
// self update but rather as part of a normal update to fill in missing
@@ -751,7 +751,7 @@ pub(crate) fn install_proxies(process: &Process) -> Result<()> {
751751
// actually delete files (they'll say they're deleted but they won't
752752
// actually be on Windows). As a result we manually drop all the
753753
// `tool_handles` later on. This'll allow us, afterwards, to actually
754-
// overwrite all the previous hard links with new ones.
754+
// overwrite all the previous soft or hard links with new ones.
755755
for tool in TOOLS {
756756
let tool_path = bin_path.join(format!("{tool}{EXE_SUFFIX}"));
757757
if let Ok(handle) = Handle::from_path(&tool_path) {
@@ -766,7 +766,7 @@ pub(crate) fn install_proxies(process: &Process) -> Result<()> {
766766
for tool in DUP_TOOLS {
767767
let tool_path = bin_path.join(format!("{tool}{EXE_SUFFIX}"));
768768
if let Ok(handle) = Handle::from_path(&tool_path) {
769-
// Like above, don't clobber anything that's already hardlinked to
769+
// Like above, don't clobber anything that's already linked to
770770
// avoid extraneous errors from being returned.
771771
if rustup == handle {
772772
continue;
@@ -790,12 +790,12 @@ pub(crate) fn install_proxies(process: &Process) -> Result<()> {
790790
continue;
791791
}
792792
}
793-
utils::hard_or_symlink_file(&rustup_path, &tool_path)?;
793+
utils::symlink_or_hardlink_file(&rustup_path, &tool_path)?;
794794
}
795795

796796
drop(tool_handles);
797797
for path in link_afterwards {
798-
utils::hard_or_symlink_file(&rustup_path, &path)?;
798+
utils::symlink_or_hardlink_file(&rustup_path, &path)?;
799799
}
800800

801801
Ok(())

src/utils/utils.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -312,19 +312,23 @@ where
312312
})
313313
}
314314

315-
pub(crate) fn hard_or_symlink_file(src: &Path, dest: &Path) -> Result<()> {
315+
pub(crate) fn symlink_or_hardlink_file(src: &Path, dest: &Path) -> Result<()> {
316+
// The error is only used by macos
317+
let Err(_err) = symlink_file(src, dest) else {
318+
return Ok(());
319+
};
320+
316321
// Some mac filesystems can do hardlinks to symlinks, some can't.
317322
// See rust-lang/rustup#3136 for why it's better never to use them.
318323
#[cfg(target_os = "macos")]
319-
let force_symlink = fs::symlink_metadata(src)
324+
if fs::symlink_metadata(src)
320325
.map(|m| m.file_type().is_symlink())
321-
.unwrap_or(false);
322-
#[cfg(not(target_os = "macos"))]
323-
let force_symlink = false;
324-
if force_symlink || hardlink_file(src, dest).is_err() {
325-
symlink_file(src, dest)?;
326+
.unwrap_or(false)
327+
{
328+
return Err(_err);
326329
}
327-
Ok(())
330+
331+
hardlink_file(src, dest)
328332
}
329333

330334
pub fn hardlink_file(src: &Path, dest: &Path) -> Result<()> {

0 commit comments

Comments
 (0)