diff --git a/Base/usr/share/man/man1/find.md b/Base/usr/share/man/man1/find.md index 938773069d..b4f19b865e 100644 --- a/Base/usr/share/man/man1/find.md +++ b/Base/usr/share/man/man1/find.md @@ -39,6 +39,10 @@ specified commands, a `-print` command is implicitly appended. pattern (case sensitive). * `-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. +* `-writable`: Checks if the file is writable by the current user. +* `-executable`: Checks if the file is executable, or directory is searchable, +by the current user. * `-print`: Outputs the file path, followed by a newline. Always evaluates to true. * `-print0`: Outputs the file path, followed by a zero byte. Always evaluates to diff --git a/Userland/Utilities/find.cpp b/Userland/Utilities/find.cpp index 7ec1ffa374..c75c31fc41 100644 --- a/Userland/Utilities/find.cpp +++ b/Userland/Utilities/find.cpp @@ -267,6 +267,23 @@ private: CaseSensitivity m_case_sensitivity { CaseSensitivity::CaseSensitive }; }; +class AccessCommand final : public Command { +public: + AccessCommand(mode_t mode) + : m_mode(mode) + { + } + +private: + virtual bool evaluate(FileData& file_data) const override + { + auto maybe_error = Core::System::access(file_data.full_path.string(), m_mode); + return !maybe_error.is_error(); + } + + mode_t m_mode { 0 }; +}; + class PrintCommand final : public Command { public: PrintCommand(char terminator = '\n') @@ -409,6 +426,12 @@ static OwnPtr parse_simple_command(Vector& args) if (args.is_empty()) fatal_error("-iname: requires additional arguments"); return make(args.take_first(), CaseSensitivity::CaseInsensitive); + } else if (arg == "-readable") { + return make(R_OK); + } else if (arg == "-writable") { + return make(W_OK); + } else if (arg == "-executable") { + return make(X_OK); } else if (arg == "-print") { g_have_seen_action_command = true; return make();