#include #include #include #include Result remove_wrapper(const os::Path& path, bool verbose) { TRY(os::FileSystem::remove(path)); if (verbose) os::println("removed '%s'", path.name().chars()); return {}; } Result remove_tree(const os::Path& path, bool verbose) { auto rc = remove_wrapper(path, verbose); if (!rc.has_error()) return {}; if (rc.error() != ENOTEMPTY) return rc.release_error(); auto dir = TRY(os::Directory::open(path)); Vector entries = TRY(dir->list_names(os::Directory::Filter::ParentAndBase)); for (const auto& entry : entries) { TRY(remove_tree({ dir->fd(), entry.view() }, verbose)); } return remove_wrapper(path, verbose); } Result luna_main(int argc, char** argv) { StringView path; bool recursive; bool verbose; os::ArgumentParser parser; parser.add_description("Remove a path from the file system."_sv); parser.add_system_program_info("rm"_sv); parser.add_positional_argument(path, "path"_sv, true); parser.add_switch_argument(recursive, 'r', "recursive"_sv, "remove a directory recursively (by default, rm removes only empty directories)"_sv); parser.add_switch_argument(verbose, 'v', "verbose"_sv, "log every removed file and directory"_sv); parser.parse(argc, argv); if (!recursive) TRY(remove_wrapper(path, verbose)); else TRY(remove_tree(path, verbose)); return 0; }