1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Merge pull request #2331 from miDeb/cp/linux-cow-errors

cp: show errors in cow on linux
This commit is contained in:
Sylvestre Ledru 2021-06-02 10:19:03 +02:00 committed by GitHub
commit f5b01a61cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 4 deletions

View file

@ -1261,13 +1261,15 @@ fn copy_helper(source: &Path, dest: &Path, options: &Options) -> CopyResult<()>
fn copy_on_write_linux(source: &Path, dest: &Path, mode: ReflinkMode) -> CopyResult<()> { fn copy_on_write_linux(source: &Path, dest: &Path, mode: ReflinkMode) -> CopyResult<()> {
debug_assert!(mode != ReflinkMode::Never); debug_assert!(mode != ReflinkMode::Never);
let src_file = File::open(source).unwrap().into_raw_fd(); let src_file = File::open(source)
.context(&*context_for(source, dest))?
.into_raw_fd();
let dst_file = OpenOptions::new() let dst_file = OpenOptions::new()
.write(true) .write(true)
.truncate(false) .truncate(false)
.create(true) .create(true)
.open(dest) .open(dest)
.unwrap() .context(&*context_for(source, dest))?
.into_raw_fd(); .into_raw_fd();
match mode { match mode {
ReflinkMode::Always => unsafe { ReflinkMode::Always => unsafe {

View file

@ -7,6 +7,8 @@ use std::fs::set_permissions;
#[cfg(not(windows))] #[cfg(not(windows))]
use std::os::unix::fs; use std::os::unix::fs;
#[cfg(target_os = "linux")]
use std::os::unix::fs::PermissionsExt;
#[cfg(windows)] #[cfg(windows)]
use std::os::windows::fs::symlink_file; use std::os::windows::fs::symlink_file;
@ -1257,3 +1259,20 @@ fn test_cp_reflink_bad() {
.fails() .fails()
.stderr_contains("invalid argument"); .stderr_contains("invalid argument");
} }
#[test]
#[cfg(target_os = "linux")]
fn test_cp_reflink_insufficient_permission() {
let (at, mut ucmd) = at_and_ucmd!();
at.make_file("unreadable")
.set_permissions(PermissionsExt::from_mode(0o000))
.unwrap();
ucmd.arg("-r")
.arg("--reflink=auto")
.arg("unreadable")
.arg(TEST_EXISTING_FILE)
.fails()
.stderr_only("cp: 'unreadable' -> 'existing_file.txt': Permission denied (os error 13)");
}

View file

@ -50,14 +50,14 @@ macro_rules! new_ucmd {
/// Convenience macro for acquiring a [`UCommand`] builder and a test path. /// Convenience macro for acquiring a [`UCommand`] builder and a test path.
/// ///
/// Returns a tuple containing the following: /// Returns a tuple containing the following:
/// - an [`AsPath`] that points to a unique temporary test directory /// - an [`AtPath`] that points to a unique temporary test directory
/// - a [`UCommand`] builder for invoking the binary to be tested /// - a [`UCommand`] builder for invoking the binary to be tested
/// ///
/// This macro is intended for quick, single-call tests. For more complex tests /// This macro is intended for quick, single-call tests. For more complex tests
/// that require multiple invocations of the tested binary, see [`TestScenario`] /// that require multiple invocations of the tested binary, see [`TestScenario`]
/// ///
/// [`UCommand`]: crate::tests::common::util::UCommand /// [`UCommand`]: crate::tests::common::util::UCommand
/// [`AsPath`]: crate::tests::common::util::AsPath /// [`AtPath`]: crate::tests::common::util::AtPath
/// [`TestScenario]: crate::tests::common::util::TestScenario /// [`TestScenario]: crate::tests::common::util::TestScenario
#[macro_export] #[macro_export]
macro_rules! at_and_ucmd { macro_rules! at_and_ucmd {