[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