FileOperation: Deduplicate file names on move

For file copying, when there is a file with the same name in the
destination directory, the file will be automatically renamed to
"file-2.txt", for example. This change expands that special-case
handling to file moving.
This commit is contained in:
Tetsui Ohkubo 2021-09-15 00:03:24 +09:00 committed by Andreas Kling
parent 588ba72fe7
commit 4bfe060336
Notes: sideshowbarker 2024-07-18 01:42:11 +09:00

View file

@ -321,27 +321,36 @@ int execute_work_items(Vector<WorkItem> const& items)
}
case WorkItem::Type::MoveFile: {
if (rename(item.source.characters(), item.destination.characters()) == 0) {
item_done += item.size;
executed_work_bytes += item.size;
print_progress();
continue;
}
auto original_errno = errno;
if (original_errno != EXDEV) {
report_warning(String::formatted("Failed to move {}: {}", item.source, strerror(original_errno)));
return 1;
}
// EXDEV means we have to copy the file data and then remove the original
if (!copy_file(item.source, item.destination))
return 1;
if (unlink(item.source.characters()) < 0) {
String destination = item.destination;
while (true) {
if (rename(item.source.characters(), destination.characters()) == 0) {
item_done += item.size;
executed_work_bytes += item.size;
print_progress();
break;
}
auto original_errno = errno;
report_error(String::formatted("unlink: {}", strerror(original_errno)));
return 1;
if (original_errno == EEXIST) {
destination = deduplicate_destination_file_name(destination);
continue;
}
if (original_errno != EXDEV) {
report_warning(String::formatted("Failed to move {}: {}", item.source, strerror(original_errno)));
return 1;
}
// EXDEV means we have to copy the file data and then remove the original
if (!copy_file(item.source, item.destination))
return 1;
if (unlink(item.source.characters()) < 0) {
auto original_errno = errno;
report_error(String::formatted("unlink: {}", strerror(original_errno)));
return 1;
}
break;
}
break;