mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-10 10:01:13 +09:00
find: Add the -newer
, -anewer
and -cnewer
options
These return true if the last modification time, last access time or creation time of a file is greater than the given reference file. If the `-L` option is in use and the given reference file is a symbolic link then the timestamp of the file pointed to by the symbolic link will be used.
This commit is contained in:
parent
57a1d99cf4
commit
64bb5652a1
Notes:
sideshowbarker
2024-07-17 07:08:37 +09:00
Author: https://github.com/tcl3
Commit: 64bb5652a1
Pull-request: https://github.com/SerenityOS/serenity/pull/20838
Reviewed-by: https://github.com/gmta ✅
2 changed files with 71 additions and 0 deletions
|
@ -52,6 +52,18 @@ space rounded up to the nearest whole unit.
|
||||||
* `-writable`: Checks if the file is writable 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,
|
* `-executable`: Checks if the file is executable, or directory is searchable,
|
||||||
by the current user.
|
by the current user.
|
||||||
|
* `-newer file`: Checks if the file last modification time is greater than that
|
||||||
|
of the specified reference file. If `file` is a symbolic link and the `-L`
|
||||||
|
option is in use, then the last modification time of the file pointed to by
|
||||||
|
the symbolic link is used.
|
||||||
|
* `-anewer file`: Checks if the file last access time is greater than that of
|
||||||
|
the specified reference file. If `file` is a symbolic link and the `-L`
|
||||||
|
option is in use, then the last access time of the file pointed to by the
|
||||||
|
symbolic link is used.
|
||||||
|
* `-cnewer file`: Checks if the file creation time is greater than that of
|
||||||
|
the specified reference file. If `file` is a symbolic link and the `-L`
|
||||||
|
option is in use, then the creation time of the file pointed to by the
|
||||||
|
symbolic link is used.
|
||||||
* `-print`: Outputs the file path, followed by a newline. Always evaluates to
|
* `-print`: Outputs the file path, followed by a newline. Always evaluates to
|
||||||
true.
|
true.
|
||||||
* `-print0`: Outputs the file path, followed by a zero byte. Always evaluates to
|
* `-print0`: Outputs the file path, followed by a zero byte. Always evaluates to
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/LexicalPath.h>
|
#include <AK/LexicalPath.h>
|
||||||
#include <AK/NonnullOwnPtr.h>
|
#include <AK/NonnullOwnPtr.h>
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
|
#include <AK/Time.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibCore/System.h>
|
#include <LibCore/System.h>
|
||||||
#include <LibMain/Main.h>
|
#include <LibMain/Main.h>
|
||||||
|
@ -326,6 +327,52 @@ private:
|
||||||
mode_t m_mode { 0 };
|
mode_t m_mode { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NewerCommand final : public StatCommand {
|
||||||
|
public:
|
||||||
|
enum class TimestampType {
|
||||||
|
LastAccess,
|
||||||
|
Creation,
|
||||||
|
LastModification
|
||||||
|
};
|
||||||
|
|
||||||
|
NewerCommand(char const* arg, TimestampType timestamp_type)
|
||||||
|
{
|
||||||
|
auto stat_function = g_follow_symlinks ? Core::System::stat : Core::System::lstat;
|
||||||
|
auto stat_or_error = stat_function({ arg, strlen(arg) });
|
||||||
|
if (stat_or_error.is_error())
|
||||||
|
fatal_error("find: '{}': {}", arg, strerror(stat_or_error.error().code()));
|
||||||
|
|
||||||
|
m_reference_file_stat = stat_or_error.release_value();
|
||||||
|
m_timestamp_type = timestamp_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool evaluate(struct stat const& stat) const override
|
||||||
|
{
|
||||||
|
struct timespec current_file_timestamp;
|
||||||
|
struct timespec reference_file_timestamp;
|
||||||
|
switch (m_timestamp_type) {
|
||||||
|
case TimestampType::LastAccess:
|
||||||
|
current_file_timestamp = stat.st_atim;
|
||||||
|
reference_file_timestamp = m_reference_file_stat.st_atim;
|
||||||
|
break;
|
||||||
|
case TimestampType::Creation:
|
||||||
|
current_file_timestamp = stat.st_ctim;
|
||||||
|
reference_file_timestamp = m_reference_file_stat.st_ctim;
|
||||||
|
break;
|
||||||
|
case TimestampType::LastModification:
|
||||||
|
current_file_timestamp = stat.st_mtim;
|
||||||
|
reference_file_timestamp = m_reference_file_stat.st_mtim;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Duration::from_timespec(current_file_timestamp) > Duration::from_timespec(reference_file_timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stat m_reference_file_stat;
|
||||||
|
TimestampType m_timestamp_type { TimestampType::LastModification };
|
||||||
|
};
|
||||||
|
|
||||||
class PrintCommand final : public Command {
|
class PrintCommand final : public Command {
|
||||||
public:
|
public:
|
||||||
PrintCommand(char terminator = '\n')
|
PrintCommand(char terminator = '\n')
|
||||||
|
@ -488,6 +535,18 @@ static OwnPtr<Command> parse_simple_command(Vector<char*>& args)
|
||||||
return make<AccessCommand>(W_OK);
|
return make<AccessCommand>(W_OK);
|
||||||
} else if (arg == "-executable") {
|
} else if (arg == "-executable") {
|
||||||
return make<AccessCommand>(X_OK);
|
return make<AccessCommand>(X_OK);
|
||||||
|
} else if (arg == "-newer") {
|
||||||
|
if (args.is_empty())
|
||||||
|
fatal_error("-newer: requires additional arguments");
|
||||||
|
return make<NewerCommand>(args.take_first(), NewerCommand::TimestampType::LastModification);
|
||||||
|
} else if (arg == "-anewer") {
|
||||||
|
if (args.is_empty())
|
||||||
|
fatal_error("-anewer: requires additional arguments");
|
||||||
|
return make<NewerCommand>(args.take_first(), NewerCommand::TimestampType::LastAccess);
|
||||||
|
} else if (arg == "-cnewer") {
|
||||||
|
if (args.is_empty())
|
||||||
|
fatal_error("-cnewer: requires additional arguments");
|
||||||
|
return make<NewerCommand>(args.take_first(), NewerCommand::TimestampType::Creation);
|
||||||
} else if (arg == "-print") {
|
} else if (arg == "-print") {
|
||||||
g_have_seen_action_command = true;
|
g_have_seen_action_command = true;
|
||||||
return make<PrintCommand>();
|
return make<PrintCommand>();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue