mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 09:58: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:
parent
b096e85777
commit
2065ced8f6
7 changed files with 63 additions and 42 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue