diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 513fb8380a7..692b47591c9 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -514,6 +514,7 @@ pub fn uu_app() -> Command { PRESERVABLE_ATTRIBUTES, )) .num_args(0..) + .require_equals(true) .value_name("ATTR_LIST") .overrides_with_all([ options::ARCHIVE, diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 1feeb0edee7..3036008c9dd 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1199,6 +1199,33 @@ fn test_cp_preserve_no_args() { } } +#[test] +fn test_cp_preserve_no_args_before_opts() { + let (at, mut ucmd) = at_and_ucmd!(); + let src_file = "a"; + let dst_file = "b"; + + // Prepare the source file + at.touch(src_file); + #[cfg(unix)] + at.set_mode(src_file, 0o0500); + + // Copy + ucmd.arg("--preserve") + .arg(src_file) + .arg(dst_file) + .succeeds(); + + #[cfg(all(unix, not(target_os = "freebsd")))] + { + // Assert that the mode, ownership, and timestamps are preserved + // NOTICE: the ownership is not modified on the src file, because that requires root permissions + let metadata_src = at.metadata(src_file); + let metadata_dst = at.metadata(dst_file); + assert_metadata_eq!(metadata_src, metadata_dst); + } +} + #[test] fn test_cp_preserve_all() { let (at, mut ucmd) = at_and_ucmd!();