mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
cp: require preserve only certain attributes (#4099)
* cp: require preserve only certain attributes # Conflicts: # src/uu/cp/src/copydir.rs # src/uu/cp/src/cp.rs * tests/cp: preserve all and preserve xattr tests with todos * tests/cp: rename preserve tests * tests/cp: add android fail test for preserve=xattr On Android, this cp with explicit preserve of xattr must fail, because of the limitations of the filesystem setup used on Android. * cp: verify some metadata in cp preserve tests # Conflicts: # tests/by-util/test_cp.rs * cp: run test_cp_preserve_all in all OS's but only check metadata on linux * test/cp: don't expect the mode to change in explicit cp preserve * cp: attributes struct instead of enum for unified required tracking * cp: refactor preserver and handle_preserve # Conflicts: # src/uu/cp/src/cp.rs * cp: update preserve attr to max * test/cp: fix the preserve xattr test Access timestamps appear to be modified only in this test. Running the command directly does not alter the access timestamp. * cp/test: preserve all and context case * cp: fix preserve args value source * test/cp: don't check mtime on freebsd * test/cp: don't check mtime on macos * test/cp: fix freebsd deps * test/cp: support freebsd tests * cp: simplify try_set_from_string * cp: parse context attr in preserve in any case to show warning later * cp: print warnings for attribute errors if not required * cp: show SELinux warning only once * cp: show SELinux warning without error * Revert "cp: show SELinux warning without error" This reverts commit d130cf0d8c8e28ac2c903413992613241decf879. * cp: add documentation for preserve components * cp: simplify try_set_from_string * cp: EN_US "behavior" spelling for cspell
This commit is contained in:
parent
8c137f5d7c
commit
50c1833c11
3 changed files with 359 additions and 178 deletions
|
@ -22,9 +22,7 @@ use filetime::FileTime;
|
|||
use rlimit::Resource;
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
use std::fs as std_fs;
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
use std::thread::sleep;
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
use std::time::Duration;
|
||||
|
||||
static TEST_EXISTING_FILE: &str = "existing_file.txt";
|
||||
|
@ -907,6 +905,91 @@ fn test_cp_preserve_no_args() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_preserve_all() {
|
||||
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);
|
||||
|
||||
// TODO: create a destination that does not allow copying of xattr and context
|
||||
// Copy
|
||||
ucmd.arg(src_file)
|
||||
.arg(dst_file)
|
||||
.arg("--preserve=all")
|
||||
.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]
|
||||
#[cfg(all(unix, not(target_os = "android")))]
|
||||
fn test_cp_preserve_xattr() {
|
||||
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);
|
||||
|
||||
// Sleep so that the time stats are different
|
||||
sleep(Duration::from_secs(1));
|
||||
|
||||
// TODO: create a destination that does not allow copying of xattr and context
|
||||
// Copy
|
||||
ucmd.arg(src_file)
|
||||
.arg(dst_file)
|
||||
.arg("--preserve=xattr")
|
||||
.succeeds();
|
||||
|
||||
// FIXME: macos copy keeps the original mtime
|
||||
#[cfg(not(any(target_os = "freebsd", target_os = "macos")))]
|
||||
{
|
||||
// Assert that the mode, ownership, and timestamps are *NOT* 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_ne!(metadata_src.mtime(), metadata_dst.mtime());
|
||||
// TODO: verify access time as well. It shouldn't change, however, it does change in this test.
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(target_os = "linux", not(feature = "feat_selinux")))]
|
||||
fn test_cp_preserve_all_context_fails_on_non_selinux() {
|
||||
new_ucmd!()
|
||||
.arg(TEST_COPY_FROM_FOLDER_FILE)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.arg("--preserve=all,context")
|
||||
.fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "android"))]
|
||||
fn test_cp_preserve_xattr_fails_on_android() {
|
||||
// Because of the SELinux extended attributes used on Android, trying to copy extended
|
||||
// attributes has to fail in this case, since we specify `--preserve=xattr` and this puts it
|
||||
// into the required attributes
|
||||
new_ucmd!()
|
||||
.arg(TEST_COPY_FROM_FOLDER_FILE)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.arg("--preserve=xattr")
|
||||
.fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
// For now, disable the test on Windows. Symlinks aren't well support on Windows.
|
||||
// It works on Unix for now and it works locally when run from a powershell
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue