From 889e6ab43d5b4f0f3571feaa8029a18470847a05 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Fri, 1 Sep 2023 20:22:20 +0100 Subject: [PATCH] find: Add the `-empty` option This predicate returns true for empty regular files or directories. --- Base/usr/share/man/man1/find.md | 2 ++ Userland/Utilities/find.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Base/usr/share/man/man1/find.md b/Base/usr/share/man/man1/find.md index 721d5b7c60..1689f66988 100644 --- a/Base/usr/share/man/man1/find.md +++ b/Base/usr/share/man/man1/find.md @@ -46,6 +46,8 @@ space rounded up to the nearest whole unit. * `-name pattern`: Checks if the file name matches the given global-style pattern (case sensitive). +* `-empty`: File is either an empty regular file or a directory containing no + files. * `-iname pattern`: Checks if the file name matches the given global-style pattern (case insensitive). * `-readable`: Checks if the file is readable by the current user. diff --git a/Userland/Utilities/find.cpp b/Userland/Utilities/find.cpp index b0683952bd..1d446716c5 100644 --- a/Userland/Utilities/find.cpp +++ b/Userland/Utilities/find.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -274,6 +275,31 @@ private: off_t m_unit_size { 512 }; }; +class EmptyCommand final : public Command { +public: + EmptyCommand() + { + } + +private: + virtual bool evaluate(FileData& file_data) const override + { + struct stat const* stat = file_data.ensure_stat(); + if (!stat) + return false; + + if (S_ISREG(stat->st_mode)) + return stat->st_size == 0; + + if (S_ISDIR(stat->st_mode)) { + auto dir_iterator = Core::DirIterator(file_data.full_path.string(), Core::DirIterator::SkipDots); + return !dir_iterator.has_next(); + } + + return false; + } +}; + class NameCommand : public Command { public: NameCommand(char const* pattern, CaseSensitivity case_sensitivity) @@ -507,6 +533,8 @@ static OwnPtr parse_simple_command(Vector& args) if (args.is_empty()) fatal_error("-size: requires additional arguments"); return make(args.take_first()); + } else if (arg == "-empty") { + return make(); } else if (arg == "-name") { if (args.is_empty()) fatal_error("-name: requires additional arguments");