From 4d48626eeb5f68f051ea67fe56e3f341e870323d Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Tue, 29 Jul 2025 16:28:14 +0800 Subject: [PATCH] cp: File logic error when preserving attributes for fifos There was a mismatch between the test, the comment, and the code. The intention was to _preserve_ attributes if the source of a fifo/pipe still exists. Perhaps the clearest way is to modify the test (as that avoids code duplication). Also add a basic test for that, if permissions are preserved, the rest should also be preserved correctly. Fixes the first part of #8402. --- src/uu/cp/src/cp.rs | 2 +- tests/by-util/test_cp.rs | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 2cdd79255..a4d0cff4d 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -2446,7 +2446,7 @@ fn copy_file( copy_attributes(&src, dest, &options.attributes)?; } } - } else if source_is_stream && source.exists() { + } else if source_is_stream && !source.exists() { // Some stream files may not exist after we have copied it, // like anonymous pipes. Thus, we can't really copy its // attributes. However, this is already handled in the stream diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 8575d1959..730c7a87e 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -4,7 +4,7 @@ // file that was distributed with this source code. // spell-checker:ignore (flags) reflink (fs) tmpfs (linux) rlimit Rlim NOFILE clob btrfs neve ROOTDIR USERDIR outfile uufs xattrs -// spell-checker:ignore bdfl hlsl IRWXO IRWXG nconfined matchpathcon libselinux-devel +// spell-checker:ignore bdfl hlsl IRWXO IRWXG nconfined matchpathcon libselinux-devel prwx use uucore::display::Quotable; use uutests::util::TestScenario; use uutests::{at_and_ucmd, new_ucmd, path_concat, util_name}; @@ -3087,13 +3087,20 @@ fn test_cp_link_backup() { fn test_cp_fifo() { let (at, mut ucmd) = at_and_ucmd!(); at.mkfifo("fifo"); - ucmd.arg("-r") + // Also test that permissions are preserved + at.set_mode("fifo", 0o731); + ucmd.arg("--preserve=mode") + .arg("-r") .arg("fifo") .arg("fifo2") .succeeds() .no_stderr() .no_stdout(); assert!(at.is_fifo("fifo2")); + + let metadata = std::fs::metadata(at.subdir.join("fifo2")).unwrap(); + let permission = uucore::fs::display_permissions(&metadata, true); + assert_eq!(permission, "prwx-wx--x".to_string()); } #[test]