1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-09 13:30:45 +00:00
serenity/Kernel/UserOrKernelBuffer.cpp
Andreas Kling 79fa9765ca Kernel: Replace KResult and KResultOr<T> with Error and ErrorOr<T>
We now use AK::Error and AK::ErrorOr<T> in both kernel and userspace!
This was a slightly tedious refactoring that took a long time, so it's
not unlikely that some bugs crept in.

Nevertheless, it does pass basic functionality testing, and it's just
real nice to finally see the same pattern in all contexts. :^)
2021-11-08 01:10:53 +01:00

69 lines
1.7 KiB
C++

/*
* Copyright (c) 2020, the SerenityOS developers.
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/Memory/MemoryManager.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
bool UserOrKernelBuffer::is_kernel_buffer() const
{
return !Memory::is_user_address(VirtualAddress(m_buffer));
}
ErrorOr<NonnullOwnPtr<KString>> UserOrKernelBuffer::try_copy_into_kstring(size_t size) const
{
if (!m_buffer)
return EINVAL;
if (Memory::is_user_address(VirtualAddress(m_buffer))) {
char* buffer;
auto kstring = TRY(KString::try_create_uninitialized(size, buffer));
TRY(copy_from_user(buffer, m_buffer, size));
return kstring;
}
return KString::try_create(ReadonlyBytes { m_buffer, size });
}
ErrorOr<void> UserOrKernelBuffer::write(void const* src, size_t offset, size_t len)
{
if (!m_buffer)
return EFAULT;
if (Memory::is_user_address(VirtualAddress(m_buffer)))
return copy_to_user(m_buffer + offset, src, len);
memcpy(m_buffer + offset, src, len);
return {};
}
ErrorOr<void> UserOrKernelBuffer::read(void* dest, size_t offset, size_t len) const
{
if (!m_buffer)
return EFAULT;
if (Memory::is_user_address(VirtualAddress(m_buffer)))
return copy_from_user(dest, m_buffer + offset, len);
memcpy(dest, m_buffer + offset, len);
return {};
}
ErrorOr<void> UserOrKernelBuffer::memset(int value, size_t offset, size_t len)
{
if (!m_buffer)
return EFAULT;
if (Memory::is_user_address(VirtualAddress(m_buffer)))
return memset_user(m_buffer + offset, value, len);
::memset(m_buffer + offset, value, len);
return {};
}
}