blob: 1b085db255ce826cd1e2a4fa20f5196c3ad508c5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "InspectableProcess.h"
#include <AK/JsonObject.h>
#include <LibCore/EventLoop.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, NonnullOwnPtr<Core::Stream::LocalSocket> socket)
: m_pid(pid)
, m_socket(move(socket))
{
// FIXME: Propagate errors
MUST(m_socket->set_blocking(true));
m_socket->on_ready_to_read = [this] {
char c;
[[maybe_unused]] auto buffer = m_socket->read({ &c, 1 });
if (m_socket->is_eof()) {
Core::deferred_invoke([pid = this->m_pid] { g_processes.remove(pid); });
return;
}
};
}
String InspectableProcess::wait_for_response()
{
if (m_socket->is_eof()) {
dbgln("InspectableProcess disconnected: PID {}", m_pid);
m_socket->close();
return {};
}
u32 length {};
auto nread = m_socket->read({ (u8*)&length, sizeof(length) }).release_value_but_fixme_should_propagate_errors();
if (nread != sizeof(length)) {
dbgln("InspectableProcess got malformed data: PID {}", m_pid);
m_socket->close();
return {};
}
auto data_buffer = ByteBuffer::create_uninitialized(length).release_value_but_fixme_should_propagate_errors();
auto remaining_data_buffer = data_buffer.bytes();
while (!remaining_data_buffer.is_empty()) {
auto maybe_nread = m_socket->read(remaining_data_buffer);
if (maybe_nread.is_error()) {
dbgln("InspectableProcess::wait_for_response: Failed to read data: {}", maybe_nread.error());
break;
}
auto nread = maybe_nread.release_value();
if (nread == 0)
break;
remaining_data_buffer = remaining_data_buffer.slice(nread);
}
VERIFY(data_buffer.size() == length);
dbgln("Got data size {} and read that many bytes", length);
return String::copy(data_buffer);
}
void InspectableProcess::send_request(JsonObject const& request)
{
auto serialized = request.to_string();
u32 length = serialized.length();
// FIXME: Propagate errors
MUST(m_socket->write({ (u8 const*)&length, sizeof(length) }));
MUST(m_socket->write(serialized.bytes()));
}
}
|