1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 13:38:11 +00:00
serenity/Kernel/Syscalls/uname.cpp
Liav A d8b514873f Kernel: Use FixedStringBuffer for fixed-length strings in syscalls
Using the kernel stack is preferable, especially when the examined
strings should be limited to a reasonable length.

This is a small improvement, because if we don't actually move these
strings then we don't need to own heap allocations for them during the
syscall handler function scope.

In addition to that, some kernel strings are known to be limited, like
the hostname string, for these strings we also can use FixedStringBuffer
to store and copy to and from these buffers, without using any heap
allocations at all.
2023-08-09 21:06:54 -06:00

51 lines
1.7 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/TypedTransfer.h>
#include <Kernel/Tasks/Process.h>
#include <Kernel/Version.h>
namespace Kernel {
#if ARCH(X86_64)
# define UNAME_MACHINE "x86_64"
#elif ARCH(AARCH64)
# define UNAME_MACHINE "AArch64"
#else
# error Unknown architecture
#endif
ErrorOr<FlatPtr> Process::sys$uname(Userspace<utsname*> user_buf)
{
VERIFY_NO_PROCESS_BIG_LOCK(this);
TRY(require_promise(Pledge::stdio));
utsname buf {
"SerenityOS",
{}, // Hostname, filled in below.
{}, // "Release" (1.0-dev), filled in below.
{}, // "Revision" (git commit hash), filled in below.
UNAME_MACHINE
};
auto version_string = TRY(KString::formatted("{}.{}-dev", SERENITY_MAJOR_REVISION, SERENITY_MINOR_REVISION));
AK::TypedTransfer<u8>::copy(reinterpret_cast<u8*>(buf.release), version_string->bytes().data(), min(version_string->length(), UTSNAME_ENTRY_LEN - 1));
AK::TypedTransfer<u8>::copy(reinterpret_cast<u8*>(buf.version), SERENITY_VERSION.bytes().data(), min(SERENITY_VERSION.length(), UTSNAME_ENTRY_LEN - 1));
hostname().with_shared([&](auto const& name) {
auto name_length = name.representable_view().length();
VERIFY(name_length <= (UTSNAME_ENTRY_LEN - 1));
AK::TypedTransfer<char>::copy(reinterpret_cast<char*>(buf.nodename), name.representable_view().characters_without_null_termination(), name_length);
buf.nodename[name_length] = '\0';
});
TRY(copy_to_user(user_buf, &buf));
return 0;
}
}