mirror of
https://github.com/uutils/coreutils
synced 2024-10-15 04:14:44 +00:00
Merge pull request #5851 from cre4ture/fix/install_invalid_link_at_destination
Fix install: invalid link at destination
This commit is contained in:
commit
ffb70592ec
|
@ -748,6 +748,18 @@ fn perform_backup(to: &Path, b: &Behavior) -> UResult<Option<PathBuf>> {
|
|||
/// Returns an empty Result or an error in case of failure.
|
||||
///
|
||||
fn copy_file(from: &Path, to: &Path) -> UResult<()> {
|
||||
// fs::copy fails if destination is a invalid symlink.
|
||||
// so lets just remove all existing files at destination before copy.
|
||||
if let Err(e) = fs::remove_file(to) {
|
||||
if e.kind() != std::io::ErrorKind::NotFound {
|
||||
show_error!(
|
||||
"Failed to remove existing file {}. Error: {:?}",
|
||||
to.display(),
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if from.as_os_str() == "/dev/null" {
|
||||
/* workaround a limitation of fs::copy
|
||||
* https://github.com/rust-lang/rust/issues/79390
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::common::util::{is_ci, run_ucmd_as_root, TestScenario};
|
|||
use filetime::FileTime;
|
||||
use std::fs;
|
||||
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
||||
#[cfg(not(any(windows, target_os = "freebsd")))]
|
||||
#[cfg(not(windows))]
|
||||
use std::process::Command;
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
use std::thread::sleep;
|
||||
|
@ -610,13 +610,17 @@ fn test_install_copy_then_compare_file_with_extra_mode() {
|
|||
}
|
||||
|
||||
const STRIP_TARGET_FILE: &str = "helloworld_installed";
|
||||
#[cfg(not(any(windows, target_os = "freebsd")))]
|
||||
#[cfg(all(not(windows), not(target_os = "freebsd")))]
|
||||
const SYMBOL_DUMP_PROGRAM: &str = "objdump";
|
||||
#[cfg(not(any(windows, target_os = "freebsd")))]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
const SYMBOL_DUMP_PROGRAM: &str = "llvm-objdump";
|
||||
#[cfg(not(windows))]
|
||||
const STRIP_SOURCE_FILE_SYMBOL: &str = "main";
|
||||
|
||||
fn strip_source_file() -> &'static str {
|
||||
if cfg!(target_os = "macos") {
|
||||
if cfg!(target_os = "freebsd") {
|
||||
"helloworld_freebsd"
|
||||
} else if cfg!(target_os = "macos") {
|
||||
"helloworld_macos"
|
||||
} else if cfg!(target_arch = "arm") || cfg!(target_arch = "aarch64") {
|
||||
"helloworld_android"
|
||||
|
@ -626,8 +630,7 @@ fn strip_source_file() -> &'static str {
|
|||
}
|
||||
|
||||
#[test]
|
||||
// FixME: Freebsd fails on 'No such file or directory'
|
||||
#[cfg(not(any(windows, target_os = "freebsd")))]
|
||||
#[cfg(not(windows))]
|
||||
fn test_install_and_strip() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
@ -650,8 +653,7 @@ fn test_install_and_strip() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
// FixME: Freebsd fails on 'No such file or directory'
|
||||
#[cfg(not(any(windows, target_os = "freebsd")))]
|
||||
#[cfg(not(windows))]
|
||||
fn test_install_and_strip_with_program() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
@ -677,8 +679,6 @@ fn test_install_and_strip_with_program() {
|
|||
|
||||
#[cfg(all(unix, feature = "chmod"))]
|
||||
#[test]
|
||||
// FixME: Freebsd fails on 'No such file or directory'
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
fn test_install_and_strip_with_program_hyphen() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
|
@ -715,6 +715,64 @@ fn test_install_and_strip_with_program_hyphen() {
|
|||
.stdout_is("./-dest\n");
|
||||
}
|
||||
|
||||
#[cfg(all(unix, feature = "chmod"))]
|
||||
#[test]
|
||||
fn test_install_on_invalid_link_at_destination() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let at = &scene.fixtures;
|
||||
at.mkdir("src");
|
||||
at.mkdir("dest");
|
||||
let src_dir = at.plus("src");
|
||||
let dst_dir = at.plus("dest");
|
||||
|
||||
at.touch("test.sh");
|
||||
at.symlink_file(
|
||||
"/opt/FakeDestination",
|
||||
&dst_dir.join("test.sh").to_string_lossy(),
|
||||
);
|
||||
scene.ccmd("chmod").arg("+x").arg("test.sh").succeeds();
|
||||
at.symlink_file("test.sh", &src_dir.join("test.sh").to_string_lossy());
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.current_dir(&src_dir)
|
||||
.arg(src_dir.join("test.sh"))
|
||||
.arg(dst_dir.join("test.sh"))
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.no_stdout();
|
||||
}
|
||||
|
||||
#[cfg(all(unix, feature = "chmod"))]
|
||||
#[test]
|
||||
fn test_install_on_invalid_link_at_destination_and_dev_null_at_source() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let at = &scene.fixtures;
|
||||
at.mkdir("src");
|
||||
at.mkdir("dest");
|
||||
let src_dir = at.plus("src");
|
||||
let dst_dir = at.plus("dest");
|
||||
|
||||
at.touch("test.sh");
|
||||
at.symlink_file(
|
||||
"/opt/FakeDestination",
|
||||
&dst_dir.join("test.sh").to_string_lossy(),
|
||||
);
|
||||
scene.ccmd("chmod").arg("+x").arg("test.sh").succeeds();
|
||||
at.symlink_file("test.sh", &src_dir.join("test.sh").to_string_lossy());
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.current_dir(&src_dir)
|
||||
.arg("/dev/null")
|
||||
.arg(dst_dir.join("test.sh"))
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.no_stdout();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_install_and_strip_with_invalid_program() {
|
||||
|
|
689
tests/fixtures/install/helloworld_freebsd
vendored
Executable file
689
tests/fixtures/install/helloworld_freebsd
vendored
Executable file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue