Skip to content

Commit

Permalink
Fix install: invalid link at destination
Browse files Browse the repository at this point in the history
also remove some FixMEs for FreeBsd
  • Loading branch information
cre4ture committed Mar 11, 2024
1 parent b34d410 commit 7cd754e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 10 deletions.
12 changes: 12 additions & 0 deletions src/uu/install/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(

Check warning on line 755 in src/uu/install/src/install.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/install/src/install.rs#L755

Added line #L755 was not covered by tests
"Failed to remove existing file {}. Error: {:?}",
to.display(),

Check warning on line 757 in src/uu/install/src/install.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/install/src/install.rs#L757

Added line #L757 was not covered by tests
e
);
}
}

if from.as_os_str() == "/dev/null" {
/* workaround a limitation of fs::copy
* https:/rust-lang/rust/issues/79390
Expand Down
78 changes: 68 additions & 10 deletions tests/by-util/test_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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"

Check warning on line 622 in tests/by-util/test_install.rs

View check run for this annotation

Codecov / codecov/patch

tests/by-util/test_install.rs#L622

Added line #L622 was not covered by tests
} else if cfg!(target_os = "macos") {
"helloworld_macos"
} else if cfg!(target_arch = "arm") || cfg!(target_arch = "aarch64") {
"helloworld_android"
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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!());

Expand Down Expand Up @@ -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() {
Expand Down
Binary file added tests/fixtures/install/helloworld_freebsd
Binary file not shown.

0 comments on commit 7cd754e

Please sign in to comment.