This commit is contained in:
Yuankun Zhang 2025-12-22 21:23:03 +09:00 committed by GitHub
commit 5d81427ecb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 72 additions and 9 deletions

View file

@ -1094,7 +1094,13 @@ fn copy_dir_contents_recursive(
}
#[cfg(not(unix))]
{
fs::copy(&from_path, &to_path)?;
if from_path.is_symlink() {
// Copy a symlink file (no-follow).
rename_symlink_fallback(&from_path, &to_path)?;
} else {
// Copy a regular file.
fs::copy(&from_path, &to_path)?;
}
}
// Print verbose message for file
@ -1137,14 +1143,19 @@ fn copy_file_with_hardlinks_helper(
return Ok(());
}
// Regular file copy
#[cfg(all(unix, not(any(target_os = "macos", target_os = "redox"))))]
{
fs::copy(from, to).and_then(|_| fsxattr::copy_xattrs(&from, &to))?;
}
#[cfg(any(target_os = "macos", target_os = "redox"))]
{
fs::copy(from, to)?;
if from.is_symlink() {
// Copy a symlink file (no-follow).
rename_symlink_fallback(from, to)?;
} else {
// Copy a regular file.
#[cfg(all(unix, not(any(target_os = "macos", target_os = "redox"))))]
{
fs::copy(from, to).and_then(|_| fsxattr::copy_xattrs(&from, &to))?;
}
#[cfg(any(target_os = "macos", target_os = "redox"))]
{
fs::copy(from, to)?;
}
}
Ok(())

View file

@ -621,6 +621,58 @@ fn test_mv_symlink_into_target() {
ucmd.arg("dir-link").arg("dir").succeeds();
}
#[cfg(all(unix, not(target_os = "android")))]
#[ignore = "requires sudo"]
#[test]
fn test_mv_broken_symlink_to_another_fs() {
let scene = TestScenario::new(util_name!());
scene.fixtures.mkdir("foo");
let output = scene
.cmd("sudo")
.env("PATH", env!("PATH"))
.args(&["-E", "--non-interactive", "ls"])
.run();
println!("test output: {output:?}");
let mount = scene
.cmd("sudo")
.env("PATH", env!("PATH"))
.args(&[
"-E",
"--non-interactive",
"mount",
"none",
"-t",
"tmpfs",
"foo",
])
.run();
if !mount.succeeded() {
print!("Test skipped; requires root user");
return;
}
scene.fixtures.mkdir("bar");
scene.fixtures.symlink_file("nonexistent", "bar/baz");
scene
.ucmd()
.arg("bar")
.arg("foo")
.succeeds()
.no_stderr()
.no_stdout();
scene
.cmd("sudo")
.env("PATH", env!("PATH"))
.args(&["-E", "--non-interactive", "umount", "foo"])
.succeeds();
}
#[test]
#[cfg(all(unix, not(target_os = "android")))]
fn test_mv_hardlink_to_symlink() {