mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-30 00:31:14 +00:00
FileOperation: Implement 'Delete' operation
This commit is contained in:
parent
e99200cc23
commit
967314023c
Notes:
sideshowbarker
2024-07-18 08:34:16 +09:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/SerenityOS/serenity/commit/967314023c0 Pull-request: https://github.com/SerenityOS/serenity/pull/8117 Reviewed-by: https://github.com/MaxWipfli ✅
|
@ -20,6 +20,7 @@ struct WorkItem {
|
|||
DeleteDirectory,
|
||||
CopyFile,
|
||||
MoveFile,
|
||||
DeleteFile,
|
||||
};
|
||||
Type type;
|
||||
String source;
|
||||
|
@ -29,6 +30,7 @@ struct WorkItem {
|
|||
|
||||
static int perform_copy(Vector<String> const& sources, String const& destination);
|
||||
static int perform_move(Vector<String> const& sources, String const& destination);
|
||||
static int perform_delete(Vector<String> const& sources);
|
||||
static int execute_work_items(Vector<WorkItem> const& items);
|
||||
static void report_error(String message);
|
||||
static void report_warning(String message);
|
||||
|
@ -39,10 +41,13 @@ int main(int argc, char** argv)
|
|||
Vector<String> paths;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_positional_argument(operation, "Operation: either 'Copy' or 'Move'", "operation", Core::ArgsParser::Required::Yes);
|
||||
args_parser.add_positional_argument(operation, "Operation: either 'Copy', 'Move' or 'Delete'", "operation", Core::ArgsParser::Required::Yes);
|
||||
args_parser.add_positional_argument(paths, "Source paths, followed by a destination if applicable", "paths", Core::ArgsParser::Required::Yes);
|
||||
args_parser.parse(argc, argv);
|
||||
|
||||
if (operation == "Delete")
|
||||
return perform_delete(paths);
|
||||
|
||||
String destination = paths.take_last();
|
||||
if (paths.is_empty()) {
|
||||
report_warning("At least one source and destination are required");
|
||||
|
@ -183,6 +188,56 @@ int perform_move(Vector<String> const& sources, String const& destination)
|
|||
return execute_work_items(items);
|
||||
}
|
||||
|
||||
static bool collect_delete_work_items(String const& source, Vector<WorkItem>& items)
|
||||
{
|
||||
struct stat st = {};
|
||||
if (stat(source.characters(), &st) < 0) {
|
||||
auto original_errno = errno;
|
||||
report_error(String::formatted("stat: {}", strerror(original_errno)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
// It's a file.
|
||||
items.append(WorkItem {
|
||||
.type = WorkItem::Type::DeleteFile,
|
||||
.source = source,
|
||||
.destination = {},
|
||||
.size = st.st_size,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// It's a directory.
|
||||
Core::DirIterator dt(source, Core::DirIterator::SkipParentAndBaseDir);
|
||||
while (dt.has_next()) {
|
||||
auto name = dt.next_path();
|
||||
if (!collect_delete_work_items(String::formatted("{}/{}", source, name), items))
|
||||
return false;
|
||||
}
|
||||
|
||||
items.append(WorkItem {
|
||||
.type = WorkItem::Type::DeleteDirectory,
|
||||
.source = source,
|
||||
.destination = {},
|
||||
.size = 0,
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int perform_delete(Vector<String> const& sources)
|
||||
{
|
||||
Vector<WorkItem> items;
|
||||
|
||||
for (auto& source : sources) {
|
||||
if (!collect_delete_work_items(source, items))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return execute_work_items(items);
|
||||
}
|
||||
|
||||
int execute_work_items(Vector<WorkItem> const& items)
|
||||
{
|
||||
off_t total_work_bytes = 0;
|
||||
|
@ -288,6 +343,20 @@ int execute_work_items(Vector<WorkItem> const& items)
|
|||
break;
|
||||
}
|
||||
|
||||
case WorkItem::Type::DeleteFile: {
|
||||
if (unlink(item.source.characters()) < 0) {
|
||||
auto original_errno = errno;
|
||||
report_error(String::formatted("unlink: {}", strerror(original_errno)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
item_done += item.size;
|
||||
executed_work_bytes += item.size;
|
||||
print_progress();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue