[libc-commits] [libc] [libc] Implement tmpfile and corresponding tests (PR #213396)

Vadim Kotov via libc-commits libc-commits at lists.llvm.org
Wed Aug 5 11:57:44 PDT 2026


https://github.com/vadimkotov updated https://github.com/llvm/llvm-project/pull/213396

>From 2b49eb86abdd7e52246ade75e83c489cc4443462 Mon Sep 17 00:00:00 2001
From: Vadim Kotov <11969390+vadimkotov at users.noreply.github.com>
Date: Fri, 31 Jul 2026 18:22:46 -0700
Subject: [PATCH 1/5] Implement tmpfile and corresponding tests

---
 libc/config/linux/x86_64/entrypoints.txt |  1 +
 libc/include/stdio.yaml                  |  6 ++++
 libc/src/stdio/CMakeLists.txt            |  7 ++++
 libc/src/stdio/linux/CMakeLists.txt      | 10 ++++++
 libc/src/stdio/linux/tmpfile.cpp         | 37 ++++++++++++++++++++
 libc/src/stdio/tmpfile.h                 | 21 ++++++++++++
 libc/test/src/stdio/CMakeLists.txt       | 15 +++++++++
 libc/test/src/stdio/tmpfile_test.cpp     | 43 ++++++++++++++++++++++++
 8 files changed, 140 insertions(+)
 create mode 100644 libc/src/stdio/linux/tmpfile.cpp
 create mode 100644 libc/src/stdio/tmpfile.h
 create mode 100644 libc/test/src/stdio/tmpfile_test.cpp

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index bf809e268f585..df639ce0ea57c 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -272,6 +272,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.stderr
     libc.src.stdio.stdin
     libc.src.stdio.stdout
+    libc.src.stdio.tmpfile
     libc.src.stdio.vsscanf
     libc.src.stdio.vfprintf
     libc.src.stdio.vprintf
diff --git a/libc/include/stdio.yaml b/libc/include/stdio.yaml
index 4b12698e2484d..a5feb29272971 100644
--- a/libc/include/stdio.yaml
+++ b/libc/include/stdio.yaml
@@ -396,6 +396,12 @@ functions:
       - type: const char *__restrict
       - type: const char *__restrict
       - type: '...'
+  - name: tmpfile
+    standards:
+      - stdc
+    return_type: FILE *
+    arguments:
+      - type: void
   - name: ungetc
     standards:
       - stdc
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 0e3fe55462e03..4445fb2385418 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -256,6 +256,13 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.fdopen
 )
 
+add_entrypoint_object(
+  tmpfile
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.tmpfile
+)
+
 # These entrypoints have multiple potential implementations.
 add_stdio_entrypoint_object(feof)
 add_stdio_entrypoint_object(feof_unlocked)
diff --git a/libc/src/stdio/linux/CMakeLists.txt b/libc/src/stdio/linux/CMakeLists.txt
index 218875c78e246..0685bf45f9c86 100644
--- a/libc/src/stdio/linux/CMakeLists.txt
+++ b/libc/src/stdio/linux/CMakeLists.txt
@@ -66,3 +66,13 @@ add_entrypoint_object(
     libc.hdr.types.FILE
     libc.src.__support.File.platform_file
 )
+
+add_entrypoint_object( tmpfile
+  SRCS
+    tmpfile.cpp
+  HDRS
+    ../tmpfile.h
+  DEPENDS
+    libc.hdr.types.FILE
+    libc.src.__support.File.platform_file
+)
diff --git a/libc/src/stdio/linux/tmpfile.cpp b/libc/src/stdio/linux/tmpfile.cpp
new file mode 100644
index 0000000000000..9741877dfda12
--- /dev/null
+++ b/libc/src/stdio/linux/tmpfile.cpp
@@ -0,0 +1,37 @@
+//===-- Implementation of tmpfile --------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/tmpfile.h"
+#include "hdr/fcntl_macros.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/open.h"
+#include "hdr/types/FILE.h"
+
+#include "src/__support/File/linux/file.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+constexpr char TMPDIR[] = "/tmp";
+
+LLVM_LIBC_FUNCTION(::FILE *, tmpfile, (void)) {
+  auto fd = linux_syscalls::open(TMPDIR, O_RDWR | O_TMPFILE | O_EXCL, 0600);
+  if (!fd.has_value()) {
+    libc_errno = fd.error();
+    return nullptr;
+  }
+  auto file = LIBC_NAMESPACE::create_file_from_fd(fd.value(), "w+b");
+  if (!file.has_value()) {
+    libc_errno = file.error();
+    return nullptr;
+  }
+  return reinterpret_cast<::FILE *>(file.value());
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/tmpfile.h b/libc/src/stdio/tmpfile.h
new file mode 100644
index 0000000000000..680663a772166
--- /dev/null
+++ b/libc/src/stdio/tmpfile.h
@@ -0,0 +1,21 @@
+//===-- Implementation header of tmpfile ---------------------------*- 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_STDIO_TMPFILE_H_
+#define LLVM_LIBC_SRC_STDIO_TMPFILE_H_
+
+#include "hdr/types/FILE.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+::FILE *tmpfile();
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDIO_TMPFILE_H_
diff --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt
index 9f310c0cd66b2..851b44c321ca0 100644
--- a/libc/test/src/stdio/CMakeLists.txt
+++ b/libc/test/src/stdio/CMakeLists.txt
@@ -604,6 +604,21 @@ add_libc_test(
     libc.src.stdio.setvbuf
 )
 
+add_libc_test(
+  tmpfile_test
+  SUITE
+    libc_stdio_unittests
+  SRCS
+    tmpfile_test.cpp
+  DEPENDS
+    libc.src.stdio.tmpfile
+    libc.src.stdio.fflush
+    libc.src.stdio.fread
+    libc.src.stdio.fseek
+    libc.src.stdio.ftell
+    libc.src.stdio.fwrite
+)
+
 # Create an output directory for any temporary test files.
 file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/testdata)
 
diff --git a/libc/test/src/stdio/tmpfile_test.cpp b/libc/test/src/stdio/tmpfile_test.cpp
new file mode 100644
index 0000000000000..c6e7e4229c2f0
--- /dev/null
+++ b/libc/test/src/stdio/tmpfile_test.cpp
@@ -0,0 +1,43 @@
+//===-- Unittests for tmpfile --------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+#include "hdr/stdio_macros.h"
+#include "src/stdio/tmpfile.h"
+#include "src/stdio/fclose.h"
+#include "src/stdio/fflush.h"
+#include "src/stdio/fread.h"
+#include "src/stdio/fseek.h"
+#include "src/stdio/ftell.h"
+#include "src/stdio/fwrite.h"
+#include "test/UnitTest/Test.h"
+
+constexpr char TEST_STR[] = "test\xaa\t\xbb";
+constexpr size_t TEST_STR_SIZE = sizeof(TEST_STR);
+
+TEST(LlvmLibcTmpfileTest, CreationAndInvariants) {
+  auto *file = LIBC_NAMESPACE::tmpfile();
+  ASSERT_NE(file, nullptr);
+
+  EXPECT_EQ(LIBC_NAMESPACE::ftell(file), 0L);
+
+  size_t nbytes_written = LIBC_NAMESPACE::fwrite(TEST_STR, 1, TEST_STR_SIZE, file);
+  EXPECT_EQ(nbytes_written, TEST_STR_SIZE);
+
+  EXPECT_EQ(LIBC_NAMESPACE::fflush(file), 0);
+  EXPECT_EQ(static_cast<size_t>(LIBC_NAMESPACE::ftell(file)), nbytes_written);
+
+  EXPECT_EQ(LIBC_NAMESPACE::fseek(file, 0, SEEK_SET), 0);
+  EXPECT_EQ(LIBC_NAMESPACE::ftell(file), 0L);
+
+
+  char buff[TEST_STR_SIZE * 2];
+  size_t nbytes_read = LIBC_NAMESPACE::fread(buff, 1, TEST_STR_SIZE, file);
+  EXPECT_EQ(nbytes_read, TEST_STR_SIZE);
+
+}
+

>From 9a417654c8ffd740c3d0576369b86ec27f7edde0 Mon Sep 17 00:00:00 2001
From: Vadim Kotov <11969390+vadimkotov at users.noreply.github.com>
Date: Mon, 3 Aug 2026 15:58:21 -0700
Subject: [PATCH 2/5] Add aarch64 and riscv entry points.

---
 libc/config/linux/aarch64/entrypoints.txt | 1 +
 libc/config/linux/riscv/entrypoints.txt   | 1 +
 2 files changed, 2 insertions(+)

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 1ccb6cf202cf7..468b5189d8fb1 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -249,6 +249,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.stderr
     libc.src.stdio.stdin
     libc.src.stdio.stdout
+    libc.src.stdio.tmpfile
     libc.src.stdio.vsscanf
     libc.src.stdio.vfprintf
     libc.src.stdio.vprintf
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 5083417b453be..e097564c1e2d6 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -272,6 +272,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.stderr
     libc.src.stdio.stdin
     libc.src.stdio.stdout
+    libc.src.stdio.tmpfile
     libc.src.stdio.vsscanf
     libc.src.stdio.vfprintf
     libc.src.stdio.vprintf

>From b572817e2db10164ffea20cb4fa6bb6c69faca22 Mon Sep 17 00:00:00 2001
From: Vadim Kotov <11969390+vadimkotov at users.noreply.github.com>
Date: Mon, 3 Aug 2026 17:49:12 -0700
Subject: [PATCH 3/5] Fix formatting and update file headers.

---
 libc/src/stdio/linux/CMakeLists.txt  |  3 ++-
 libc/src/stdio/linux/tmpfile.cpp     | 10 +++++++---
 libc/src/stdio/tmpfile.h             |  7 ++++++-
 libc/test/src/stdio/tmpfile_test.cpp | 17 ++++++++++-------
 4 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/libc/src/stdio/linux/CMakeLists.txt b/libc/src/stdio/linux/CMakeLists.txt
index 0685bf45f9c86..3f201456e5303 100644
--- a/libc/src/stdio/linux/CMakeLists.txt
+++ b/libc/src/stdio/linux/CMakeLists.txt
@@ -67,7 +67,8 @@ add_entrypoint_object(
     libc.src.__support.File.platform_file
 )
 
-add_entrypoint_object( tmpfile
+add_entrypoint_object(
+  tmpfile
   SRCS
     tmpfile.cpp
   HDRS
diff --git a/libc/src/stdio/linux/tmpfile.cpp b/libc/src/stdio/linux/tmpfile.cpp
index 9741877dfda12..5e59d2182d5cd 100644
--- a/libc/src/stdio/linux/tmpfile.cpp
+++ b/libc/src/stdio/linux/tmpfile.cpp
@@ -1,15 +1,19 @@
-//===-- Implementation of tmpfile --------------------------------*- 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
 //
 //===----------------------------------------------------------------------===//
-
+///
+/// \file
+/// Linux implementation of tmpefile.
+///
+//===----------------------------------------------------------------------===//
 #include "src/stdio/tmpfile.h"
 #include "hdr/fcntl_macros.h"
-#include "src/__support/OSUtil/linux/syscall_wrappers/open.h"
 #include "hdr/types/FILE.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/open.h"
 
 #include "src/__support/File/linux/file.h"
 #include "src/__support/common.h"
diff --git a/libc/src/stdio/tmpfile.h b/libc/src/stdio/tmpfile.h
index 680663a772166..8d8185f4b4d34 100644
--- a/libc/src/stdio/tmpfile.h
+++ b/libc/src/stdio/tmpfile.h
@@ -1,10 +1,15 @@
-//===-- Implementation header of tmpfile ---------------------------*- 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
 //
 //===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header of tmpfile.
+///
+//===----------------------------------------------------------------------===//
 
 #ifndef LLVM_LIBC_SRC_STDIO_TMPFILE_H_
 #define LLVM_LIBC_SRC_STDIO_TMPFILE_H_
diff --git a/libc/test/src/stdio/tmpfile_test.cpp b/libc/test/src/stdio/tmpfile_test.cpp
index c6e7e4229c2f0..66a7b73361789 100644
--- a/libc/test/src/stdio/tmpfile_test.cpp
+++ b/libc/test/src/stdio/tmpfile_test.cpp
@@ -1,19 +1,24 @@
-//===-- Unittests for tmpfile --------------------------------------===//
+//===----------------------------------------------------------------------===//
 //
 // 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 tmpfile.
+///
+//===----------------------------------------------------------------------===//
+
 #include "hdr/stdio_macros.h"
-#include "src/stdio/tmpfile.h"
 #include "src/stdio/fclose.h"
 #include "src/stdio/fflush.h"
 #include "src/stdio/fread.h"
 #include "src/stdio/fseek.h"
 #include "src/stdio/ftell.h"
 #include "src/stdio/fwrite.h"
+#include "src/stdio/tmpfile.h"
 #include "test/UnitTest/Test.h"
 
 constexpr char TEST_STR[] = "test\xaa\t\xbb";
@@ -25,7 +30,8 @@ TEST(LlvmLibcTmpfileTest, CreationAndInvariants) {
 
   EXPECT_EQ(LIBC_NAMESPACE::ftell(file), 0L);
 
-  size_t nbytes_written = LIBC_NAMESPACE::fwrite(TEST_STR, 1, TEST_STR_SIZE, file);
+  size_t nbytes_written =
+      LIBC_NAMESPACE::fwrite(TEST_STR, 1, TEST_STR_SIZE, file);
   EXPECT_EQ(nbytes_written, TEST_STR_SIZE);
 
   EXPECT_EQ(LIBC_NAMESPACE::fflush(file), 0);
@@ -34,10 +40,7 @@ TEST(LlvmLibcTmpfileTest, CreationAndInvariants) {
   EXPECT_EQ(LIBC_NAMESPACE::fseek(file, 0, SEEK_SET), 0);
   EXPECT_EQ(LIBC_NAMESPACE::ftell(file), 0L);
 
-
   char buff[TEST_STR_SIZE * 2];
   size_t nbytes_read = LIBC_NAMESPACE::fread(buff, 1, TEST_STR_SIZE, file);
   EXPECT_EQ(nbytes_read, TEST_STR_SIZE);
-
 }
-

>From f36c92f22bd5676228ed5530ac1020eb0924f1a8 Mon Sep 17 00:00:00 2001
From: Vadim Kotov <11969390+vadimkotov at users.noreply.github.com>
Date: Wed, 5 Aug 2026 09:51:20 -0700
Subject: [PATCH 4/5] Add tmpfile entry point to Linux ARM entrypoints.txt

---
 libc/config/linux/arm/entrypoints.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 1986d6a5347dc..6c1249ffab238 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -187,6 +187,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.free
     libc.src.stdlib.malloc
 
+    # stdio.h entrypoints
+    libc.src.stdio.tmpfile
+
     # sys/ioctl.h entrypoints
     libc.src.sys.ioctl.ioctl
 

>From e987a898437837e81f2945ab9a4dccf3a880ea6e Mon Sep 17 00:00:00 2001
From: Vadim Kotov <kotov at google.com>
Date: Wed, 5 Aug 2026 11:55:25 -0700
Subject: [PATCH 5/5] Add missing dependencies to stdio Linux CMakeLists.txt
 and fix a typo in tmpfile.cpp

---
 libc/src/stdio/linux/CMakeLists.txt | 5 +++++
 libc/src/stdio/linux/tmpfile.cpp    | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/libc/src/stdio/linux/CMakeLists.txt b/libc/src/stdio/linux/CMakeLists.txt
index 3f201456e5303..6631f2ca4814a 100644
--- a/libc/src/stdio/linux/CMakeLists.txt
+++ b/libc/src/stdio/linux/CMakeLists.txt
@@ -74,6 +74,11 @@ add_entrypoint_object(
   HDRS
     ../tmpfile.h
   DEPENDS
+    libc.hdr.fcntl_macros
     libc.hdr.types.FILE
+    libc.src.__support.common
     libc.src.__support.File.platform_file
+    libc.src.__support.libc_errno
+    libc.src.__support.macros.config
+    libc.src.__support.OSUtil.linux.syscall_wrappers.open
 )
diff --git a/libc/src/stdio/linux/tmpfile.cpp b/libc/src/stdio/linux/tmpfile.cpp
index 5e59d2182d5cd..3758a6fadc627 100644
--- a/libc/src/stdio/linux/tmpfile.cpp
+++ b/libc/src/stdio/linux/tmpfile.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// Linux implementation of tmpefile.
+/// Linux implementation of tmpfile.
 ///
 //===----------------------------------------------------------------------===//
 #include "src/stdio/tmpfile.h"



More information about the libc-commits mailing list