[libc-commits] [libc] [libc] implement mkstemp (PR #199220)
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Fri May 22 12:17:34 PDT 2026
================
@@ -0,0 +1,141 @@
+//===-- Unittests for mkstemp ---------------------------------------------===//
+//
+// 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/errno_macros.h"
+#include "hdr/fcntl_macros.h"
+#include "hdr/signal_macros.h"
+#include "src/stdlib/mkstemp.h"
+#include "src/unistd/access.h"
+#include "src/unistd/close.h"
+#include "src/unistd/read.h"
+#include "src/unistd/unlink.h"
+#include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcMkstempTest, ValidTemplate) {
+ char tmpl[] = "tmp_XXXXXX";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ ASSERT_GE(fd, 0);
+ LIBC_NAMESPACE::close(fd);
+ LIBC_NAMESPACE::unlink(tmpl);
+}
+
+TEST(LlvmLibcMkstempTest, TemplateModifiedInPlace) {
+ char tmpl[] = "tmp_XXXXXX";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ ASSERT_GE(fd, 0);
+ bool modified = false;
+ for (int i = 4; i < 10; i++)
+ if (tmpl[i] != 'X') {
+ modified = true;
+ break;
+ }
+ EXPECT_TRUE(modified);
+ LIBC_NAMESPACE::close(fd);
+ LIBC_NAMESPACE::unlink(tmpl);
+}
+
+TEST(LlvmLibcMkstempTest, FileExists) {
+ char tmpl[] = "tmp_XXXXXX";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ ASSERT_GE(fd, 0);
+ EXPECT_EQ(LIBC_NAMESPACE::access(tmpl, F_OK), 0);
+ LIBC_NAMESPACE::close(fd);
+ LIBC_NAMESPACE::unlink(tmpl);
+}
+
+TEST(LlvmLibcMkstempTest, FdIsWritable) {
+ char tmpl[] = "tmp_XXXXXX";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ ASSERT_GE(fd, 0);
+ const char msg[] = "hello";
+ EXPECT_EQ(LIBC_NAMESPACE::write(fd, msg, 5), static_cast<ssize_t>(5));
+ LIBC_NAMESPACE::close(fd);
+ LIBC_NAMESPACE::unlink(tmpl);
+}
+
+TEST(LlvmLibcMkstempTest, Uniqueness) {
+ char tmpl1[] = "tmp_XXXXXX";
+ char tmpl2[] = "tmp_XXXXXX";
+ int fd1 = LIBC_NAMESPACE::mkstemp(tmpl1);
+ int fd2 = LIBC_NAMESPACE::mkstemp(tmpl2);
+ ASSERT_GE(fd1, 0);
+ ASSERT_GE(fd2, 0);
+ bool different = false;
+ for (int i = 0; i < 10; i++)
+ if (tmpl1[i] != tmpl2[i]) {
+ different = true;
+ break;
+ }
+ EXPECT_TRUE(different);
+ LIBC_NAMESPACE::close(fd1);
+ LIBC_NAMESPACE::close(fd2);
+ LIBC_NAMESPACE::unlink(tmpl1);
+ LIBC_NAMESPACE::unlink(tmpl2);
+}
+
+TEST(LlvmLibcMkstempTest, FileIsEmpty) {
+ char tmpl[] = "tmp_XXXXXX";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ ASSERT_GE(fd, 0);
+ // read should return 0 on empty file
+ char buf[1];
+ EXPECT_EQ(LIBC_NAMESPACE::read(fd, buf, 1), static_cast<ssize_t>(0));
+ LIBC_NAMESPACE::close(fd);
+ LIBC_NAMESPACE::unlink(tmpl);
+}
+
+TEST(LlvmLibcMkstempTest, SixXsNoPrefix) {
+ char tmpl[] = "XXXXXX";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ ASSERT_GE(fd, 0);
+ LIBC_NAMESPACE::close(fd);
+ LIBC_NAMESPACE::unlink(tmpl);
+}
+
+#if defined(LIBC_ADD_NULL_CHECKS)
+TEST(LlvmLibcMkstempTest, NullPointer) {
+ EXPECT_DEATH([] { LIBC_NAMESPACE::mkstemp(nullptr); }, WITH_SIGNAL(-1));
+}
+#endif
+
+TEST(LlvmLibcMkstempTest, TemplateTooShort) {
+ char tmpl[] = "XXXXX";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ EXPECT_EQ(fd, -1);
+ ASSERT_ERRNO_EQ(EINVAL);
+}
+
+TEST(LlvmLibcMkstempTest, DoesNotEndInXs) {
+ char tmpl[] = "tmp_XXXXXY";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ EXPECT_EQ(fd, -1);
+ ASSERT_ERRNO_EQ(EINVAL);
+}
+
+TEST(LlvmLibcMkstempTest, XsInMiddleNotEnd) {
+ char tmpl[] = "XXXXXXtmp";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ EXPECT_EQ(fd, -1);
+ ASSERT_ERRNO_EQ(EINVAL);
+}
+
+TEST(LlvmLibcMkstempTest, FiveXsAtEnd) {
+ char tmpl[] = "tmp_XXXXX";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ EXPECT_EQ(fd, -1);
+ ASSERT_ERRNO_EQ(EINVAL);
+}
+
+TEST(LlvmLibcMkstempTest, EmptyString) {
+ char tmpl[] = "";
+ int fd = LIBC_NAMESPACE::mkstemp(tmpl);
+ EXPECT_EQ(fd, -1);
+ ASSERT_ERRNO_EQ(EINVAL);
+}
----------------
michaelrj-google wrote:
nit: fix missing newline at EoF
https://github.com/llvm/llvm-project/pull/199220
More information about the libc-commits
mailing list