[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