[libc-commits] [libc] [libc] Implement getentropy in sys/random (PR #226501)
via libc-commits
libc-commits at lists.llvm.org
Fri Sep 25 07:08:02 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Aman Maurya (amanmaurya92)
<details>
<summary>Changes</summary>
Implement the standard POSIX.1-2024 function `getentropy` in `<sys/random.h>`, bringing `<sys/random.h>` to 100% completion.
Fixes #<!-- -->226458
---
Full diff: https://github.com/llvm/llvm-project/pull/226501.diff
11 Files Affected:
- (modified) libc/config/linux/aarch64/entrypoints.txt (+1)
- (modified) libc/config/linux/riscv/entrypoints.txt (+1)
- (modified) libc/config/linux/x86_64/entrypoints.txt (+1)
- (modified) libc/config/linux/x86_64/exclude.txt (+1)
- (modified) libc/include/sys/random.yaml (+1)
- (modified) libc/src/sys/random/CMakeLists.txt (+7)
- (added) libc/src/sys/random/getentropy.h (+26)
- (modified) libc/src/sys/random/linux/CMakeLists.txt (+15)
- (added) libc/src/sys/random/linux/getentropy.cpp (+49)
- (modified) libc/test/src/sys/random/linux/CMakeLists.txt (+14)
- (added) libc/test/src/sys/random/linux/getentropy_test.cpp (+75)
``````````diff
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 15a5367f5fc95d..e337677f3a30d0 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -322,6 +322,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/random.h entrypoints
libc.src.sys.random.getrandom
+ libc.src.sys.random.getentropy
# sys/resource.h entrypoints
libc.src.sys.resource.getpriority
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 8f4dded27de68c..c2a71b8c99169d 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -353,6 +353,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/random.h entrypoints
libc.src.sys.random.getrandom
+ libc.src.sys.random.getentropy
# sys/resource.h entrypoints
libc.src.sys.resource.getpriority
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 8ca73cc82cc2db..ea73b7de8b97e0 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -353,6 +353,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/random.h entrypoints
libc.src.sys.random.getrandom
+ libc.src.sys.random.getentropy
# sys/resource.h entrypoints
libc.src.sys.resource.getpriority
diff --git a/libc/config/linux/x86_64/exclude.txt b/libc/config/linux/x86_64/exclude.txt
index 31b60a9c3497cb..e23160255bc669 100644
--- a/libc/config/linux/x86_64/exclude.txt
+++ b/libc/config/linux/x86_64/exclude.txt
@@ -16,6 +16,7 @@ if(NOT has_sys_random)
if(NOT LLVM_LIBC_FULL_BUILD)
list(APPEND TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS
libc.src.sys.random.getrandom
+ libc.src.sys.random.getentropy
)
endif()
endif()
diff --git a/libc/include/sys/random.yaml b/libc/include/sys/random.yaml
index c57a6fe7ccc75f..8c5fcc8846c609 100644
--- a/libc/include/sys/random.yaml
+++ b/libc/include/sys/random.yaml
@@ -19,6 +19,7 @@ functions:
- name: getentropy
standards:
- gnu
+ - posix
return_type: int
arguments:
- type: void *
diff --git a/libc/src/sys/random/CMakeLists.txt b/libc/src/sys/random/CMakeLists.txt
index 2291a86934a0fe..526b12632100e1 100644
--- a/libc/src/sys/random/CMakeLists.txt
+++ b/libc/src/sys/random/CMakeLists.txt
@@ -8,3 +8,10 @@ add_entrypoint_object(
DEPENDS
.${LIBC_TARGET_OS}.getrandom
)
+
+add_entrypoint_object(
+ getentropy
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.getentropy
+)
diff --git a/libc/src/sys/random/getentropy.h b/libc/src/sys/random/getentropy.h
new file mode 100644
index 00000000000000..0cef2b83729a51
--- /dev/null
+++ b/libc/src/sys/random/getentropy.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Declaration of the getentropy function.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_RANDOM_GETENTROPY_H
+#define LLVM_LIBC_SRC_SYS_RANDOM_GETENTROPY_H
+
+#include "hdr/types/size_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int getentropy(void *buffer, size_t length);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_RANDOM_GETENTROPY_H
diff --git a/libc/src/sys/random/linux/CMakeLists.txt b/libc/src/sys/random/linux/CMakeLists.txt
index 249de1025b173a..8eed6410538a6c 100644
--- a/libc/src/sys/random/linux/CMakeLists.txt
+++ b/libc/src/sys/random/linux/CMakeLists.txt
@@ -10,3 +10,18 @@ add_entrypoint_object(
libc.src.__support.OSUtil.linux.syscall_wrappers.getrandom
libc.src.errno.errno
)
+
+add_entrypoint_object(
+ getentropy
+ SRCS
+ getentropy.cpp
+ HDRS
+ ../getentropy.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.types.size_t
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.OSUtil.linux.syscall_wrappers.getrandom
+ libc.src.errno.errno
+)
diff --git a/libc/src/sys/random/linux/getentropy.cpp b/libc/src/sys/random/linux/getentropy.cpp
new file mode 100644
index 00000000000000..42e2fa9f6ee429
--- /dev/null
+++ b/libc/src/sys/random/linux/getentropy.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of the getentropy function.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/random/getentropy.h"
+
+#include "hdr/errno_macros.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/getrandom.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, getentropy, (void *buffer, size_t length)) {
+ constexpr size_t MAX_BYTES = 256;
+ if (length > MAX_BYTES) {
+ libc_errno = EIO;
+ return -1;
+ }
+
+ auto *buf_ptr = reinterpret_cast<char *>(buffer);
+ size_t remaining = length;
+ while (remaining > 0) {
+ auto result = linux_syscalls::getrandom(buf_ptr, remaining, 0);
+ if (!result.has_value()) {
+ if (result.error() == EINTR)
+ continue;
+ libc_errno = static_cast<int>(result.error());
+ return -1;
+ }
+ ssize_t bytes_read = result.value();
+ buf_ptr += bytes_read;
+ remaining -= static_cast<size_t>(bytes_read);
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/sys/random/linux/CMakeLists.txt b/libc/test/src/sys/random/linux/CMakeLists.txt
index f9983d9d4037d9..c6600c9470ef41 100644
--- a/libc/test/src/sys/random/linux/CMakeLists.txt
+++ b/libc/test/src/sys/random/linux/CMakeLists.txt
@@ -14,3 +14,17 @@ add_libc_test(
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)
+
+add_libc_test(
+ getentropy_test
+ SUITE
+ libc_sys_random_unittests
+ SRCS
+ getentropy_test.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.src.errno.errno
+ libc.src.sys.random.getentropy
+ libc.test.UnitTest.ErrnoCheckingTest
+ libc.test.UnitTest.ErrnoSetterMatcher
+)
diff --git a/libc/test/src/sys/random/linux/getentropy_test.cpp b/libc/test/src/sys/random/linux/getentropy_test.cpp
new file mode 100644
index 00000000000000..9fdda16ea1db7e
--- /dev/null
+++ b/libc/test/src/sys/random/linux/getentropy_test.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Unit tests for the getentropy function.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/random/getentropy.h"
+
+#include "hdr/errno_macros.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcGetEntropyTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcGetEntropyTest, ZeroLength) {
+ char buffer[16]{};
+ ASSERT_THAT(LIBC_NAMESPACE::getentropy(buffer, 0), Succeeds<int>(0));
+ ASSERT_THAT(LIBC_NAMESPACE::getentropy(nullptr, 0), Succeeds<int>(0));
+}
+
+TEST_F(LlvmLibcGetEntropyTest, LengthTooLarge) {
+ char buffer[257]{};
+ ASSERT_THAT(LIBC_NAMESPACE::getentropy(buffer, 257), Fails<int>(EIO));
+}
+
+TEST_F(LlvmLibcGetEntropyTest, InvalidBuffer) {
+ ASSERT_THAT(LIBC_NAMESPACE::getentropy(nullptr, 16), Fails<int>(EFAULT));
+}
+
+TEST_F(LlvmLibcGetEntropyTest, SmallBuffer) {
+ char buffer[16]{};
+ ASSERT_THAT(LIBC_NAMESPACE::getentropy(buffer, sizeof(buffer)),
+ Succeeds<int>(0));
+}
+
+TEST_F(LlvmLibcGetEntropyTest, MaxBuffer) {
+ constexpr size_t MAX_BYTES = 256;
+ char buffer[MAX_BYTES]{};
+ ASSERT_THAT(LIBC_NAMESPACE::getentropy(buffer, MAX_BYTES), Succeeds<int>(0));
+
+ bool all_zeros = true;
+ for (size_t i = 0; i < MAX_BYTES; ++i) {
+ if (buffer[i] != 0) {
+ all_zeros = false;
+ break;
+ }
+ }
+ ASSERT_FALSE(all_zeros);
+}
+
+TEST_F(LlvmLibcGetEntropyTest, DifferentOutputs) {
+ constexpr size_t BUF_SIZE = 32;
+ char buf1[BUF_SIZE]{};
+ char buf2[BUF_SIZE]{};
+ ASSERT_THAT(LIBC_NAMESPACE::getentropy(buf1, BUF_SIZE), Succeeds<int>(0));
+ ASSERT_THAT(LIBC_NAMESPACE::getentropy(buf2, BUF_SIZE), Succeeds<int>(0));
+
+ bool differ = false;
+ for (size_t i = 0; i < BUF_SIZE; ++i) {
+ if (buf1[i] != buf2[i]) {
+ differ = true;
+ break;
+ }
+ }
+ ASSERT_TRUE(differ);
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/226501
More information about the libc-commits
mailing list