diff --git a/libc/src/__support/HashTable/CMakeLists.txt b/libc/src/__support/HashTable/CMakeLists.txt index a1de0680cc7d5..698b8d0dfa68b 100644 --- a/libc/src/__support/HashTable/CMakeLists.txt +++ b/libc/src/__support/HashTable/CMakeLists.txt @@ -15,7 +15,8 @@ if (NOT ${getrandom_index} EQUAL -1) message(STATUS "Using getrandom for hashtable randomness") set(randomness_compile_flags -DLIBC_HASHTABLE_USE_GETRANDOM) set(randomness_extra_depends - libc.src.sys.random.getrandom libc.src.errno.errno) + libc.src.__support.OSUtil.linux.getrandom + libc.hdr.errno_macros) endif() diff --git a/libc/src/__support/HashTable/randomness.h b/libc/src/__support/HashTable/randomness.h index 6b58a4125f785..7e54c9aa6ad1f 100644 --- a/libc/src/__support/HashTable/randomness.h +++ b/libc/src/__support/HashTable/randomness.h @@ -14,8 +14,8 @@ #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" #if defined(LIBC_HASHTABLE_USE_GETRANDOM) -#include "src/__support/libc_errno.h" -#include "src/sys/random/getrandom.h" +#include "hdr/errno_macros.h" +#include "src/__support/OSUtil/linux/getrandom.h" #endif namespace LIBC_NAMESPACE_DECL { @@ -35,20 +35,18 @@ LIBC_INLINE uint64_t next_random_seed() { entropy[0] = reinterpret_cast(&entropy); entropy[1] = reinterpret_cast(&state); #if defined(LIBC_HASHTABLE_USE_GETRANDOM) - int errno_backup = libc_errno; size_t count = sizeof(entropy); uint8_t *buffer = reinterpret_cast(entropy); while (count > 0) { - ssize_t len = getrandom(buffer, count, 0); - if (len == -1) { - if (libc_errno == ENOSYS) + auto len = internal::getrandom(buffer, count, 0); + if (!len.has_value()) { + if (len.error() == ENOSYS) break; continue; } - count -= len; - buffer += len; + count -= len.value(); + buffer += len.value(); } - libc_errno = errno_backup; #endif state.update(&entropy, sizeof(entropy)); } diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt index 4681d8c2bb73c..f303e54ce7b3b 100644 --- a/libc/src/__support/OSUtil/linux/CMakeLists.txt +++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt @@ -24,6 +24,19 @@ add_object_library( libc.include.sys_syscall ) +add_header_library( + getrandom + HDRS + getrandom.h + DEPENDS + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config + libc.hdr.types.ssize_t + libc.include.sys_syscall +) + add_header_library( vdso_sym HDRS diff --git a/libc/src/__support/OSUtil/linux/getrandom.h b/libc/src/__support/OSUtil/linux/getrandom.h new file mode 100644 index 0000000000000..793639472fee7 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/getrandom.h @@ -0,0 +1,35 @@ +//===------------ Implementation of getrandom function ----------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_GETRANDOM_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_GETRANDOM_H + +#include "hdr/types/ssize_t.h" +#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace internal { + +LIBC_INLINE static ErrorOr getrandom(void *buf, size_t buflen, + unsigned int flags) { + ssize_t ret = + LIBC_NAMESPACE::syscall_impl(SYS_getrandom, buf, buflen, flags); + if (ret < 0) { + return Error(-static_cast(ret)); + } + return ret; +} + +} // namespace internal +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_GETRANDOM_H diff --git a/libc/src/sys/random/linux/getrandom.cpp b/libc/src/sys/random/linux/getrandom.cpp index 0b8471ed8b374..4a95bddfa428e 100644 --- a/libc/src/sys/random/linux/getrandom.cpp +++ b/libc/src/sys/random/linux/getrandom.cpp @@ -8,24 +8,23 @@ #include "src/sys/random/getrandom.h" +#include "src/__support/OSUtil/linux/getrandom.h" #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" - +#include "src/__support/error_or.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" -#include // For syscall numbers. namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(ssize_t, getrandom, (void *buf, size_t buflen, unsigned int flags)) { - ssize_t ret = - LIBC_NAMESPACE::syscall_impl(SYS_getrandom, buf, buflen, flags); - if (ret < 0) { - libc_errno = static_cast(-ret); + auto rand = internal::getrandom(buf, buflen, flags); + if (!rand.has_value()) { + libc_errno = static_cast(rand.error()); return -1; } - return ret; + return rand.value(); } } // namespace LIBC_NAMESPACE_DECL