From 3d3a5b431f1836b6905e5ac2408389916b3e1ce1 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 13 May 2021 22:34:57 +0200 Subject: Services: Add InspectorServer to reverse the direction of Inspector This service daemon will act as an intermediary between the Inspector program and the inspectable programs it wants to inspect. Programs can make themselves available for inspection by connecting to /tmp/portal/inspectables using the Core::EventLoop RPC protocol. --- .../InspectorServer/InspectableProcess.cpp | 77 ++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Userland/Services/InspectorServer/InspectableProcess.cpp (limited to 'Userland/Services/InspectorServer/InspectableProcess.cpp') diff --git a/Userland/Services/InspectorServer/InspectableProcess.cpp b/Userland/Services/InspectorServer/InspectableProcess.cpp new file mode 100644 index 0000000000..a064acd415 --- /dev/null +++ b/Userland/Services/InspectorServer/InspectableProcess.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "InspectableProcess.h" + +namespace InspectorServer { + +HashMap> g_processes; + +InspectableProcess* InspectableProcess::from_pid(pid_t pid) +{ + return g_processes.get(pid).value_or(nullptr); +} + +InspectableProcess::InspectableProcess(pid_t pid, NonnullRefPtr socket) + : m_pid(pid) + , m_socket(move(socket)) +{ + m_socket->set_blocking(true); + m_socket->on_ready_to_read = [this] { + auto buffer = m_socket->read(1); + if (m_socket->eof()) { + g_processes.remove(m_pid); + return; + } + }; +} + +InspectableProcess::~InspectableProcess() +{ +} + +String InspectableProcess::wait_for_response() +{ + if (m_socket->eof()) { + dbgln("InspectableProcess disconnected: PID {}", m_pid); + m_socket->close(); + return {}; + } + + u32 length {}; + auto nread = m_socket->read((u8*)&length, sizeof(length)); + if (nread != sizeof(length)) { + dbgln("InspectableProcess got malformed data: PID {}", m_pid); + m_socket->close(); + return {}; + } + + ByteBuffer data; + size_t remaining_bytes = length; + + while (remaining_bytes) { + auto packet = m_socket->read(remaining_bytes); + if (packet.size() == 0) + break; + data.append(packet.data(), packet.size()); + remaining_bytes -= packet.size(); + } + + VERIFY(data.size() == length); + dbgln("Got data size {} and read that many bytes", length); + + return String::copy(data); +} + +void InspectableProcess::send_request(JsonObject const& request) +{ + auto serialized = request.to_string(); + auto length = serialized.length(); + m_socket->write((u8 const*)&length, sizeof(length)); + m_socket->write(serialized); +} + +} -- cgit v1.2.3