[libc-commits] [libc] [libc] Add getpwent_r entrypoint (PR #226966)
Jeff Bailey via libc-commits
libc-commits at lists.llvm.org
Mon Sep 28 04:44:58 PDT 2026
https://github.com/kaladron created https://github.com/llvm/llvm-project/pull/226966
Add the reentrant password database iteration entrypoint getpwent_r.
getpwent_r reads the next password database record from the stream into the caller-supplied struct passwd and buffer, returning 0 on success, ENOENT at end-of-file, or an error number (such as ERANGE) on failure. When a record exceeds the caller buffer size, FlatFileDatabase::getnext rewinds the stream to the beginning of that record so that a subsequent retry with a larger buffer reads the same entry.
* Add getpwent_r entrypoint and pwd::read_next fixed-buffer overload
* Rewind stream on ERANGE in FlatFileDatabase::getnext(EntryType *, span<char>)
* Define getpwent_r in include/pwd.yaml and Linux entrypoints.txt
* Add unit tests for getpwent_r
Assisted-by: Automated tooling, human reviewed.
>From ca5fddc744a6f6eb50f2d027403968b6345b9179 Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Tue, 22 Sep 2026 20:40:10 +0100
Subject: [PATCH] [libc] Add getpwent_r entrypoint
Add the reentrant password database iteration entrypoint getpwent_r.
getpwent_r reads the next password database record from the stream into
the caller-supplied struct passwd and buffer, returning 0 on success,
ENOENT at end-of-file, or an error number (such as ERANGE) on failure.
When a record exceeds the caller buffer size, FlatFileDatabase::getnext
rewinds the stream to the beginning of that record so that a subsequent
retry with a larger buffer reads the same entry.
* Add getpwent_r entrypoint and pwd::read_next fixed-buffer overload
* Rewind stream on ERANGE in FlatFileDatabase::getnext(EntryType *, span<char>)
* Define getpwent_r in include/pwd.yaml and Linux entrypoints.txt
* Add unit tests for getpwent_r
Assisted-by: Automated tooling, human reviewed.
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/arm/entrypoints.txt | 1 +
libc/config/linux/i386/entrypoints.txt | 1 +
libc/config/linux/riscv/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/include/pwd.yaml | 10 ++
libc/src/__support/pwd/flat_file_db.h | 16 +-
libc/src/pwd/CMakeLists.txt | 17 ++
libc/src/pwd/getpwent_r.cpp | 46 ++++++
libc/src/pwd/getpwent_r.h | 28 ++++
libc/src/pwd/pwd_utils.cpp | 4 +
libc/src/pwd/pwd_utils.h | 4 +
libc/test/src/pwd/CMakeLists.txt | 26 +++
libc/test/src/pwd/getpwent_r_test.cpp | 188 ++++++++++++++++++++++
14 files changed, 341 insertions(+), 3 deletions(-)
create mode 100644 libc/src/pwd/getpwent_r.cpp
create mode 100644 libc/src/pwd/getpwent_r.h
create mode 100644 libc/test/src/pwd/getpwent_r_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 15a5367f5fc95..e2402b1264931 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -62,6 +62,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# pwd.h entrypoints
libc.src.pwd.endpwent
libc.src.pwd.getpwent
+ libc.src.pwd.getpwent_r
libc.src.pwd.getpwnam
libc.src.pwd.getpwnam_r
libc.src.pwd.getpwuid
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 1441146393c5f..f2a7f8e182658 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -45,6 +45,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# pwd.h entrypoints
libc.src.pwd.endpwent
libc.src.pwd.getpwent
+ libc.src.pwd.getpwent_r
libc.src.pwd.getpwnam
libc.src.pwd.getpwnam_r
libc.src.pwd.getpwuid
diff --git a/libc/config/linux/i386/entrypoints.txt b/libc/config/linux/i386/entrypoints.txt
index b58956c166686..3ee6e68b466e8 100644
--- a/libc/config/linux/i386/entrypoints.txt
+++ b/libc/config/linux/i386/entrypoints.txt
@@ -14,6 +14,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# pwd.h entrypoints
libc.src.pwd.endpwent
libc.src.pwd.getpwent
+ libc.src.pwd.getpwent_r
libc.src.pwd.getpwnam
libc.src.pwd.getpwnam_r
libc.src.pwd.getpwuid
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 8f4dded27de68..b90ab97416a41 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -81,6 +81,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# pwd.h entrypoints
libc.src.pwd.endpwent
libc.src.pwd.getpwent
+ libc.src.pwd.getpwent_r
libc.src.pwd.getpwnam
libc.src.pwd.getpwnam_r
libc.src.pwd.getpwuid
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 8ca73cc82cc2d..211476af8f712 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -81,6 +81,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# pwd.h entrypoints
libc.src.pwd.endpwent
libc.src.pwd.getpwent
+ libc.src.pwd.getpwent_r
libc.src.pwd.getpwnam
libc.src.pwd.getpwnam_r
libc.src.pwd.getpwuid
diff --git a/libc/include/pwd.yaml b/libc/include/pwd.yaml
index 9301307d22d3a..f91fec9f33263 100644
--- a/libc/include/pwd.yaml
+++ b/libc/include/pwd.yaml
@@ -1,6 +1,7 @@
header: pwd.h
standards:
- posix
+ - gnu
types:
- type_name: struct_passwd
- type_name: gid_t
@@ -14,6 +15,15 @@ functions:
- posix
return_type: struct passwd *
arguments: []
+ - name: getpwent_r
+ standards:
+ - gnu
+ return_type: int
+ arguments:
+ - type: struct passwd *
+ - type: char *
+ - type: size_t
+ - type: struct passwd **
- name: setpwent
standards:
- posix
diff --git a/libc/src/__support/pwd/flat_file_db.h b/libc/src/__support/pwd/flat_file_db.h
index 319197872cd3b..4c6f01a5225e5 100644
--- a/libc/src/__support/pwd/flat_file_db.h
+++ b/libc/src/__support/pwd/flat_file_db.h
@@ -216,10 +216,13 @@ template <typename EntryType> class FlatFileDatabase {
// Reads and parses the next record from the database into a fixed buffer.
// Returns true if an entry was read, false if EOF was reached, or an Error on
// failure. Blank lines are skipped. A record that does not fit in the buffer
- // is reported as ERANGE.
+ // is reported as ERANGE and leaves the stream positioned at the start of
+ // that record so the caller can retry with a larger buffer.
LIBC_INLINE ErrorOr<bool> getnext(EntryType *entry, cpp::span<char> buffer) {
if (!entry)
return Error(EINVAL);
+ if (buffer.size() < 2)
+ return Error(ERANGE);
if (!file) {
auto res = setdb();
@@ -228,6 +231,7 @@ template <typename EntryType> class FlatFileDatabase {
}
while (true) {
+ auto pos_or = file->tell();
auto result = read_line(file, buffer);
if (!result.has_value())
return Error(result.error());
@@ -240,16 +244,22 @@ template <typename EntryType> class FlatFileDatabase {
if (res.bytes_read == 0)
continue;
- if (res.truncated)
+ if (res.truncated) {
+ if (pos_or.has_value())
+ file->seek(pos_or.value(), SEEK_SET);
return Error(ERANGE);
+ }
// Slicing at bytes_read + 1 includes the terminating null byte written
// by read_line; the remainder of the buffer serves as scratch space.
auto parse_res =
parse_line<EntryType>(buffer.first(res.bytes_read + 1),
buffer.subspan(res.bytes_read + 1), entry);
- if (!parse_res.has_value())
+ if (!parse_res.has_value()) {
+ if (parse_res.error() == ERANGE && pos_or.has_value())
+ file->seek(pos_or.value(), SEEK_SET);
return Error(parse_res.error());
+ }
return true;
}
}
diff --git a/libc/src/pwd/CMakeLists.txt b/libc/src/pwd/CMakeLists.txt
index 9ab145a1e3592..0e9097ad33faa 100644
--- a/libc/src/pwd/CMakeLists.txt
+++ b/libc/src/pwd/CMakeLists.txt
@@ -16,6 +16,23 @@ add_entrypoint_object(
.pwd_utils
)
+add_entrypoint_object(
+ getpwent_r
+ SRCS
+ getpwent_r.cpp
+ HDRS
+ getpwent_r.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.types.size_t
+ libc.hdr.types.struct_passwd
+ libc.src.__support.CPP.span
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.null_check
+ .pwd_utils
+)
+
add_entrypoint_object(
setpwent
SRCS
diff --git a/libc/src/pwd/getpwent_r.cpp b/libc/src/pwd/getpwent_r.cpp
new file mode 100644
index 0000000000000..f60b5670943cd
--- /dev/null
+++ b/libc/src/pwd/getpwent_r.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation of getpwent_r.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/pwd/getpwent_r.h"
+#include "hdr/errno_macros.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/struct_passwd.h"
+#include "src/__support/CPP/span.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+#include "src/pwd/pwd_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, getpwent_r,
+ (struct passwd * pwbuf, char *buf, size_t buflen,
+ struct passwd **pwbufp)) {
+ LIBC_CRASH_ON_NULLPTR(pwbuf);
+ LIBC_CRASH_ON_NULLPTR(buf);
+ LIBC_CRASH_ON_NULLPTR(pwbufp);
+
+ *pwbufp = nullptr;
+
+ const auto res = pwd::read_next(pwbuf, cpp::span<char>(buf, buflen));
+ if (!res.has_value())
+ return res.error();
+
+ if (!res.value())
+ return ENOENT;
+
+ *pwbufp = pwbuf;
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/pwd/getpwent_r.h b/libc/src/pwd/getpwent_r.h
new file mode 100644
index 0000000000000..d3c191a84afb6
--- /dev/null
+++ b/libc/src/pwd/getpwent_r.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Internal header for getpwent_r.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_PWD_GETPWENT_R_H
+#define LLVM_LIBC_SRC_PWD_GETPWENT_R_H
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/struct_passwd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen,
+ struct passwd **pwbufp);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_PWD_GETPWENT_R_H
diff --git a/libc/src/pwd/pwd_utils.cpp b/libc/src/pwd/pwd_utils.cpp
index 8d865c3a0fc45..56aa34fd4733c 100644
--- a/libc/src/pwd/pwd_utils.cpp
+++ b/libc/src/pwd/pwd_utils.cpp
@@ -88,6 +88,10 @@ ErrorOr<struct passwd *> read_next() {
return &pwd_entry;
}
+ErrorOr<bool> read_next(struct passwd *pwd, cpp::span<char> buffer) {
+ return db.getnext(pwd, buffer);
+}
+
namespace {
// The lookups are shared between the caller-supplied fixed buffer used by the
diff --git a/libc/src/pwd/pwd_utils.h b/libc/src/pwd/pwd_utils.h
index b3d16f49893b5..ee8af26946ef2 100644
--- a/libc/src/pwd/pwd_utils.h
+++ b/libc/src/pwd/pwd_utils.h
@@ -112,6 +112,10 @@ ErrorOr<void> close();
// Reads the next entry from the password database.
ErrorOr<struct passwd *> read_next();
+// Reads the next entry from the password database into a caller-supplied
+// buffer.
+ErrorOr<bool> read_next(struct passwd *pwd, cpp::span<char> buffer);
+
// Searches for a password entry matching the given username using the
// static process-global buffer.
ErrorOr<struct passwd *> find_by_name(cpp::string_view name);
diff --git a/libc/test/src/pwd/CMakeLists.txt b/libc/test/src/pwd/CMakeLists.txt
index f60bf7016b1e5..11573806c602f 100644
--- a/libc/test/src/pwd/CMakeLists.txt
+++ b/libc/test/src/pwd/CMakeLists.txt
@@ -40,6 +40,32 @@ add_libc_test(
libc.test.UnitTest.ErrnoCheckingTest
)
+add_libc_test(
+ getpwent_r_test
+ SUITE
+ libc_pwd_unittests
+ HDRS
+ pwd_test_utils.h
+ SRCS
+ getpwent_r_test.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.signal_macros
+ libc.hdr.types.gid_t
+ libc.hdr.types.size_t
+ libc.hdr.types.struct_passwd
+ libc.hdr.types.uid_t
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+ libc.src.pwd.endpwent
+ libc.src.pwd.getpwent_r
+ libc.src.pwd.pwd_utils
+ libc.src.pwd.setpwent
+ libc.src.stdio.remove
+ libc.src.string.string_utils
+ libc.test.UnitTest.ErrnoCheckingTest
+)
+
add_libc_test(
getpwnam_test
SUITE
diff --git a/libc/test/src/pwd/getpwent_r_test.cpp b/libc/test/src/pwd/getpwent_r_test.cpp
new file mode 100644
index 0000000000000..bf9773cef5c88
--- /dev/null
+++ b/libc/test/src/pwd/getpwent_r_test.cpp
@@ -0,0 +1,188 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 getpwent_r.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "hdr/signal_macros.h"
+#include "hdr/types/gid_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/struct_passwd.h"
+#include "hdr/types/uid_t.h"
+#include "pwd_test_utils.h"
+#include "src/pwd/endpwent.h"
+#include "src/pwd/getpwent_r.h"
+#include "src/pwd/pwd_utils.h"
+#include "src/pwd/setpwent.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcGetpwentRTest = LlvmLibcPwdTest;
+
+TEST_F(LlvmLibcGetpwentRTest, SuccessAndEofReturnsEnoent) {
+ const char *content = "root:x:0:0:root:/root:/bin/bash\n"
+ "bin:x:1:1:bin:/bin:/sbin/nologin\n";
+ ScopedPasswdFile test_file(
+ libc_make_test_file_path("getpwent_r_success.test"), content);
+
+ struct passwd pwd;
+ char buffer[256];
+ struct passwd *result = nullptr;
+
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, buffer, sizeof(buffer), &result),
+ 0);
+ ASSERT_EQ(result, &pwd);
+ EXPECT_STREQ(pwd.pw_name, "root");
+ EXPECT_STREQ(pwd.pw_passwd, "x");
+ EXPECT_EQ(pwd.pw_uid, static_cast<uid_t>(0));
+ EXPECT_EQ(pwd.pw_gid, static_cast<gid_t>(0));
+ EXPECT_STREQ(pwd.pw_gecos, "root");
+ EXPECT_STREQ(pwd.pw_dir, "/root");
+ EXPECT_STREQ(pwd.pw_shell, "/bin/bash");
+
+ result = nullptr;
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, buffer, sizeof(buffer), &result),
+ 0);
+ ASSERT_EQ(result, &pwd);
+ EXPECT_STREQ(pwd.pw_name, "bin");
+ EXPECT_EQ(pwd.pw_uid, static_cast<uid_t>(1));
+
+ result = reinterpret_cast<struct passwd *>(0xdeadbeef);
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, buffer, sizeof(buffer), &result),
+ ENOENT);
+ EXPECT_EQ(result, static_cast<struct passwd *>(nullptr));
+}
+
+TEST_F(LlvmLibcGetpwentRTest, SetpwentRewindsAndEndpwentReopens) {
+ const char *content = "root:x:0:0:root:/root:/bin/bash\n"
+ "bin:x:1:1:bin:/bin:/sbin/nologin\n";
+ ScopedPasswdFile test_file(libc_make_test_file_path("getpwent_r_rewind.test"),
+ content);
+
+ struct passwd pwd;
+ char buffer[256];
+ struct passwd *result = nullptr;
+
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, buffer, sizeof(buffer), &result),
+ 0);
+ ASSERT_EQ(result, &pwd);
+ EXPECT_STREQ(pwd.pw_name, "root");
+
+ LIBC_NAMESPACE::setpwent();
+ result = nullptr;
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, buffer, sizeof(buffer), &result),
+ 0);
+ ASSERT_EQ(result, &pwd);
+ EXPECT_STREQ(pwd.pw_name, "root");
+
+ LIBC_NAMESPACE::endpwent();
+ result = nullptr;
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, buffer, sizeof(buffer), &result),
+ 0);
+ ASSERT_EQ(result, &pwd);
+ EXPECT_STREQ(pwd.pw_name, "root");
+}
+
+TEST_F(LlvmLibcGetpwentRTest, BufferTooSmallAndRetryReadsSameEntry) {
+ const char *content = "root:x:0:0:root:/root:/bin/bash\n"
+ "bin:x:1:1:bin:/bin:/sbin/nologin\n";
+ ScopedPasswdFile test_file(libc_make_test_file_path("getpwent_r_erange.test"),
+ content);
+
+ struct passwd pwd;
+ char small_buf[8];
+ struct passwd *result = reinterpret_cast<struct passwd *>(0xdeadbeef);
+
+ ASSERT_EQ(
+ LIBC_NAMESPACE::getpwent_r(&pwd, small_buf, sizeof(small_buf), &result),
+ ERANGE);
+ EXPECT_EQ(result, static_cast<struct passwd *>(nullptr));
+
+ result = reinterpret_cast<struct passwd *>(0xdeadbeef);
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, small_buf, 0, &result), ERANGE);
+ EXPECT_EQ(result, static_cast<struct passwd *>(nullptr));
+
+ // Retrying with a sufficiently large buffer must read the first record
+ // ("root") rather than skipping past it.
+ char large_buf[256];
+ ASSERT_EQ(
+ LIBC_NAMESPACE::getpwent_r(&pwd, large_buf, sizeof(large_buf), &result),
+ 0);
+ ASSERT_EQ(result, &pwd);
+ EXPECT_STREQ(pwd.pw_name, "root");
+}
+
+TEST_F(LlvmLibcGetpwentRTest, BlankLinesSkipped) {
+ const char *content = "\nroot:x:0:0:root:/root:/bin/bash\n\n\n"
+ "bin:x:1:1:bin:/bin:/sbin/nologin\n\n";
+ ScopedPasswdFile test_file(libc_make_test_file_path("getpwent_r_blank.test"),
+ content);
+
+ struct passwd pwd;
+ char buffer[256];
+ struct passwd *result = nullptr;
+
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, buffer, sizeof(buffer), &result),
+ 0);
+ ASSERT_EQ(result, &pwd);
+ EXPECT_STREQ(pwd.pw_name, "root");
+
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, buffer, sizeof(buffer), &result),
+ 0);
+ ASSERT_EQ(result, &pwd);
+ EXPECT_STREQ(pwd.pw_name, "bin");
+
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, buffer, sizeof(buffer), &result),
+ ENOENT);
+ EXPECT_EQ(result, static_cast<struct passwd *>(nullptr));
+}
+
+TEST_F(LlvmLibcGetpwentRTest, FileOpenFailure) {
+ const auto missing_path =
+ libc_make_test_file_path("nonexistent_dir/getpwent_r_missing.test");
+ LIBC_NAMESPACE::pwd::TESTONLY_set_passwd_path(missing_path);
+
+ struct passwd pwd;
+ char buffer[256];
+ struct passwd *result = reinterpret_cast<struct passwd *>(0xdeadbeef);
+
+ ASSERT_EQ(LIBC_NAMESPACE::getpwent_r(&pwd, buffer, sizeof(buffer), &result),
+ ENOENT);
+ EXPECT_EQ(result, static_cast<struct passwd *>(nullptr));
+}
+
+#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_TESTS_CAN_USE_MPFR)
+TEST_F(LlvmLibcGetpwentRTest, NullPointerCrash) {
+ struct passwd pwd;
+ char buffer[256];
+ struct passwd *result = nullptr;
+ ASSERT_DEATH(
+ [=]() {
+ LIBC_NAMESPACE::getpwent_r(nullptr, const_cast<char *>(buffer),
+ sizeof(buffer),
+ const_cast<struct passwd **>(&result));
+ },
+ WITH_SIGNAL(-1));
+ ASSERT_DEATH(
+ [=]() {
+ LIBC_NAMESPACE::getpwent_r(const_cast<struct passwd *>(&pwd), nullptr,
+ sizeof(buffer),
+ const_cast<struct passwd **>(&result));
+ },
+ WITH_SIGNAL(-1));
+ ASSERT_DEATH(
+ [=]() {
+ LIBC_NAMESPACE::getpwent_r(const_cast<struct passwd *>(&pwd),
+ const_cast<char *>(buffer), sizeof(buffer),
+ nullptr);
+ },
+ WITH_SIGNAL(-1));
+}
+#endif // LIBC_ADD_NULL_CHECKS && !LIBC_TESTS_CAN_USE_MPFR
More information about the libc-commits
mailing list