1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 03:57:44 +00:00

cp: fix order of checks in copy_helper

This commit is contained in:
Michael Debertol 2021-06-19 17:45:45 +02:00
parent 5ba69d4a35
commit 6400cded54

View file

@ -1218,28 +1218,38 @@ fn copy_file(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> {
/// Copy the file from `source` to `dest` either using the normal `fs::copy` or a /// Copy the file from `source` to `dest` either using the normal `fs::copy` or a
/// copy-on-write scheme if --reflink is specified and the filesystem supports it. /// copy-on-write scheme if --reflink is specified and the filesystem supports it.
fn copy_helper(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> { fn copy_helper(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> {
if options.reflink_mode != ReflinkMode::Never { if options.parents {
#[cfg(not(any(target_os = "linux", target_os = "macos")))] let parent = dest.parent().unwrap_or(dest);
return Err("--reflink is only supported on linux and macOS" fs::create_dir_all(parent)?;
.to_string() }
.into()); let is_symlink = fs::symlink_metadata(&source)?.file_type().is_symlink();
if source.to_string_lossy() == "/dev/null" {
#[cfg(target_os = "macos")]
copy_on_write_macos(source, dest, options.reflink_mode)?;
#[cfg(target_os = "linux")]
copy_on_write_linux(source, dest, options.reflink_mode)?;
} else if !options.dereference && fs::symlink_metadata(&source)?.file_type().is_symlink() {
copy_link(source, dest)?;
} else if source.to_string_lossy() == "/dev/null" {
/* workaround a limitation of fs::copy /* workaround a limitation of fs::copy
* https://github.com/rust-lang/rust/issues/79390 * https://github.com/rust-lang/rust/issues/79390
*/ */
File::create(dest)?; File::create(dest)?;
} else { } else if !options.dereference && is_symlink {
if options.parents { copy_link(source, dest)?;
let parent = dest.parent().unwrap_or(dest); } else if options.reflink_mode != ReflinkMode::Never {
fs::create_dir_all(parent)?; #[cfg(not(any(target_os = "linux", target_os = "macos")))]
return Err("--reflink is only supported on linux and macOS"
.to_string()
.into());
if is_symlink {
assert!(options.dereference);
let real_path = std::fs::read_link(source)?;
#[cfg(target_os = "macos")]
copy_on_write_macos(&real_path, dest, options.reflink_mode)?;
#[cfg(target_os = "linux")]
copy_on_write_linux(&real_path, dest, options.reflink_mode)?;
} else {
#[cfg(target_os = "macos")]
copy_on_write_macos(source, dest, options.reflink_mode)?;
#[cfg(target_os = "linux")]
copy_on_write_linux(source, dest, options.reflink_mode)?;
} }
} else {
fs::copy(source, dest).context(&*context_for(source, dest))?; fs::copy(source, dest).context(&*context_for(source, dest))?;
} }