diff --git a/Userland/Libraries/LibCore/System.cpp b/Userland/Libraries/LibCore/System.cpp index 711373277c5..459ac94dfe5 100644 --- a/Userland/Libraries/LibCore/System.cpp +++ b/Userland/Libraries/LibCore/System.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -931,6 +932,22 @@ ErrorOr adjtime(const struct timeval* delta, struct timeval* old_delta) } #endif +ErrorOr 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 exec(StringView filename, Span arguments, SearchInPath search_in_path, Optional> environment) { #ifdef __serenity__ @@ -971,28 +988,10 @@ ErrorOr exec(StringView filename, Span 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 diff --git a/Userland/Libraries/LibCore/System.h b/Userland/Libraries/LibCore/System.h index e25c2e7777a..d183682dd6f 100644 --- a/Userland/Libraries/LibCore/System.h +++ b/Userland/Libraries/LibCore/System.h @@ -160,6 +160,7 @@ ErrorOr> pipe2(int flags); #ifndef AK_OS_ANDROID ErrorOr adjtime(const struct timeval* delta, struct timeval* old_delta); #endif +ErrorOr find_file_in_path(StringView filename); enum class SearchInPath { No, Yes,