mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-03 04:50:29 +00:00
LibCore: Add function for searching a file in $PATH
This extracts the logic of searching for a file in $PATH from System::exec to a separate function.
This commit is contained in:
parent
01f0ae20b6
commit
91a03bc6ae
Notes:
sideshowbarker
2024-07-17 08:42:05 +09:00
Author: https://github.com/itamar8910 Commit: https://github.com/SerenityOS/serenity/commit/91a03bc6ae Pull-request: https://github.com/SerenityOS/serenity/pull/14613
2 changed files with 21 additions and 21 deletions
|
@ -12,6 +12,7 @@
|
|||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -931,6 +932,22 @@ ErrorOr<void> adjtime(const struct timeval* delta, struct timeval* old_delta)
|
|||
}
|
||||
#endif
|
||||
|
||||
ErrorOr<String> find_file_in_path(StringView filename)
|
||||
{
|
||||
auto const* path_ptr = getenv("PATH");
|
||||
StringView path { path_ptr, strlen(path_ptr) };
|
||||
if (path.is_empty())
|
||||
path = "/bin:/usr/bin"sv;
|
||||
auto parts = path.split_view(':');
|
||||
for (auto& part : parts) {
|
||||
auto candidate = String::formatted("{}/{}", part, filename);
|
||||
if (Core::File::exists(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return Error::from_errno(ENOENT);
|
||||
}
|
||||
|
||||
ErrorOr<void> exec(StringView filename, Span<StringView> arguments, SearchInPath search_in_path, Optional<Span<StringView>> environment)
|
||||
{
|
||||
#ifdef __serenity__
|
||||
|
@ -971,28 +988,10 @@ ErrorOr<void> exec(StringView filename, Span<StringView> arguments, SearchInPath
|
|||
return {};
|
||||
};
|
||||
|
||||
if (search_in_path == SearchInPath::Yes && !filename.contains('/')) {
|
||||
auto const* path_ptr = getenv("PATH");
|
||||
StringView path { path_ptr, strlen(path_ptr) };
|
||||
if (path.is_empty())
|
||||
path = "/bin:/usr/bin"sv;
|
||||
auto parts = path.split_view(':');
|
||||
for (auto& part : parts) {
|
||||
auto candidate = String::formatted("{}/{}", part, filename);
|
||||
params.path = { candidate.characters(), candidate.length() };
|
||||
auto result = run_exec(params);
|
||||
if (result.is_error()) {
|
||||
if (result.error().code() != ENOENT)
|
||||
return result.error();
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
return Error::from_syscall("exec"sv, -ENOENT);
|
||||
} else {
|
||||
params.path = { filename.characters_without_null_termination(), filename.length() };
|
||||
}
|
||||
bool should_search_in_path = search_in_path == SearchInPath::Yes && !filename.contains('/');
|
||||
String exec_filename = should_search_in_path ? TRY(find_file_in_path(filename)) : filename.to_string();
|
||||
|
||||
params.path = { exec_filename.characters(), exec_filename.length() };
|
||||
TRY(run_exec(params));
|
||||
VERIFY_NOT_REACHED();
|
||||
#else
|
||||
|
|
|
@ -160,6 +160,7 @@ ErrorOr<Array<int, 2>> pipe2(int flags);
|
|||
#ifndef AK_OS_ANDROID
|
||||
ErrorOr<void> adjtime(const struct timeval* delta, struct timeval* old_delta);
|
||||
#endif
|
||||
ErrorOr<String> find_file_in_path(StringView filename);
|
||||
enum class SearchInPath {
|
||||
No,
|
||||
Yes,
|
||||
|
|
Loading…
Reference in a new issue