diff --git a/Ladybird/WebContentView.cpp b/Ladybird/WebContentView.cpp index 26d03ae63c..e16e3f8ad8 100644 --- a/Ladybird/WebContentView.cpp +++ b/Ladybird/WebContentView.cpp @@ -568,53 +568,8 @@ void WebContentView::create_client() { m_client_state = {}; - int socket_fds[2] {}; - MUST(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds)); - - int ui_fd = socket_fds[0]; - int wc_fd = socket_fds[1]; - - int fd_passing_socket_fds[2] {}; - MUST(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, fd_passing_socket_fds)); - - int ui_fd_passing_fd = fd_passing_socket_fds[0]; - int wc_fd_passing_fd = fd_passing_socket_fds[1]; - - auto child_pid = fork(); - if (!child_pid) { - MUST(Core::System::close(ui_fd_passing_fd)); - MUST(Core::System::close(ui_fd)); - - auto takeover_string = DeprecatedString::formatted("WebContent:{}", wc_fd); - MUST(Core::System::setenv("SOCKET_TAKEOVER"sv, takeover_string, true)); - - auto webcontent_fd_passing_socket_string = DeprecatedString::number(wc_fd_passing_fd); - - Vector arguments { - "WebContent"sv, - "--webcontent-fd-passing-socket"sv, - webcontent_fd_passing_socket_string - }; - - if (!m_webdriver_content_ipc_path.is_empty()) { - arguments.append("--webdriver-content-path"sv); - arguments.append(m_webdriver_content_ipc_path); - } - - auto result = spawn_helper_process("WebContent"sv, arguments, Core::System::SearchInPath::Yes); - if (result.is_error()) - warnln("Could not launch WebContent: {}", result.error()); - VERIFY_NOT_REACHED(); - } - - MUST(Core::System::close(wc_fd_passing_fd)); - MUST(Core::System::close(wc_fd)); - - auto socket = MUST(Core::LocalSocket::adopt_fd(ui_fd)); - MUST(socket->set_blocking(true)); - - auto new_client = MUST(adopt_nonnull_ref_or_enomem(new (nothrow) WebView::WebContentClient(std::move(socket), *this))); - new_client->set_fd_passing_socket(MUST(Core::LocalSocket::adopt_fd(ui_fd_passing_fd))); + auto candidate_web_content_paths = get_paths_for_helper_process("WebContent"sv).release_value_but_fixme_should_propagate_errors(); + auto new_client = launch_web_content_process(candidate_web_content_paths, m_webdriver_content_ipc_path).release_value_but_fixme_should_propagate_errors(); m_web_content_notifier.setSocket(new_client->socket().fd().value()); m_web_content_notifier.setEnabled(true); diff --git a/Userland/Libraries/LibWebView/ViewImplementation.cpp b/Userland/Libraries/LibWebView/ViewImplementation.cpp index e547191e81..85332ee979 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.cpp +++ b/Userland/Libraries/LibWebView/ViewImplementation.cpp @@ -124,4 +124,66 @@ void ViewImplementation::run_javascript(StringView js_source) client().async_run_javascript(js_source); } +#if !defined(AK_OS_SERENITY) + +ErrorOr> ViewImplementation::launch_web_content_process(ReadonlySpan candidate_web_content_paths, StringView webdriver_content_ipc_path) +{ + int socket_fds[2] {}; + TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds)); + + int ui_fd = socket_fds[0]; + int wc_fd = socket_fds[1]; + + int fd_passing_socket_fds[2] {}; + TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, fd_passing_socket_fds)); + + int ui_fd_passing_fd = fd_passing_socket_fds[0]; + int wc_fd_passing_fd = fd_passing_socket_fds[1]; + + if (auto child_pid = TRY(Core::System::fork()); child_pid == 0) { + TRY(Core::System::close(ui_fd_passing_fd)); + TRY(Core::System::close(ui_fd)); + + auto takeover_string = TRY(String::formatted("WebContent:{}", wc_fd)); + TRY(Core::System::setenv("SOCKET_TAKEOVER"sv, takeover_string, true)); + + auto webcontent_fd_passing_socket_string = TRY(String::number(wc_fd_passing_fd)); + + Vector arguments { + "WebContent"sv, + "--webcontent-fd-passing-socket"sv, + webcontent_fd_passing_socket_string + }; + + if (!webdriver_content_ipc_path.is_empty()) { + TRY(arguments.try_append("--webdriver-content-path"sv)); + TRY(arguments.try_append(webdriver_content_ipc_path)); + } + + ErrorOr result; + for (auto const& path : candidate_web_content_paths) { + result = Core::System::exec(path, arguments, Core::System::SearchInPath::Yes); + if (!result.is_error()) + break; + } + + if (result.is_error()) + warnln("Could not launch any of {}: {}", candidate_web_content_paths, result.error()); + VERIFY_NOT_REACHED(); + } + + TRY(Core::System::close(wc_fd_passing_fd)); + TRY(Core::System::close(wc_fd)); + + auto socket = TRY(Core::LocalSocket::adopt_fd(ui_fd)); + TRY(socket->set_blocking(true)); + + auto new_client = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) WebView::WebContentClient(move(socket), *this))); + new_client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(ui_fd_passing_fd))); + + return new_client; +} + +#endif + } diff --git a/Userland/Libraries/LibWebView/ViewImplementation.h b/Userland/Libraries/LibWebView/ViewImplementation.h index a9dda8531d..ea4813a9a9 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.h +++ b/Userland/Libraries/LibWebView/ViewImplementation.h @@ -117,6 +117,10 @@ protected: virtual void create_client() = 0; virtual void update_zoom() = 0; +#if !defined(AK_OS_SERENITY) + ErrorOr> launch_web_content_process(ReadonlySpan candidate_web_content_paths, StringView webdriver_content_ipc_path); +#endif + struct SharedBitmap { i32 id { -1 }; i32 pending_paints { 0 };