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.
This commit is contained in:
Andreas Kling 2021-05-13 22:34:57 +02:00
commit 3d3a5b431f
Notes: sideshowbarker 2024-07-18 18:12:32 +09:00
11 changed files with 332 additions and 0 deletions

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "InspectableProcess.h"
namespace InspectorServer {
HashMap<pid_t, NonnullOwnPtr<InspectableProcess>> g_processes;
InspectableProcess* InspectableProcess::from_pid(pid_t pid)
{
return g_processes.get(pid).value_or(nullptr);
}
InspectableProcess::InspectableProcess(pid_t pid, NonnullRefPtr<Core::LocalSocket> 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);
}
}