/* * Copyright (c) 2024, Andrew Kaster * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace WebView { class Process { AK_MAKE_NONCOPYABLE(Process); AK_MAKE_DEFAULT_MOVABLE(Process); public: Process(ProcessType type, RefPtr connection, Core::Process process); ~Process(); template struct ProcessAndClient; template static ErrorOr> spawn(ProcessType type, Core::ProcessSpawnOptions const& options, ClientArguments&&... client_arguments); ProcessType type() const { return m_type; } Optional const& title() const { return m_title; } void set_title(Optional title) { m_title = move(title); } template Optional client() { if (auto strong_connection = m_connection.strong_ref()) return verify_cast(*strong_connection); return {}; } pid_t pid() const { return m_process.pid(); } struct ProcessPaths { ByteString socket_path; ByteString pid_path; }; static ErrorOr paths_for_process(StringView process_name); static ErrorOr> get_process_pid(StringView process_name, StringView pid_path); static ErrorOr create_ipc_socket(ByteString const& socket_path); private: struct ProcessAndIPCTransport { Core::Process process; IPC::Transport transport; }; static ErrorOr spawn_and_connect_to_process(Core::ProcessSpawnOptions const& options); Core::Process m_process; ProcessType m_type; Optional m_title; WeakPtr m_connection; }; template struct Process::ProcessAndClient { Process process; NonnullRefPtr client; }; template ErrorOr> Process::spawn(ProcessType type, Core::ProcessSpawnOptions const& options, ClientArguments&&... client_arguments) { auto [core_process, transport] = TRY(spawn_and_connect_to_process(options)); auto client = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ClientType { move(transport), forward(client_arguments)... })); return ProcessAndClient { Process { type, client, move(core_process) }, client }; } }