|
@@ -1655,4 +1655,39 @@ ErrorOr<void> posix_fallocate(int fd, off_t offset, off_t length)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+// This constant is copied from LibFileSystem. We cannot use or even include it directly,
|
|
|
+// because that would cause a dependency of LibCore on LibFileSystem, effectively rendering
|
|
|
+// the distinction between these libraries moot.
|
|
|
+static constexpr StringView INTERNAL_DEFAULT_PATH_SV = "/usr/local/sbin:/usr/local/bin:/usr/bin:/bin"sv;
|
|
|
+
|
|
|
+ErrorOr<String> resolve_executable_from_environment(StringView filename, int flags)
|
|
|
+{
|
|
|
+ if (filename.is_empty())
|
|
|
+ return Error::from_errno(ENOENT);
|
|
|
+
|
|
|
+ // Paths that aren't just a file name generally count as already resolved.
|
|
|
+ if (filename.contains('/')) {
|
|
|
+ TRY(Core::System::access(filename, X_OK, flags));
|
|
|
+ return TRY(String::from_utf8(filename));
|
|
|
+ }
|
|
|
+
|
|
|
+ auto const* path_str = ::getenv("PATH");
|
|
|
+ StringView path;
|
|
|
+ if (path_str)
|
|
|
+ path = { path_str, strlen(path_str) };
|
|
|
+ if (path.is_empty())
|
|
|
+ path = INTERNAL_DEFAULT_PATH_SV;
|
|
|
+
|
|
|
+ auto directories = path.split_view(':');
|
|
|
+
|
|
|
+ for (auto directory : directories) {
|
|
|
+ auto file = TRY(String::formatted("{}/{}", directory, filename));
|
|
|
+
|
|
|
+ if (!Core::System::access(file, X_OK, flags).is_error())
|
|
|
+ return file;
|
|
|
+ }
|
|
|
+
|
|
|
+ return Error::from_errno(ENOENT);
|
|
|
+}
|
|
|
+
|
|
|
}
|