find: Add the -readable, -writable and -executable options

This commit is contained in:
Tim Ledbetter 2023-08-27 10:42:04 +01:00 committed by Tim Flynn
parent 4519ac2da9
commit edd49c1531
2 changed files with 27 additions and 0 deletions

View file

@ -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

View file

@ -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<Command> parse_simple_command(Vector<char*>& args)
if (args.is_empty())
fatal_error("-iname: requires additional arguments");
return make<NameCommand>(args.take_first(), CaseSensitivity::CaseInsensitive);
} else if (arg == "-readable") {
return make<AccessCommand>(R_OK);
} else if (arg == "-writable") {
return make<AccessCommand>(W_OK);
} else if (arg == "-executable") {
return make<AccessCommand>(X_OK);
} else if (arg == "-print") {
g_have_seen_action_command = true;
return make<PrintCommand>();