mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:17:45 +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
2 changed files with 21 additions and 21 deletions
|
@ -12,6 +12,7 @@
|
||||||
#include <AK/StdLibExtras.h>
|
#include <AK/StdLibExtras.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <LibCore/File.h>
|
||||||
#include <LibCore/System.h>
|
#include <LibCore/System.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -931,6 +932,22 @@ ErrorOr<void> adjtime(const struct timeval* delta, struct timeval* old_delta)
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
ErrorOr<void> exec(StringView filename, Span<StringView> arguments, SearchInPath search_in_path, Optional<Span<StringView>> environment)
|
||||||
{
|
{
|
||||||
#ifdef __serenity__
|
#ifdef __serenity__
|
||||||
|
@ -971,28 +988,10 @@ ErrorOr<void> exec(StringView filename, Span<StringView> arguments, SearchInPath
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
if (search_in_path == SearchInPath::Yes && !filename.contains('/')) {
|
bool should_search_in_path = search_in_path == SearchInPath::Yes && !filename.contains('/');
|
||||||
auto const* path_ptr = getenv("PATH");
|
String exec_filename = should_search_in_path ? TRY(find_file_in_path(filename)) : filename.to_string();
|
||||||
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() };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
params.path = { exec_filename.characters(), exec_filename.length() };
|
||||||
TRY(run_exec(params));
|
TRY(run_exec(params));
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -160,6 +160,7 @@ ErrorOr<Array<int, 2>> pipe2(int flags);
|
||||||
#ifndef AK_OS_ANDROID
|
#ifndef AK_OS_ANDROID
|
||||||
ErrorOr<void> adjtime(const struct timeval* delta, struct timeval* old_delta);
|
ErrorOr<void> adjtime(const struct timeval* delta, struct timeval* old_delta);
|
||||||
#endif
|
#endif
|
||||||
|
ErrorOr<String> find_file_in_path(StringView filename);
|
||||||
enum class SearchInPath {
|
enum class SearchInPath {
|
||||||
No,
|
No,
|
||||||
Yes,
|
Yes,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue