[libc-commits] [libc] [libc] Add stub for confstr (PR #218789)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Tue Aug 25 14:53:17 PDT 2026


https://github.com/michaelrj-google updated https://github.com/llvm/llvm-project/pull/218789

>From 638f37821de28b648a6582cb71cf820f3873bd41 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Tue, 25 Aug 2026 21:31:05 +0000
Subject: [PATCH 1/2] [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 <michaelrj at google.com>
Date: Tue, 25 Aug 2026 21:52:54 +0000
Subject: [PATCH 2/2] 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)));
 }



More information about the libc-commits mailing list