diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 9ef767d05..650ec1348 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -987,8 +987,6 @@ impl Options { let not_implemented_opts = vec![ #[cfg(not(any(windows, unix)))] options::ONE_FILE_SYSTEM, - #[cfg(windows)] - options::FORCE, ]; for not_implemented_opt in not_implemented_opts { @@ -1991,6 +1989,16 @@ fn delete_dest_if_needed_and_allowed( } fn delete_path(path: &Path, options: &Options) -> CopyResult<()> { + // Windows requires clearing readonly attribute before deletion when using --force + #[cfg(windows)] + if options.force() { + if let Ok(mut perms) = fs::metadata(path).map(|m| m.permissions()) { + #[allow(clippy::permissions_set_readonly_false)] + perms.set_readonly(false); + let _ = fs::set_permissions(path, perms); + } + } + match fs::remove_file(path) { Ok(()) => { if options.verbose { diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 7562eab38..e8f6765cb 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -11,7 +11,6 @@ use uucore::selinux::get_getfattr_output; use uutests::util::TestScenario; use uutests::{at_and_ucmd, new_ucmd, path_concat, util_name}; -#[cfg(not(windows))] use std::fs::set_permissions; use std::io::Write; @@ -972,7 +971,6 @@ fn test_cp_arg_no_clobber_twice() { } #[test] -#[cfg(not(windows))] fn test_cp_arg_force() { let (at, mut ucmd) = at_and_ucmd!();