diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index b872e0c749e..0b6b35ee316 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -770,8 +770,9 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { copy_files_into_dir(sources, &target, b) } else { let source = sources.first().unwrap(); + let source_metadata = metadata_for_source(source)?; - if source.is_dir() { + if source_metadata.is_dir() { return Err(InstallError::OmittingDirectory(source.clone()).into()); } @@ -827,6 +828,11 @@ fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { } } +fn metadata_for_source(path: &Path) -> UResult { + path.metadata() + .map_err_context(|| format!("cannot stat {}", path.quote())) +} + /// Copy some files into a directory. /// /// Prints verbose information and error messages. @@ -842,15 +848,15 @@ fn copy_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> UR return Err(InstallError::TargetDirIsntDir(target_dir.to_path_buf()).into()); } for sourcepath in files { - if let Err(err) = sourcepath - .metadata() - .map_err_context(|| format!("cannot stat {}", sourcepath.quote())) - { - show!(err); - continue; - } + let source_metadata = match metadata_for_source(sourcepath) { + Ok(metadata) => metadata, + Err(err) => { + show!(err); + continue; + } + }; - if sourcepath.is_dir() { + if source_metadata.is_dir() { let err = InstallError::OmittingDirectory(sourcepath.clone()); show!(err); continue; diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index 11dfa7a4ef2..dd51225c840 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -371,6 +371,15 @@ fn test_install_target_file() { assert!(at.file_exists(file2)); } +#[test] +fn test_install_missing_source_reports_cannot_stat_with_path() { + new_ucmd!() + .arg("missing_source") + .arg("target_file") + .fails_with_code(1) + .stderr_contains("cannot stat 'missing_source': No such file or directory"); +} + #[test] fn test_install_target_new_file() { let (at, mut ucmd) = at_and_ucmd!();