1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 05:38:11 +00:00

Kernel: Make KBufferBuilder::append() & friends return KResult

This allows callers to react to a failed append (due to OOM.)
This commit is contained in:
Andreas Kling 2021-09-06 18:24:13 +02:00
parent b096e85777
commit 2065ced8f6
7 changed files with 63 additions and 42 deletions

View file

@ -57,7 +57,7 @@ KResultOr<NonnullOwnPtr<KBuffer>> Inode::read_entire(FileDescription* descriptio
VERIFY(nread <= sizeof(buffer)); VERIFY(nread <= sizeof(buffer));
if (nread == 0) if (nread == 0)
break; break;
builder.append((const char*)buffer, nread); TRY(builder.append((const char*)buffer, nread));
offset += nread; offset += nread;
if (nread < sizeof(buffer)) if (nread < sizeof(buffer))
break; break;

View file

@ -178,7 +178,8 @@ private:
Message& append_number(N number) Message& append_number(N number)
{ {
VERIFY(!m_have_been_built); VERIFY(!m_have_been_built);
m_builder.append(reinterpret_cast<const char*>(&number), sizeof(number)); // FIXME: Handle append failure.
(void)m_builder.append(reinterpret_cast<const char*>(&number), sizeof(number));
return *this; return *this;
} }
@ -264,14 +265,16 @@ Plan9FS::Message& Plan9FS::Message::operator<<(u64 number)
Plan9FS::Message& Plan9FS::Message::operator<<(const StringView& string) Plan9FS::Message& Plan9FS::Message::operator<<(const StringView& string)
{ {
*this << static_cast<u16>(string.length()); *this << static_cast<u16>(string.length());
m_builder.append(string); // FIXME: Handle append failure.
(void)m_builder.append(string);
return *this; return *this;
} }
void Plan9FS::Message::append_data(const StringView& data) void Plan9FS::Message::append_data(const StringView& data)
{ {
*this << static_cast<u32>(data.length()); *this << static_cast<u32>(data.length());
m_builder.append(data); // FIXME: Handle append failure.
(void)m_builder.append(data);
} }
Plan9FS::Message::Decoder& Plan9FS::Message::Decoder::operator>>(u8& number) Plan9FS::Message::Decoder& Plan9FS::Message::Decoder::operator>>(u8& number)

View file

@ -336,7 +336,8 @@ private:
ProcFSSelfProcessDirectory(); ProcFSSelfProcessDirectory();
virtual bool acquire_link(KBufferBuilder& builder) override virtual bool acquire_link(KBufferBuilder& builder) override
{ {
builder.appendff("{}", Process::current().pid().value()); if (builder.appendff("{}", Process::current().pid().value()).is_error())
return false;
return true; return true;
} }
}; };
@ -559,8 +560,10 @@ private:
virtual bool output(KBufferBuilder& builder) override virtual bool output(KBufferBuilder& builder) override
{ {
InterruptDisabler disabler; InterruptDisabler disabler;
for (char ch : ConsoleDevice::the().logbuffer()) for (char ch : ConsoleDevice::the().logbuffer()) {
builder.append(ch); if (builder.append(ch).is_error())
return false;
}
return true; return true;
} }
}; };
@ -664,7 +667,8 @@ private:
ProcFSUptime(); ProcFSUptime();
virtual bool output(KBufferBuilder& builder) override virtual bool output(KBufferBuilder& builder) override
{ {
builder.appendff("{}\n", TimeManagement::the().uptime_ms() / 1000); if (builder.appendff("{}\n", TimeManagement::the().uptime_ms() / 1000).is_error())
return false;
return true; return true;
} }
}; };
@ -676,8 +680,10 @@ private:
ProcFSCommandLine(); ProcFSCommandLine();
virtual bool output(KBufferBuilder& builder) override virtual bool output(KBufferBuilder& builder) override
{ {
builder.append(kernel_command_line().string()); if (builder.append(kernel_command_line().string()).is_error())
builder.append('\n'); return false;
if (builder.append('\n').is_error())
return false;
return true; return true;
} }
}; };
@ -739,7 +745,8 @@ private:
{ {
if (!Process::current().is_superuser()) if (!Process::current().is_superuser())
return false; return false;
builder.append(String::number(kernel_load_base)); if (builder.append(String::number(kernel_load_base)).is_error())
return false;
return true; return true;
} }
}; };

View file

@ -45,68 +45,73 @@ KBufferBuilder::KBufferBuilder()
{ {
} }
void KBufferBuilder::append_bytes(ReadonlyBytes bytes) KResult KBufferBuilder::append_bytes(ReadonlyBytes bytes)
{ {
if (!check_expand(bytes.size())) if (!check_expand(bytes.size()))
return; return ENOMEM;
memcpy(insertion_ptr(), bytes.data(), bytes.size()); memcpy(insertion_ptr(), bytes.data(), bytes.size());
m_size += bytes.size(); m_size += bytes.size();
return KSuccess;
} }
void KBufferBuilder::append(const StringView& str) KResult KBufferBuilder::append(const StringView& str)
{ {
if (str.is_empty()) if (str.is_empty())
return; return KSuccess;
if (!check_expand(str.length())) if (!check_expand(str.length()))
return; return ENOMEM;
memcpy(insertion_ptr(), str.characters_without_null_termination(), str.length()); memcpy(insertion_ptr(), str.characters_without_null_termination(), str.length());
m_size += str.length(); m_size += str.length();
return KSuccess;
} }
void KBufferBuilder::append(const char* characters, int length) KResult KBufferBuilder::append(const char* characters, int length)
{ {
if (!length) if (!length)
return; return KSuccess;
if (!check_expand(length)) if (!check_expand(length))
return; return ENOMEM;
memcpy(insertion_ptr(), characters, length); memcpy(insertion_ptr(), characters, length);
m_size += length; m_size += length;
return KSuccess;
} }
void KBufferBuilder::append(char ch) KResult KBufferBuilder::append(char ch)
{ {
if (!check_expand(1)) if (!check_expand(1))
return; return ENOMEM;
insertion_ptr()[0] = ch; insertion_ptr()[0] = ch;
m_size += 1; m_size += 1;
return KSuccess;
} }
void KBufferBuilder::append_escaped_for_json(const StringView& string) KResult KBufferBuilder::append_escaped_for_json(const StringView& string)
{ {
for (auto ch : string) { for (auto ch : string) {
switch (ch) { switch (ch) {
case '\e': case '\e':
append("\\u001B"); TRY(append("\\u001B"));
break; break;
case '\b': case '\b':
append("\\b"); TRY(append("\\b"));
break; break;
case '\n': case '\n':
append("\\n"); TRY(append("\\n"));
break; break;
case '\t': case '\t':
append("\\t"); TRY(append("\\t"));
break; break;
case '\"': case '\"':
append("\\\""); TRY(append("\\\""));
break; break;
case '\\': case '\\':
append("\\\\"); TRY(append("\\\\"));
break; break;
default: default:
append(ch); TRY(append(ch));
} }
} }
return KSuccess;
} }
} }

View file

@ -20,26 +20,33 @@ public:
KBufferBuilder(KBufferBuilder&&) = default; KBufferBuilder(KBufferBuilder&&) = default;
~KBufferBuilder() = default; ~KBufferBuilder() = default;
void append(const StringView&); KResult append(const StringView&);
void append(char); KResult append(char);
void append(const char*, int); KResult append(const char*, int);
void append_escaped_for_json(const StringView&); KResult append_escaped_for_json(const StringView&);
void append_bytes(ReadonlyBytes); KResult append_bytes(ReadonlyBytes);
template<typename... Parameters> template<typename... Parameters>
void appendff(CheckedFormatString<Parameters...>&& fmtstr, const Parameters&... parameters) KResult appendff(CheckedFormatString<Parameters...>&& fmtstr, const Parameters&... parameters)
{ {
// FIXME: This really not ideal, but vformat expects StringBuilder. // FIXME: This really not ideal, but vformat expects StringBuilder.
StringBuilder builder; StringBuilder builder;
AK::VariadicFormatParams variadic_format_params { parameters... }; AK::VariadicFormatParams variadic_format_params { parameters... };
vformat(builder, fmtstr.view(), variadic_format_params); vformat(builder, fmtstr.view(), variadic_format_params);
append_bytes(builder.string_view().bytes()); return append_bytes(builder.string_view().bytes());
} }
bool flush(); bool flush();
OwnPtr<KBuffer> build(); OwnPtr<KBuffer> build();
ReadonlyBytes bytes() const
{
if (!m_buffer)
return {};
return ReadonlyBytes { m_buffer->data(), m_buffer->size() };
}
private: private:
bool check_expand(size_t); bool check_expand(size_t);
u8* insertion_ptr() u8* insertion_ptr()

View file

@ -184,7 +184,8 @@ protected:
} }
virtual bool output(KBufferBuilder& builder) override virtual bool output(KBufferBuilder& builder) override
{ {
builder.appendff("{}\n", value()); if (builder.appendff("{}\n", value()).is_error())
return false;
return true; return true;
} }
}; };

View file

@ -81,7 +81,7 @@ KResultOr<size_t> Process::procfs_get_file_description_link(unsigned fd, KBuffer
{ {
auto file_description = TRY(m_fds.file_description(fd)); auto file_description = TRY(m_fds.file_description(fd));
auto data = file_description->absolute_path(); auto data = file_description->absolute_path();
builder.append(data); TRY(builder.append(data));
return data.length(); return data.length();
} }
@ -249,8 +249,7 @@ KResult Process::procfs_get_virtual_memory_stats(KBufferBuilder& builder) const
KResult Process::procfs_get_current_work_directory_link(KBufferBuilder& builder) const KResult Process::procfs_get_current_work_directory_link(KBufferBuilder& builder) const
{ {
builder.append_bytes(const_cast<Process&>(*this).current_directory().absolute_path().bytes()); return builder.append_bytes(const_cast<Process&>(*this).current_directory().absolute_path().bytes());
return KSuccess;
} }
mode_t Process::binary_link_required_mode() const mode_t Process::binary_link_required_mode() const
@ -265,8 +264,7 @@ KResult Process::procfs_get_binary_link(KBufferBuilder& builder) const
auto* custody = executable(); auto* custody = executable();
if (!custody) if (!custody)
return KResult(ENOEXEC); return KResult(ENOEXEC);
builder.append(custody->absolute_path().bytes()); return builder.append(custody->absolute_path().bytes());
return KSuccess;
} }
} }