1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 06:38:10 +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));
if (nread == 0)
break;
builder.append((const char*)buffer, nread);
TRY(builder.append((const char*)buffer, nread));
offset += nread;
if (nread < sizeof(buffer))
break;

View file

@ -178,7 +178,8 @@ private:
Message& append_number(N number)
{
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;
}
@ -264,14 +265,16 @@ Plan9FS::Message& Plan9FS::Message::operator<<(u64 number)
Plan9FS::Message& Plan9FS::Message::operator<<(const StringView& string)
{
*this << static_cast<u16>(string.length());
m_builder.append(string);
// FIXME: Handle append failure.
(void)m_builder.append(string);
return *this;
}
void Plan9FS::Message::append_data(const StringView& data)
{
*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)

View file

@ -336,7 +336,8 @@ private:
ProcFSSelfProcessDirectory();
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;
}
};
@ -559,8 +560,10 @@ private:
virtual bool output(KBufferBuilder& builder) override
{
InterruptDisabler disabler;
for (char ch : ConsoleDevice::the().logbuffer())
builder.append(ch);
for (char ch : ConsoleDevice::the().logbuffer()) {
if (builder.append(ch).is_error())
return false;
}
return true;
}
};
@ -664,7 +667,8 @@ private:
ProcFSUptime();
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;
}
};
@ -676,8 +680,10 @@ private:
ProcFSCommandLine();
virtual bool output(KBufferBuilder& builder) override
{
builder.append(kernel_command_line().string());
builder.append('\n');
if (builder.append(kernel_command_line().string()).is_error())
return false;
if (builder.append('\n').is_error())
return false;
return true;
}
};
@ -739,7 +745,8 @@ private:
{
if (!Process::current().is_superuser())
return false;
builder.append(String::number(kernel_load_base));
if (builder.append(String::number(kernel_load_base)).is_error())
return false;
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()))
return;
return ENOMEM;
memcpy(insertion_ptr(), bytes.data(), bytes.size());
m_size += bytes.size();
return KSuccess;
}
void KBufferBuilder::append(const StringView& str)
KResult KBufferBuilder::append(const StringView& str)
{
if (str.is_empty())
return;
return KSuccess;
if (!check_expand(str.length()))
return;
return ENOMEM;
memcpy(insertion_ptr(), str.characters_without_null_termination(), 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)
return;
return KSuccess;
if (!check_expand(length))
return;
return ENOMEM;
memcpy(insertion_ptr(), characters, length);
m_size += length;
return KSuccess;
}
void KBufferBuilder::append(char ch)
KResult KBufferBuilder::append(char ch)
{
if (!check_expand(1))
return;
return ENOMEM;
insertion_ptr()[0] = ch;
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) {
switch (ch) {
case '\e':
append("\\u001B");
TRY(append("\\u001B"));
break;
case '\b':
append("\\b");
TRY(append("\\b"));
break;
case '\n':
append("\\n");
TRY(append("\\n"));
break;
case '\t':
append("\\t");
TRY(append("\\t"));
break;
case '\"':
append("\\\"");
TRY(append("\\\""));
break;
case '\\':
append("\\\\");
TRY(append("\\\\"));
break;
default:
append(ch);
TRY(append(ch));
}
}
return KSuccess;
}
}

View file

@ -20,26 +20,33 @@ public:
KBufferBuilder(KBufferBuilder&&) = default;
~KBufferBuilder() = default;
void append(const StringView&);
void append(char);
void append(const char*, int);
KResult append(const StringView&);
KResult append(char);
KResult append(const char*, int);
void append_escaped_for_json(const StringView&);
void append_bytes(ReadonlyBytes);
KResult append_escaped_for_json(const StringView&);
KResult append_bytes(ReadonlyBytes);
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.
StringBuilder builder;
AK::VariadicFormatParams variadic_format_params { parameters... };
vformat(builder, fmtstr.view(), variadic_format_params);
append_bytes(builder.string_view().bytes());
return append_bytes(builder.string_view().bytes());
}
bool flush();
OwnPtr<KBuffer> build();
ReadonlyBytes bytes() const
{
if (!m_buffer)
return {};
return ReadonlyBytes { m_buffer->data(), m_buffer->size() };
}
private:
bool check_expand(size_t);
u8* insertion_ptr()

View file

@ -184,7 +184,8 @@ protected:
}
virtual bool output(KBufferBuilder& builder) override
{
builder.appendff("{}\n", value());
if (builder.appendff("{}\n", value()).is_error())
return false;
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 data = file_description->absolute_path();
builder.append(data);
TRY(builder.append(data));
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
{
builder.append_bytes(const_cast<Process&>(*this).current_directory().absolute_path().bytes());
return KSuccess;
return builder.append_bytes(const_cast<Process&>(*this).current_directory().absolute_path().bytes());
}
mode_t Process::binary_link_required_mode() const
@ -265,8 +264,7 @@ KResult Process::procfs_get_binary_link(KBufferBuilder& builder) const
auto* custody = executable();
if (!custody)
return KResult(ENOEXEC);
builder.append(custody->absolute_path().bytes());
return KSuccess;
return builder.append(custody->absolute_path().bytes());
}
}