From 638f37821de28b648a6582cb71cf820f3873bd41 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Tue, 25 Aug 2026 21:31:05 +0000 Subject: [PATCH 1/3] [libc] Add stub for confstr POSIX defines confstr as returning strings for various macros (see: https://pubs.opengroup.org/onlinepubs/9799919799/functions/confstr.html) This PR adds an implementation as experimental that always returns that there's no valid string. --- libc/config/linux/aarch64/entrypoints.txt | 5 ++++ libc/config/linux/arm/entrypoints.txt | 5 ++++ libc/config/linux/riscv/entrypoints.txt | 5 ++++ libc/config/linux/x86_64/entrypoints.txt | 5 ++++ libc/include/unistd.yaml | 8 ++++++ libc/src/unistd/CMakeLists.txt | 13 +++++++++ libc/src/unistd/confstr.cpp | 24 ++++++++++++++++ libc/src/unistd/confstr.h | 27 ++++++++++++++++++ libc/test/src/unistd/CMakeLists.txt | 11 ++++++++ libc/test/src/unistd/confstr_test.cpp | 34 +++++++++++++++++++++++ 10 files changed, 137 insertions(+) create mode 100644 libc/src/unistd/confstr.cpp create mode 100644 libc/src/unistd/confstr.h create mode 100644 libc/test/src/unistd/confstr_test.cpp diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index dfba85299c4da..8008a7776005e 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -1373,6 +1373,11 @@ if(LLVM_LIBC_FULL_BUILD) endif() if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS) + list(APPEND TARGET_LIBC_ENTRYPOINTS + # unistd.h entrypoints + libc.src.unistd.confstr + ) + if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS # net/if.h entrypoints diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt index 1f8c64bcae127..0c7d4085534f3 100644 --- a/libc/config/linux/arm/entrypoints.txt +++ b/libc/config/linux/arm/entrypoints.txt @@ -661,6 +661,11 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS ) if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS) + list(APPEND TARGET_LIBC_ENTRYPOINTS + # unistd.h entrypoints + libc.src.unistd.confstr + ) + if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS # regex.h entrypoints diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 507670684930c..c049c280b13ac 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -1591,6 +1591,11 @@ if(LLVM_LIBC_FULL_BUILD) endif() if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS) + list(APPEND TARGET_LIBC_ENTRYPOINTS + # unistd.h entrypoints + libc.src.unistd.confstr + ) + if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS # net/if.h entrypoints diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 7420a4db3330c..1b6c678a5dc1c 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -1604,6 +1604,11 @@ if(LLVM_LIBC_FULL_BUILD) endif() if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS) + list(APPEND TARGET_LIBC_ENTRYPOINTS + # unistd.h entrypoints + libc.src.unistd.confstr + ) + if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS # net/if.h entrypoints diff --git a/libc/include/unistd.yaml b/libc/include/unistd.yaml index 0d5b5e71cf7f3..d6c0235dd830f 100644 --- a/libc/include/unistd.yaml +++ b/libc/include/unistd.yaml @@ -103,6 +103,14 @@ functions: - type: const char * - type: uid_t - type: gid_t + - name: confstr + standards: + - posix + return_type: size_t + arguments: + - type: int + - type: char * + - type: size_t - name: close standards: - posix diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt index c10ea20681059..6109981b032d2 100644 --- a/libc/src/unistd/CMakeLists.txt +++ b/libc/src/unistd/CMakeLists.txt @@ -47,6 +47,19 @@ add_entrypoint_object( .${LIBC_TARGET_OS}.chown ) +add_entrypoint_object( + confstr + SRCS + confstr.cpp + HDRS + confstr.h + DEPENDS + libc.hdr.types.size_t + libc.hdr.unistd_macros + libc.src.__support.common + libc.src.__support.macros.config +) + add_entrypoint_object( close ALIAS diff --git a/libc/src/unistd/confstr.cpp b/libc/src/unistd/confstr.cpp new file mode 100644 index 0000000000000..3ea3a275928fb --- /dev/null +++ b/libc/src/unistd/confstr.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 confstr +/// +//===----------------------------------------------------------------------===// + +#include "src/unistd/confstr.h" + +#include "hdr/types/size_t.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(size_t, confstr, (int, char *, size_t)) { return 0; } + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/unistd/confstr.h b/libc/src/unistd/confstr.h new file mode 100644 index 0000000000000..1792942e6c101 --- /dev/null +++ b/libc/src/unistd/confstr.h @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 header for confstr +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_UNISTD_CONFSTR_H +#define LLVM_LIBC_SRC_UNISTD_CONFSTR_H + +#include "hdr/types/size_t.h" +#include "hdr/unistd_macros.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +size_t confstr(int name, char *buf, size_t len); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_UNISTD_CONFSTR_H diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt index a220509308bd4..016752bb16289 100644 --- a/libc/test/src/unistd/CMakeLists.txt +++ b/libc/test/src/unistd/CMakeLists.txt @@ -641,6 +641,17 @@ add_libc_test( ) +add_libc_test( + confstr_test + SUITE + libc_unistd_unittests + SRCS + confstr_test.cpp + DEPENDS + libc.hdr.types.size_t + libc.src.unistd.confstr +) + add_libc_test( sysconf_test SUITE diff --git a/libc/test/src/unistd/confstr_test.cpp b/libc/test/src/unistd/confstr_test.cpp new file mode 100644 index 0000000000000..28da2bc521460 --- /dev/null +++ b/libc/test/src/unistd/confstr_test.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +/// Unittests for confstr +/// +//===----------------------------------------------------------------------===// + +#include "src/unistd/confstr.h" + +#include "hdr/types/size_t.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcConfStrTest, Basic) { + char buf[64] = "initial"; + size_t ret = LIBC_NAMESPACE::confstr(0, buf, sizeof(buf)); + EXPECT_EQ(ret, size_t(0)); +} + +TEST(LlvmLibcConfStrTest, NullBufZeroLen) { + size_t ret = LIBC_NAMESPACE::confstr(0, nullptr, 0); + EXPECT_EQ(ret, size_t(0)); +} + +TEST(LlvmLibcConfStrTest, NonExistentConfig) { + char buf[64]; + size_t ret = LIBC_NAMESPACE::confstr(-1, buf, sizeof(buf)); + EXPECT_EQ(ret, size_t(0)); +} From f5b490a54e5c3232e6dbc950585205cf756ad9f0 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Tue, 25 Aug 2026 21:52:54 +0000 Subject: [PATCH 2/3] address comments --- libc/config/linux/aarch64/entrypoints.txt | 6 +----- libc/config/linux/arm/entrypoints.txt | 6 +----- libc/config/linux/riscv/entrypoints.txt | 6 +----- libc/config/linux/x86_64/entrypoints.txt | 6 +----- libc/src/unistd/CMakeLists.txt | 2 ++ libc/src/unistd/confstr.cpp | 7 ++++++- libc/test/src/unistd/CMakeLists.txt | 2 ++ libc/test/src/unistd/confstr_test.cpp | 24 ++++++++++------------- 8 files changed, 24 insertions(+), 35 deletions(-) diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 8008a7776005e..7f3fe0c96c7b1 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -392,6 +392,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.unistd.access libc.src.unistd.chdir libc.src.unistd.chown + libc.src.unistd.confstr libc.src.unistd.close libc.src.unistd.dup libc.src.unistd.dup2 @@ -1373,11 +1374,6 @@ if(LLVM_LIBC_FULL_BUILD) endif() if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS) - list(APPEND TARGET_LIBC_ENTRYPOINTS - # unistd.h entrypoints - libc.src.unistd.confstr - ) - if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS # net/if.h entrypoints diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt index 0c7d4085534f3..4adc554ea36cb 100644 --- a/libc/config/linux/arm/entrypoints.txt +++ b/libc/config/linux/arm/entrypoints.txt @@ -228,6 +228,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.unistd.access libc.src.unistd.chdir libc.src.unistd.chown + libc.src.unistd.confstr libc.src.unistd.close libc.src.unistd.dup libc.src.unistd.dup2 @@ -661,11 +662,6 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS ) if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS) - list(APPEND TARGET_LIBC_ENTRYPOINTS - # unistd.h entrypoints - libc.src.unistd.confstr - ) - if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS # regex.h entrypoints diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index c049c280b13ac..5c35a6f602fe3 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -422,6 +422,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.unistd.access libc.src.unistd.chdir libc.src.unistd.chown + libc.src.unistd.confstr libc.src.unistd.close libc.src.unistd.dup libc.src.unistd.dup2 @@ -1591,11 +1592,6 @@ if(LLVM_LIBC_FULL_BUILD) endif() if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS) - list(APPEND TARGET_LIBC_ENTRYPOINTS - # unistd.h entrypoints - libc.src.unistd.confstr - ) - if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS # net/if.h entrypoints diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 1b6c678a5dc1c..317c7d7587849 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -431,6 +431,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.unistd.access libc.src.unistd.chdir libc.src.unistd.chown + libc.src.unistd.confstr libc.src.unistd.close libc.src.unistd.dup libc.src.unistd.dup2 @@ -1604,11 +1605,6 @@ if(LLVM_LIBC_FULL_BUILD) endif() if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS) - list(APPEND TARGET_LIBC_ENTRYPOINTS - # unistd.h entrypoints - libc.src.unistd.confstr - ) - if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS # net/if.h entrypoints diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt index 6109981b032d2..9b26293777d35 100644 --- a/libc/src/unistd/CMakeLists.txt +++ b/libc/src/unistd/CMakeLists.txt @@ -54,9 +54,11 @@ add_entrypoint_object( HDRS confstr.h DEPENDS + libc.hdr.errno_macros libc.hdr.types.size_t libc.hdr.unistd_macros libc.src.__support.common + libc.src.__support.libc_errno libc.src.__support.macros.config ) diff --git a/libc/src/unistd/confstr.cpp b/libc/src/unistd/confstr.cpp index 3ea3a275928fb..562ea9641c984 100644 --- a/libc/src/unistd/confstr.cpp +++ b/libc/src/unistd/confstr.cpp @@ -13,12 +13,17 @@ #include "src/unistd/confstr.h" +#include "hdr/errno_macros.h" #include "hdr/types/size_t.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(size_t, confstr, (int, char *, size_t)) { return 0; } +LLVM_LIBC_FUNCTION(size_t, confstr, (int, char *, size_t)) { + libc_errno = EINVAL; + return 0; +} } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt index 016752bb16289..11d59566cd754 100644 --- a/libc/test/src/unistd/CMakeLists.txt +++ b/libc/test/src/unistd/CMakeLists.txt @@ -648,8 +648,10 @@ add_libc_test( SRCS confstr_test.cpp DEPENDS + libc.hdr.errno_macros libc.hdr.types.size_t libc.src.unistd.confstr + libc.test.UnitTest.ErrnoSetterMatcher ) add_libc_test( diff --git a/libc/test/src/unistd/confstr_test.cpp b/libc/test/src/unistd/confstr_test.cpp index 28da2bc521460..b9a372ce50e1a 100644 --- a/libc/test/src/unistd/confstr_test.cpp +++ b/libc/test/src/unistd/confstr_test.cpp @@ -13,22 +13,18 @@ #include "src/unistd/confstr.h" +#include "hdr/errno_macros.h" #include "hdr/types/size_t.h" +#include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" -TEST(LlvmLibcConfStrTest, Basic) { - char buf[64] = "initial"; - size_t ret = LIBC_NAMESPACE::confstr(0, buf, sizeof(buf)); - EXPECT_EQ(ret, size_t(0)); -} +using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; -TEST(LlvmLibcConfStrTest, NullBufZeroLen) { - size_t ret = LIBC_NAMESPACE::confstr(0, nullptr, 0); - EXPECT_EQ(ret, size_t(0)); -} - -TEST(LlvmLibcConfStrTest, NonExistentConfig) { - char buf[64]; - size_t ret = LIBC_NAMESPACE::confstr(-1, buf, sizeof(buf)); - EXPECT_EQ(ret, size_t(0)); +TEST(LlvmLibcConfStrTest, InvalidName) { + char buf[64] = "initial"; + EXPECT_THAT(LIBC_NAMESPACE::confstr(0, buf, sizeof(buf)), + Fails(EINVAL, size_t(0))); + EXPECT_THAT(LIBC_NAMESPACE::confstr(0, nullptr, 0), Fails(EINVAL, size_t(0))); + EXPECT_THAT(LIBC_NAMESPACE::confstr(-1, buf, sizeof(buf)), + Fails(EINVAL, size_t(0))); } From b0b9a7723f3effc4cc45fb5b8ee11a07ecfa954c Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Tue, 25 Aug 2026 22:44:02 +0000 Subject: [PATCH 3/3] fix dependencies, update test --- libc/src/unistd/CMakeLists.txt | 1 + libc/src/unistd/confstr.cpp | 1 + libc/src/unistd/confstr.h | 1 - libc/test/src/unistd/CMakeLists.txt | 1 + libc/test/src/unistd/confstr_test.cpp | 5 +++-- 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt index 9b26293777d35..1bcc0f58892bb 100644 --- a/libc/src/unistd/CMakeLists.txt +++ b/libc/src/unistd/CMakeLists.txt @@ -60,6 +60,7 @@ add_entrypoint_object( libc.src.__support.common libc.src.__support.libc_errno libc.src.__support.macros.config + libc.src.errno.errno ) add_entrypoint_object( diff --git a/libc/src/unistd/confstr.cpp b/libc/src/unistd/confstr.cpp index 562ea9641c984..6a2b3accbadff 100644 --- a/libc/src/unistd/confstr.cpp +++ b/libc/src/unistd/confstr.cpp @@ -15,6 +15,7 @@ #include "hdr/errno_macros.h" #include "hdr/types/size_t.h" +#include "hdr/unistd_macros.h" #include "src/__support/common.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" diff --git a/libc/src/unistd/confstr.h b/libc/src/unistd/confstr.h index 1792942e6c101..942efaad7c41c 100644 --- a/libc/src/unistd/confstr.h +++ b/libc/src/unistd/confstr.h @@ -15,7 +15,6 @@ #define LLVM_LIBC_SRC_UNISTD_CONFSTR_H #include "hdr/types/size_t.h" -#include "hdr/unistd_macros.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt index 11d59566cd754..d33476a1fec58 100644 --- a/libc/test/src/unistd/CMakeLists.txt +++ b/libc/test/src/unistd/CMakeLists.txt @@ -651,6 +651,7 @@ add_libc_test( libc.hdr.errno_macros libc.hdr.types.size_t libc.src.unistd.confstr + libc.test.UnitTest.ErrnoCheckingTest libc.test.UnitTest.ErrnoSetterMatcher ) diff --git a/libc/test/src/unistd/confstr_test.cpp b/libc/test/src/unistd/confstr_test.cpp index b9a372ce50e1a..3d2127004ee9d 100644 --- a/libc/test/src/unistd/confstr_test.cpp +++ b/libc/test/src/unistd/confstr_test.cpp @@ -15,12 +15,13 @@ #include "hdr/errno_macros.h" #include "hdr/types/size_t.h" +#include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/ErrnoSetterMatcher.h" -#include "test/UnitTest/Test.h" +using LlvmLibcConfStrTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; -TEST(LlvmLibcConfStrTest, InvalidName) { +TEST_F(LlvmLibcConfStrTest, InvalidName) { char buf[64] = "initial"; EXPECT_THAT(LIBC_NAMESPACE::confstr(0, buf, sizeof(buf)), Fails(EINVAL, size_t(0)));