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:
parent
588ba72fe7
commit
4bfe060336
Notes:
sideshowbarker
2024-07-18 01:42:11 +09:00
Author: https://github.com/peryaudo Commit: https://github.com/SerenityOS/serenity/commit/4bfe060336b Pull-request: https://github.com/SerenityOS/serenity/pull/10060
1 changed files with 29 additions and 20 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue