-
Notifications
You must be signed in to change notification settings - Fork 1k
fix: copy_dir and copy_file to preserve symlinks instead of following them.
#4671
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
7ce58b5 to
5460b37
Compare
|
Thanks for making this patch! Reasonable support for external packagers are still expected, and whether a manual setup is required is largely based on the packagers' opinion: https://rust-lang.github.io/rustup/installation/other.html#using-a-package-manager I have the feeling that we need to somehow support both cases based on whether that's copying the original binary or not... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a specific use case where rustup is not working as you'd expect, which this PR allows to fix?
If you can find such a case, I agree with using this new implementation except for this:
Line 845 in 3382f6f
| utils::copy_file(&this_exe_path, &rustup_path)?; |
#1521 is probably too widespread as a fix, and it makes perfect sense to use different copy implementations during self installation and during toolchain installation.
Suggest refining the test cases accordingly if going this way.
src/utils/raw.rs
Outdated
| let dest = dest.join(entry.file_name()); | ||
| if kind.is_dir() { | ||
| copy_dir(&src, &dest)?; | ||
| let src_path = entry.path(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: src and dest bindings in the loop body are preventing the input params from being used. Thus, I don't see a very convincing reason to rename them here.
I don't, and I only encountered this looking at the code. It's my understanding that copying symlinks breaks their identity and can cause software to load libraries twice (like the crash that was fixed ad-hoc above). It's also just correct behavior afaik;
I would agree with this and will adjust, so long as you think it's a reasonable patch. I figured at the least I could flag this to note the variance in functionality for copy's. |
|
@cachebag Thanks for your clarification. I think although it has no direct influence now, judging by what I'd expect from the function API then indeed, the old behavior feels more correct to me, and leaving it uncorrected might lead to misuse in the long run. Looking back there is still a slight possibility that we could be missing other cases apart from self installation, so I'd say let's go on polishing this patch by carefully analyzing the call sites. Please don't hesitate to ask me if you don't feel certain about anything! |
That makes sense to me, thank you! |
5460b37 to
09c35e1
Compare
Previously, copy_dir would follow symlinks and copy the target contents. Now it preserves symlinks by reading the link target and creating a new symlink with the same target. Adds regression test copy_dir_preserves_symlinks.
Adds copy_file_preserving_symlink that preserves symlink targets instead of creating symlinks to the source path. Uses it in Transaction::copy_file, Transaction::modify_file, and copy_and_delete. Leaves utils::copy_file unchanged for self-installation (per rust-lang#1521). Adds regression test copy_file_preserves_symlinks.
09c35e1 to
f4c5445
Compare
This PR employs symlink preservation in
copy_fileand adds it tocopy_dir.PR #1504 added symlink preservation to fix crashes in lldb-preview, which contains internal symlinks (liblldb was loading twice due to broken symlinks). Then, PR #1521 later changed
copy_fileto create symlinks pointing to the source path (for Homebrew integration), which may have regressed #1504.This PR restores #1504's behavior: read the symlink target and preserve it. What I'm curious about is what the intended behavior for #1521 was because shouldn't users be able to run
rustup-init --no-self-update? Is that not the recommended way to managerustupvia external package managers?If this PR steers out of scope of the goals of
rustupI'm happy to close it but I feel like the former behavior is preferable for most use cases.